Fix ICC warnings
[alexxy/gromacs.git] / src / external / tng_io / src / lib / tng_io.c
index b51796adbc133c23c334bdfea90f1833b386778e..7702d23846c5d12cd5aa2351c0a7a4fe2a4f193e 100644 (file)
@@ -1,9 +1,7 @@
 /* This code is part of the tng binary trajectory format.
- *
- *                      VERSION 1.5
  *
  * Written by Magnus Lundborg
- * Copyright (c) 2012-2013, The GROMACS development team.
+ * Copyright (c) 2012-2014, The GROMACS development team.
  * Check out http://www.gromacs.org for more information.
  *
  *
@@ -11,6 +9,14 @@
  * modify it under the terms of the Revised BSD License.
  */
 
+#define _FILE_OFFSET_BITS 64
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+#define _LARGEFILE_SOURCE
+/* Define for large files, on AIX-style hosts. */
+#define _LARGE_FILES
+
+#include "tng/tng_io.h"
+
 #ifdef USE_STD_INTTYPES_H
 #include <inttypes.h>
 #endif
 #include <zlib.h>
 #endif
 
-#include "../../include/tng_io.h"
-#include "../../include/md5.h"
-#include "../../include/compression/tng_compress.h"
-
+#include "tng/md5.h"
+#include "compression/tng_compress.h"
+#include "tng/version.h"
+
+#if defined( _WIN32 ) || defined( _WIN64 )
+    #ifndef fseeko
+        #define fseeko _fseeki64
+    #endif
+    #ifndef ftello
+        #ifdef __MINGW32__
+            #define ftello ftello64
+        #else
+            #define ftello _ftelli64
+        #endif
+    #endif
+#endif
 
 struct tng_bond {
     /** One of the atoms of the bond */
@@ -190,6 +208,7 @@ struct tng_trajectory_frame_set {
 };
 
 /* FIXME: Should there be a pointer to a tng_gen_block from each data block? */
+/* FIXME: Make only one data block struct */
 struct tng_particle_data {
     /** The block ID of the data block containing this particle data.
      *  This is used to determine the kind of data that is stored */
@@ -248,7 +267,7 @@ struct tng_non_particle_data {
     /** A 1-dimensional array of values of length
      *  [sizeof (datatype)] * n_frames * n_values_per_frame */
     void *values;
-    /** If storing character data store it in a 3-dimensional array */
+    /** If storing character data store it in a 2-dimensional array */
     char ***strings;
 };
 
@@ -260,7 +279,7 @@ struct tng_trajectory {
     /** A handle to the input file */
     FILE *input_file;
     /** The length of the input file */
-    long input_file_len;
+    int64_t input_file_len;
     /** The path of the output trajectory file */
     char *output_file_path;
     /** A handle to the output file */
@@ -345,16 +364,13 @@ struct tng_trajectory {
     /** The currently active frame set */
     struct tng_trajectory_frame_set current_trajectory_frame_set;
     /** The pos in the src file of the current frame set */
-    long current_trajectory_frame_set_input_file_pos;
+    int64_t current_trajectory_frame_set_input_file_pos;
     /** The pos in the dest file of the current frame set */
-    long current_trajectory_frame_set_output_file_pos;
+    int64_t current_trajectory_frame_set_output_file_pos;
     /** The number of frame sets in the trajectory N.B. Not saved in file and
      *  cannot be trusted to be up-to-date */
     int64_t n_trajectory_frame_sets;
 
-    /** The number of trajectory blocks in the file */
-    int64_t n_trajectory_blocks;
-
     /* These data blocks are non-trajectory data blocks */
     /** The number of non-frame dependent particle dependent data blocks */
     int n_particle_data_blocks;
@@ -735,7 +751,7 @@ static tng_function_status tng_block_init(struct tng_gen_block **block_p)
     *block_p = malloc(sizeof(struct tng_gen_block));
     if(!*block_p)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                sizeof(struct tng_gen_block), __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -746,7 +762,7 @@ static tng_function_status tng_block_init(struct tng_gen_block **block_p)
     /* Reset the md5_hash */
     memcpy(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN);
     block->name = 0;
-    block->block_version = TNG_VERSION;
+    block->block_version = TNG_API_VERSION;
     block->header_contents = 0;
     block->header_contents_size = 0;
     block->block_contents = 0;
@@ -797,13 +813,15 @@ static tng_function_status tng_block_destroy(struct tng_gen_block **block_p)
 /** Read the header of a data block, regardless of its type
  * @param tng_data is a trajectory data container.
  * @param block is a general block container.
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
+ * @return TNG_SUCCESS (0) if successful, TNG_FAILURE(1) if a minor
+ * error has occured (not able to read the header size, thus skipping
+ * the block) or TNG_CRITICAL (2) if a major error has occured.
  */
 static tng_function_status tng_block_header_read
                 (tng_trajectory_t tng_data, tng_gen_block_t block)
 {
-    int len, offset = 0;
+    int len;
+    int64_t offset = 0;
 
     TNG_ASSERT(block != 0, "TNG library: Trying to read to uninitialized block (NULL pointer).");
 
@@ -821,8 +839,14 @@ static tng_function_status tng_block_header_read
         return(TNG_CRITICAL);
     }
 
+    if(block->header_contents_size == 0)
+    {
+        block->id = -1;
+        return(TNG_FAILURE);
+    }
+
     /* If this was the size of the general info block check the endianness */
-    if(ftell(tng_data->input_file) < 9)
+    if(ftello(tng_data->input_file) < 9)
     {
         /* File is little endian */
         if ( *((const char*)&block->header_contents_size) != 0x00 &&
@@ -889,8 +913,8 @@ static tng_function_status tng_block_header_read
     }
 
     /* Move the reading position to the beginning of the header. */
-    fseek(tng_data->input_file, -(long)sizeof(block->header_contents_size),
-          SEEK_CUR);
+    fseeko(tng_data->input_file, -(int64_t)sizeof(block->header_contents_size),
+           SEEK_CUR);
 
     /* If there is already memory allocated for the contents free it (we do not
      * know if the size is correct). */
@@ -1029,125 +1053,121 @@ static tng_function_status tng_block_header_read
 //     return(TNG_SUCCESS);
 // }
 */
-/** Write the header of a data block, regardless of its type
+
+/** Update the md5 hash of a block already written to the file
  * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param hash_mode is an option to decide whether to use the md5 hash or not.
- * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
+ * @param block is the block, of which to update the md5 hash.
+ * @param header_start_pos is the file position where the block header starts.
+ * @param contents_start_pos is the file position where the block contents
+ * start.
  * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
  * error has occured.
  */
-static tng_function_status tng_block_header_write
-                (tng_trajectory_t tng_data,
-                 tng_gen_block_t block,
-                 const char hash_mode)
+static tng_function_status tng_md5_hash_update(tng_trajectory_t tng_data,
+                                               tng_gen_block_t block,
+                                               const int64_t header_start_pos,
+                                               const int64_t contents_start_pos)
 {
-    int name_len, offset = 0;
-
-    TNG_ASSERT(block != 0, "TNG library: Trying to write uninitialized block (NULL pointer).");
+    if(block->block_contents)
+    {
+        free(block->block_contents);
+    }
 
-    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
+    block->block_contents = malloc(block->block_contents_size);
+    if(!block->block_contents)
     {
-        fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
-               __FILE__, __LINE__);
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+               block->block_contents_size, __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
 
-    if(!block->name)
+    fseeko(tng_data->output_file, contents_start_pos, SEEK_SET);
+    if(fread(block->block_contents, block->block_contents_size, 1,
+            tng_data->output_file) == 0)
     {
-        block->name = malloc(1);
-        if(!block->name)
-        {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
-        }
-        block->name[0] = 0;
+        fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
+        return(TNG_CRITICAL);
     }
 
-    name_len = tng_min_i((int)strlen(block->name) + 1, TNG_MAX_STR_LEN);
+    tng_block_md5_hash_generate(block);
 
-    if(hash_mode == TNG_USE_HASH)
-    {
-        tng_block_md5_hash_generate(block);
-    }
+    fseeko(tng_data->output_file, header_start_pos + 3 * sizeof(int64_t),
+          SEEK_SET);
+    fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file);
 
-    /* Calculate the size of the header to write */
-    block->header_contents_size = sizeof(block->header_contents_size) +
-                                  sizeof(block->block_contents_size) +
-                                  sizeof(block->id) +
-                                  sizeof(block->block_version) +
-                                  TNG_MD5_HASH_LEN +
-                                  name_len;
+    return(TNG_SUCCESS);
+}
 
-    if(block->header_contents)
-    {
-        free(block->header_contents);
-    }
+/** Update the frame set pointers in the file header (general info block),
+ * already written to disk
+ * @param tng_data is a trajectory data container.
+ * @param hash_mode specifies whether to update the block md5 hash when
+ * updating the pointers.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
+ */
+static tng_function_status tng_header_pointers_update
+                (tng_trajectory_t tng_data, const char hash_mode)
+{
+    tng_gen_block_t block;
+    FILE *temp = tng_data->input_file;
+    int64_t output_file_pos, pos, contents_start_pos;
 
-    block->header_contents = malloc(block->header_contents_size);
-    if(!block->header_contents)
+    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               block->header_contents_size, __FILE__, __LINE__);
+        fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
+               __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
 
-    /* First copy all data into the header_contents block and finally write
-     * the whole block at once. */
-    memcpy(block->header_contents, &block->header_contents_size,
-           sizeof(block->header_contents_size));
-    if(tng_data->output_endianness_swap_func_64)
+    tng_data->input_file = tng_data->output_file;
+
+    tng_block_init(&block);
+
+    output_file_pos = ftello(tng_data->output_file);
+    fseeko(tng_data->output_file, 0, SEEK_SET);
+
+    if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        fprintf(stderr, "TNG library: Cannot read general info header. %s: %d\n",
+               __FILE__, __LINE__);
+        tng_data->input_file = temp;
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
     }
-    offset += sizeof(block->header_contents_size);
 
-    memcpy(block->header_contents+offset, &block->block_contents_size,
-           sizeof(block->block_contents_size));
-    if(tng_data->output_endianness_swap_func_64)
+    contents_start_pos = ftello(tng_data->output_file);
+
+    fseeko(tng_data->output_file, block->block_contents_size - 5 *
+          sizeof(int64_t), SEEK_CUR);
+
+    tng_data->input_file = temp;
+
+    pos = tng_data->first_trajectory_frame_set_output_file_pos;
+
+    if(tng_data->input_endianness_swap_func_64)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                    &pos)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    offset += sizeof(block->block_contents_size);
 
-    memcpy(block->header_contents+offset, &block->id, sizeof(block->id));
-    if(tng_data->output_endianness_swap_func_64)
+    if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
     }
-    offset += sizeof(block->id);
-
-    memcpy(block->header_contents+offset, block->md5_hash, TNG_MD5_HASH_LEN);
-    offset += TNG_MD5_HASH_LEN;
 
-    strncpy(block->header_contents+offset, block->name, name_len);
-    offset += name_len;
+    pos = tng_data->last_trajectory_frame_set_output_file_pos;
 
-    memcpy(block->header_contents+offset, &block->block_version,
-           sizeof(block->block_version));
-    if(tng_data->output_endianness_swap_func_64)
+    if(tng_data->input_endianness_swap_func_64)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                    &pos)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
@@ -1155,962 +1175,991 @@ static tng_function_status tng_block_header_write
         }
     }
 
-    if(fwrite(block->header_contents, block->header_contents_size,
-       1, tng_data->output_file) != 1)
+    if(fwrite(&pos,
+        sizeof(int64_t), 1, tng_data->output_file) != 1)
     {
-        fprintf(stderr, "TNG library: Could not write all header data. %s: %d\n", __FILE__, __LINE__);
+        tng_block_destroy(&block);
         return(TNG_CRITICAL);
     }
+
+    if(hash_mode == TNG_USE_HASH)
+    {
+        tng_md5_hash_update(tng_data, block, 0, contents_start_pos);
+    }
+
+    tng_block_destroy(&block);
+
+    fseeko(tng_data->output_file, output_file_pos, SEEK_SET);
+
     return(TNG_SUCCESS);
 }
 
-/** Read a general info block. This is the first block of a TNG file.
- *  Populate the fields in tng_data.
+/** Update the frame set pointers in the current frame set block, already
+ * written to disk. It also updates the pointers of the blocks pointing to
+ * the current frame set block.
  * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param hash_mode is an option to decide whether to use the md5 hash or not.
- * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
- * compared to the md5 hash of the read contents to ensure valid data.
+ * @param hash_mode specifies whether to update the block md5 hash when
+ * updating the pointers.
  * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
  * error has occured.
  */
-static tng_function_status tng_general_info_block_read
-                (tng_trajectory_t tng_data, tng_gen_block_t block,
-                 const char hash_mode)
+static tng_function_status tng_frame_set_pointers_update
+                (tng_trajectory_t tng_data, const char hash_mode)
 {
-    int len, offset = 0;
-    tng_bool same_hash;
-
-    void *temp;
-
-    TNG_ASSERT(block != 0, "TNG library: Trying to read data to an uninitialized block (NULL pointer)");
+    tng_gen_block_t block;
+    tng_trajectory_frame_set_t frame_set;
+    FILE *temp = tng_data->input_file;
+    int64_t pos, output_file_pos, contents_start_pos;
 
-    if(tng_input_file_init(tng_data) != TNG_SUCCESS)
+    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
     {
+        fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
+               __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
 
-    temp = realloc(block->block_contents, block->block_contents_size);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               block->block_contents_size, __FILE__, __LINE__);
-        free(block->block_contents);
-        block->block_contents = 0;
-        return(TNG_CRITICAL);
-    }
-    block->block_contents = temp;
+    tng_block_init(&block);
+    output_file_pos = ftello(tng_data->output_file);
 
-    /* Read the whole block into block_contents to be able to write it to disk
-     * even if it cannot be interpreted. */
-    if(fread(block->block_contents, block->block_contents_size, 1,
-             tng_data->input_file) == 0)
-    {
-        fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
-        return(TNG_CRITICAL);
-    }
+    tng_data->input_file = tng_data->output_file;
 
-    /* FIXME: Does not check if the size of the contents matches the expected
-     * size or if the contents can be read. */
+    frame_set = &tng_data->current_trajectory_frame_set;
 
-    if(hash_mode == TNG_USE_HASH)
+    pos = tng_data->current_trajectory_frame_set_output_file_pos;
+
+    /* Update next frame set */
+    if(frame_set->next_frame_set_file_pos > 0)
     {
-        tng_md5_hash_match_verify(block, &same_hash);
-        if(same_hash != TNG_TRUE)
+        fseeko(tng_data->output_file, frame_set->next_frame_set_file_pos,
+              SEEK_SET);
+
+        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
         {
-            fprintf(stderr, "TNG library: General info block contents corrupt. Hashes do not match. "
-                "%s: %d\n",
+            fprintf(stderr, "TNG library: Cannot read frame header. %s: %d\n",
                 __FILE__, __LINE__);
-    /*         return(TNG_FAILURE); */
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
         }
-    }
 
-    len = tng_min_i((int)strlen(block->block_contents) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->first_program_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->first_program_name);
-        tng_data->first_program_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->first_program_name = temp;
-    strncpy(tng_data->first_program_name, block->block_contents, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents + offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->last_program_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->last_program_name);
-        tng_data->last_program_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->last_program_name = temp;
-    strncpy(tng_data->last_program_name, block->block_contents + offset, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->first_user_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->first_user_name);
-        tng_data->first_user_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->first_user_name = temp;
-    strncpy(tng_data->first_user_name, block->block_contents+offset, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->last_user_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->last_user_name);
-        tng_data->last_user_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->last_user_name = temp;
-    strncpy(tng_data->last_user_name, block->block_contents+offset, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->first_computer_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->first_computer_name);
-        tng_data->first_computer_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->first_computer_name = temp;
-    strncpy(tng_data->first_computer_name, block->block_contents+offset, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->last_computer_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->last_computer_name);
-        tng_data->last_computer_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->last_computer_name = temp;
-    strncpy(tng_data->last_computer_name, block->block_contents+offset, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->first_pgp_signature, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->first_pgp_signature);
-        tng_data->first_pgp_signature = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->first_pgp_signature = temp;
-    strncpy(tng_data->first_pgp_signature, block->block_contents+offset, len);
-    offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->last_pgp_signature, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->last_pgp_signature);
-        tng_data->last_pgp_signature = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->last_pgp_signature = temp;
-    strncpy(tng_data->last_pgp_signature, block->block_contents+offset, len);
-    offset += len;
+        contents_start_pos = ftello(tng_data->output_file);
 
-    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-    temp = realloc(tng_data->forcefield_name, len);
-    if(!temp)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
-               __FILE__, __LINE__);
-        free(tng_data->forcefield_name);
-        tng_data->forcefield_name = 0;
-        return(TNG_CRITICAL);
-    }
-    tng_data->forcefield_name = temp;
-    strncpy(tng_data->forcefield_name, block->block_contents+offset, len);
-    offset += len;
+        fseeko(tng_data->output_file, block->block_contents_size - (5 *
+            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
 
-    memcpy(&tng_data->time, block->block_contents+offset,
-           sizeof(tng_data->time));
-    if(tng_data->input_endianness_swap_func_64)
-    {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   &tng_data->time)
-            != TNG_SUCCESS)
+        if(tng_data->input_endianness_swap_func_64)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                        &pos)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
         }
-    }
-    offset += sizeof(tng_data->time);
 
-    memcpy(&tng_data->var_num_atoms_flag, block->block_contents+offset,
-           sizeof(tng_data->var_num_atoms_flag));
-    offset += sizeof(tng_data->var_num_atoms_flag);
+        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
+        }
 
-    memcpy(&tng_data->frame_set_n_frames, block->block_contents+offset,
-           sizeof(tng_data->frame_set_n_frames));
-    if(tng_data->input_endianness_swap_func_64)
-    {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                 &tng_data->frame_set_n_frames)
-            != TNG_SUCCESS)
+        if(hash_mode == TNG_USE_HASH)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            tng_md5_hash_update(tng_data, block, frame_set->next_frame_set_file_pos,
+                                contents_start_pos);
         }
+        fseeko(tng_data->output_file, output_file_pos, SEEK_SET);
     }
-    offset += sizeof(tng_data->frame_set_n_frames);
-
-    memcpy(&tng_data->first_trajectory_frame_set_input_file_pos,
-           block->block_contents+offset,
-           sizeof(tng_data->first_trajectory_frame_set_input_file_pos));
-    if(tng_data->input_endianness_swap_func_64)
+    /* Update previous frame set */
+    if(frame_set->prev_frame_set_file_pos > 0)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                          &tng_data->first_trajectory_frame_set_input_file_pos)
-            != TNG_SUCCESS)
+        fseeko(tng_data->output_file, frame_set->prev_frame_set_file_pos,
+              SEEK_SET);
+
+        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot read frame header. %s: %d\n",
+                __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
         }
-    }
-    offset += sizeof(tng_data->first_trajectory_frame_set_input_file_pos);
 
-    tng_data->current_trajectory_frame_set.next_frame_set_file_pos =
-    tng_data->first_trajectory_frame_set_input_file_pos;
+        contents_start_pos = ftello(tng_data->output_file);
 
+        fseeko(tng_data->output_file, block->block_contents_size - (6 *
+            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
 
-    memcpy(&tng_data->last_trajectory_frame_set_input_file_pos,
-           block->block_contents+offset,
-           sizeof(tng_data->last_trajectory_frame_set_input_file_pos));
-    if(tng_data->input_endianness_swap_func_64)
-    {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                          &tng_data->last_trajectory_frame_set_input_file_pos)
-            != TNG_SUCCESS)
+        if(tng_data->input_endianness_swap_func_64)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                        &pos)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
         }
-    }
-    offset += sizeof(tng_data->last_trajectory_frame_set_input_file_pos);
 
-    memcpy(&tng_data->medium_stride_length, block->block_contents+offset,
-           sizeof(tng_data->medium_stride_length));
-    if(tng_data->input_endianness_swap_func_64)
-    {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                               &tng_data->medium_stride_length)
-            != TNG_SUCCESS)
+        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
         }
-    }
-    offset += sizeof(tng_data->medium_stride_length);
 
-    memcpy(&tng_data->long_stride_length, block->block_contents+offset,
-           sizeof(tng_data->long_stride_length));
-    if(tng_data->input_endianness_swap_func_64)
-    {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                 &tng_data->long_stride_length)
-            != TNG_SUCCESS)
+        if(hash_mode == TNG_USE_HASH)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            tng_md5_hash_update(tng_data, block, frame_set->prev_frame_set_file_pos,
+                                contents_start_pos);
         }
+        fseeko(tng_data->output_file, output_file_pos, SEEK_SET);
     }
-    offset += sizeof(tng_data->long_stride_length);
 
-    if(block->block_version >= 3)
+    /* Update the frame set one medium stride step after */
+    if(frame_set->medium_stride_next_frame_set_file_pos > 0)
     {
-        memcpy(&tng_data->distance_unit_exponential, block->block_contents+offset,
-            sizeof(tng_data->distance_unit_exponential));
+        fseeko(tng_data->output_file,
+               frame_set->medium_stride_next_frame_set_file_pos,
+               SEEK_SET);
+
+        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
+                __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
+        }
+
+        contents_start_pos = ftello(tng_data->output_file);
+
+        fseeko(tng_data->output_file, block->block_contents_size - (3 *
+            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
+
         if(tng_data->input_endianness_swap_func_64)
         {
             if(tng_data->input_endianness_swap_func_64(tng_data,
-                                          &tng_data->distance_unit_exponential)
+                                                        &pos)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
-    }
 
-    return(TNG_SUCCESS);
-}
+        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
+        }
 
-/** Write a general info block. This is the first block of a TNG file.
- * @param tng_data is a trajectory data container.
- * @param hash_mode is an option to decide whether to use the md5 hash or not.
- * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
- */
-static tng_function_status tng_general_info_block_write
-                (tng_trajectory_t tng_data,
-                 const char hash_mode)
-{
-    int first_program_name_len, first_user_name_len;
-    int first_computer_name_len, first_pgp_signature_len;
-    int last_program_name_len, last_user_name_len;
-    int last_computer_name_len, last_pgp_signature_len;
-    int forcefield_name_len, name_len;
-    int offset = 0;
-    tng_gen_block_t block;
-
-    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
-    {
-        return(TNG_CRITICAL);
-    }
-
-    fseek(tng_data->output_file, 0, SEEK_SET);
-
-    /* If the strings are unallocated allocate memory for just string
-     * termination */
-    if(!tng_data->first_program_name)
-    {
-        tng_data->first_program_name = malloc(1);
-        if(!tng_data->first_program_name)
+        if(hash_mode == TNG_USE_HASH)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
+            tng_md5_hash_update(tng_data, block,
+                                frame_set->medium_stride_next_frame_set_file_pos,
+                                contents_start_pos);
         }
-        tng_data->first_program_name[0] = 0;
     }
-    if(!tng_data->last_program_name)
+    /* Update the frame set one medium stride step before */
+    if(frame_set->medium_stride_prev_frame_set_file_pos > 0)
     {
-        tng_data->last_program_name = malloc(1);
-        if(!tng_data->last_program_name)
+        fseeko(tng_data->output_file,
+               frame_set->medium_stride_prev_frame_set_file_pos,
+               SEEK_SET);
+
+        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
+                __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
             return(TNG_CRITICAL);
         }
-        tng_data->last_program_name[0] = 0;
-    }
-    if(!tng_data->first_user_name)
-    {
-        tng_data->first_user_name = malloc(1);
-        if(!tng_data->first_user_name)
+
+        contents_start_pos = ftello(tng_data->output_file);
+
+        fseeko(tng_data->output_file, block->block_contents_size - (4 *
+            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
+
+        if(tng_data->input_endianness_swap_func_64)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                        &pos)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
         }
-        tng_data->first_user_name[0] = 0;
-    }
-    if(!tng_data->last_user_name)
-    {
-        tng_data->last_user_name = malloc(1);
-        if(!tng_data->last_user_name)
+
+        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
             return(TNG_CRITICAL);
         }
-        tng_data->last_user_name[0] = 0;
-    }
-    if(!tng_data->first_computer_name)
-    {
-        tng_data->first_computer_name = malloc(1);
-        if(!tng_data->first_computer_name)
+
+        if(hash_mode == TNG_USE_HASH)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
+            tng_md5_hash_update(tng_data, block,
+                                frame_set->medium_stride_prev_frame_set_file_pos,
+                                contents_start_pos);
         }
-        tng_data->first_computer_name[0] = 0;
     }
-    if(!tng_data->last_computer_name)
+
+    /* Update the frame set one long stride step after */
+    if(frame_set->long_stride_next_frame_set_file_pos > 0)
     {
-        tng_data->last_computer_name = malloc(1);
-        if(!tng_data->last_computer_name)
+        fseeko(tng_data->output_file,
+               frame_set->long_stride_next_frame_set_file_pos,
+               SEEK_SET);
+
+        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
+                __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
             return(TNG_CRITICAL);
         }
-        tng_data->last_computer_name[0] = 0;
-    }
-    if(!tng_data->first_pgp_signature)
-    {
-        tng_data->first_pgp_signature = malloc(1);
-        if(!tng_data->first_pgp_signature)
+
+        contents_start_pos = ftello(tng_data->output_file);
+
+        fseeko(tng_data->output_file, block->block_contents_size - (1 *
+               sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
+
+        if(tng_data->input_endianness_swap_func_64)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                        &pos)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+
+        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
             return(TNG_CRITICAL);
         }
-        tng_data->first_pgp_signature[0] = 0;
+
+        if(hash_mode == TNG_USE_HASH)
+        {
+            tng_md5_hash_update(tng_data, block,
+                                frame_set->long_stride_next_frame_set_file_pos,
+                                contents_start_pos);
+        }
     }
-    if(!tng_data->last_pgp_signature)
+    /* Update the frame set one long stride step before */
+    if(frame_set->long_stride_prev_frame_set_file_pos > 0)
     {
-        tng_data->last_pgp_signature = malloc(1);
-        if(!tng_data->last_pgp_signature)
+        fseeko(tng_data->output_file,
+               frame_set->long_stride_prev_frame_set_file_pos,
+               SEEK_SET);
+
+        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
+                __FILE__, __LINE__);
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
             return(TNG_CRITICAL);
         }
-        tng_data->last_pgp_signature[0] = 0;
-    }
-    if(!tng_data->forcefield_name)
-    {
-        tng_data->forcefield_name = malloc(1);
-        if(!tng_data->forcefield_name)
+
+        contents_start_pos = ftello(tng_data->output_file);
+
+        fseeko(tng_data->output_file, block->block_contents_size - (2 *
+            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
+
+        if(tng_data->input_endianness_swap_func_64)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                   __FILE__, __LINE__);
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                        &pos)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+
+        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
             return(TNG_CRITICAL);
         }
-        tng_data->forcefield_name[0] = 0;
+
+        if(hash_mode == TNG_USE_HASH)
+        {
+            tng_md5_hash_update(tng_data, block,
+                                frame_set->long_stride_prev_frame_set_file_pos,
+                                contents_start_pos);
+        }
     }
 
-    tng_block_init(&block);
+    fseeko(tng_data->output_file, output_file_pos, SEEK_SET);
 
-    name_len = (int)strlen("GENERAL INFO");
+    tng_data->input_file = temp;
 
-    block->name = malloc(name_len + 1);
-    if(!block->name)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
-                name_len+1, __FILE__, __LINE__);
-        tng_block_destroy(&block);
-        return(TNG_CRITICAL);
-    }
+    tng_block_destroy(&block);
 
-    strcpy(block->name, "GENERAL INFO");
-    block->id = TNG_GENERAL_INFO;
+    return(TNG_SUCCESS);
+}
 
-    first_program_name_len = tng_min_i((int)strlen(tng_data->first_program_name) + 1,
-                           TNG_MAX_STR_LEN);
-    last_program_name_len = tng_min_i((int)strlen(tng_data->last_program_name) + 1,
-                           TNG_MAX_STR_LEN);
-    first_user_name_len = tng_min_i((int)strlen(tng_data->first_user_name) + 1,
-                        TNG_MAX_STR_LEN);
-    last_user_name_len = tng_min_i((int)strlen(tng_data->last_user_name) + 1,
-                        TNG_MAX_STR_LEN);
-    first_computer_name_len = tng_min_i((int)strlen(tng_data->first_computer_name) + 1,
-                            TNG_MAX_STR_LEN);
-    last_computer_name_len = tng_min_i((int)strlen(tng_data->last_computer_name) + 1,
-                            TNG_MAX_STR_LEN);
-    first_pgp_signature_len = tng_min_i((int)strlen(tng_data->first_pgp_signature) + 1,
-                            TNG_MAX_STR_LEN);
-    last_pgp_signature_len = tng_min_i((int)strlen(tng_data->last_pgp_signature) + 1,
-                            TNG_MAX_STR_LEN);
-    forcefield_name_len = tng_min_i((int)strlen(tng_data->forcefield_name) + 1,
-                              TNG_MAX_STR_LEN);
+static tng_function_status tng_reread_frame_set_at_file_pos
+                (tng_trajectory_t tng_data,
+                 const int64_t pos)
+{
+    tng_gen_block_t block;
+    tng_function_status stat;
 
-    block->block_contents_size = sizeof(tng_data->time) +
-                sizeof(tng_data->var_num_atoms_flag) +
-                sizeof(tng_data->frame_set_n_frames) +
-                sizeof(tng_data->first_trajectory_frame_set_input_file_pos) +
-                sizeof(tng_data->last_trajectory_frame_set_input_file_pos) +
-                sizeof(tng_data->medium_stride_length) +
-                sizeof(tng_data->long_stride_length) +
-                sizeof(tng_data->distance_unit_exponential) +
-                first_program_name_len +
-                last_program_name_len +
-                first_user_name_len +
-                last_user_name_len +
-                first_computer_name_len +
-                last_computer_name_len +
-                first_pgp_signature_len +
-                last_pgp_signature_len +
-                forcefield_name_len;
+    tng_block_init(&block);
 
-    if(block->block_contents)
-    {
-        free(block->block_contents);
-    }
-    block->block_contents = malloc(block->block_contents_size);
-    if(!block->block_contents)
+    fseeko(tng_data->input_file, pos, SEEK_SET);
+    if(pos > 0)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               block->block_contents_size, __FILE__, __LINE__);
-        tng_block_destroy(&block);
-        return(TNG_CRITICAL);
+        stat = tng_block_header_read(tng_data, block);
+        if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
+        {
+            fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos,
+                    __FILE__, __LINE__);
+            tng_block_destroy(&block);
+            return(TNG_FAILURE);
+        }
+
+        if(tng_block_read_next(tng_data, block,
+                               TNG_SKIP_HASH) != TNG_SUCCESS)
+        {
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
+        }
     }
 
-    strncpy(block->block_contents, tng_data->first_program_name, first_program_name_len);
-    offset += first_program_name_len;
+    tng_block_destroy(&block);
 
-    strncpy(block->block_contents+offset, tng_data->last_program_name, last_program_name_len);
-    offset += last_program_name_len;
+    return(TNG_SUCCESS);
+}
 
-    strncpy(block->block_contents+offset, tng_data->first_user_name, first_user_name_len);
-    offset += first_user_name_len;
-
-    strncpy(block->block_contents+offset, tng_data->last_user_name, last_user_name_len);
-    offset += last_user_name_len;
-
-    strncpy(block->block_contents+offset, tng_data->first_computer_name,
-            first_computer_name_len);
-    offset += first_computer_name_len;
-
-    strncpy(block->block_contents+offset, tng_data->last_computer_name,
-            last_computer_name_len);
-    offset += last_computer_name_len;
-
-    strncpy(block->block_contents+offset, tng_data->first_pgp_signature,
-            first_pgp_signature_len);
-    offset += first_pgp_signature_len;
+static tng_function_status tng_file_pos_of_subsequent_trajectory_block_get
+                (tng_trajectory_t tng_data,
+                 int64_t *pos)
+{
+    int64_t orig_pos, curr_frame_set_pos;
+    tng_gen_block_t block;
+    tng_function_status stat;
+    tng_trajectory_frame_set_t frame_set =
+    &tng_data->current_trajectory_frame_set;
 
-    strncpy(block->block_contents+offset, tng_data->last_pgp_signature,
-            last_pgp_signature_len);
-    offset += last_pgp_signature_len;
+    orig_pos = ftello(tng_data->input_file);
+    curr_frame_set_pos = tng_data->current_trajectory_frame_set_input_file_pos;
 
-    strncpy(block->block_contents+offset, tng_data->forcefield_name,
-            forcefield_name_len);
-    offset += forcefield_name_len;
+    *pos = tng_data->first_trajectory_frame_set_input_file_pos;
 
-    memcpy(block->block_contents+offset, &tng_data->time,
-           sizeof(tng_data->time));
-    if(tng_data->output_endianness_swap_func_64)
+    if(*pos <= 0)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        return(TNG_SUCCESS);
     }
-    offset += sizeof(tng_data->time);
 
-    memcpy(block->block_contents+offset, &tng_data->var_num_atoms_flag,
-           sizeof(tng_data->var_num_atoms_flag));
-    offset += sizeof(tng_data->var_num_atoms_flag);
+    fseeko(tng_data->input_file, *pos, SEEK_SET);
 
-    memcpy(block->block_contents+offset, &tng_data->frame_set_n_frames,
-           sizeof(tng_data->frame_set_n_frames));
-    if(tng_data->output_endianness_swap_func_64)
+    tng_block_init(&block);
+    /* Read block headers first to see that a frame set block is found. */
+    stat = tng_block_header_read(tng_data, block);
+    if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", *pos,
+                __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_FAILURE);
     }
-    offset += sizeof(tng_data->frame_set_n_frames);
 
-    memcpy(block->block_contents+offset,
-           &tng_data->first_trajectory_frame_set_input_file_pos,
-           sizeof(tng_data->first_trajectory_frame_set_input_file_pos));
-    if(tng_data->output_endianness_swap_func_64)
+    if(tng_block_read_next(tng_data, block,
+                           TNG_SKIP_HASH) != TNG_SUCCESS)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
     }
-    offset += sizeof(tng_data->first_trajectory_frame_set_input_file_pos);
 
-    memcpy(block->block_contents+offset,
-           &tng_data->last_trajectory_frame_set_input_file_pos,
-           sizeof(tng_data->last_trajectory_frame_set_input_file_pos));
-    if(tng_data->output_endianness_swap_func_64)
+    /* Read all frame set blocks (not the blocks between them) */
+    while(frame_set->next_frame_set_file_pos > 0)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
+        fseeko(tng_data->input_file, frame_set->next_frame_set_file_pos, SEEK_SET);
+        stat = tng_block_header_read(tng_data, block);
+        if(stat == TNG_CRITICAL)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", *pos,
                     __FILE__, __LINE__);
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
+        }
+        if(stat != TNG_SUCCESS || block->id != TNG_TRAJECTORY_FRAME_SET)
+        {
+            return(TNG_FAILURE);
         }
-    }
-    offset += sizeof(tng_data->last_trajectory_frame_set_input_file_pos);
 
-    memcpy(block->block_contents+offset, &tng_data->medium_stride_length,
-           sizeof(tng_data->medium_stride_length));
-    if(tng_data->output_endianness_swap_func_64)
-    {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
+        stat = tng_block_read_next(tng_data, block, TNG_SKIP_HASH);
+        if(stat != TNG_SUCCESS)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            tng_block_destroy(&block);
+            return(stat);
+        }
+        /* Update *pos if this is the earliest frame set so far (after orig_pos) */
+        if(tng_data->current_trajectory_frame_set_input_file_pos < *pos &&
+           tng_data->current_trajectory_frame_set_input_file_pos > orig_pos)
+        {
+            *pos = tng_data->current_trajectory_frame_set_input_file_pos;
         }
     }
-    offset += sizeof(tng_data->medium_stride_length);
 
-    memcpy(block->block_contents+offset, &tng_data->long_stride_length,
-           sizeof(tng_data->long_stride_length));
-    if(tng_data->output_endianness_swap_func_64)
+    /* Re-read the frame set that used to be the current one */
+    tng_reread_frame_set_at_file_pos(tng_data, curr_frame_set_pos);
+
+    fseeko(tng_data->input_file, orig_pos, SEEK_SET);
+
+    tng_block_destroy(&block);
+
+    return(TNG_SUCCESS);
+}
+
+static tng_function_status tng_frame_set_complete_migrate
+                (tng_trajectory_t tng_data,
+                 int64_t block_start_pos,
+                 int64_t block_len,
+                 int64_t new_pos)
+{
+    int64_t i;
+    tng_bool updated = TNG_FALSE;
+
+    char *contents;
+
+    if(tng_input_file_init(tng_data) != TNG_SUCCESS)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        return(TNG_CRITICAL);
     }
-    offset += sizeof(tng_data->long_stride_length);
 
-    memcpy(block->block_contents+offset, &tng_data->distance_unit_exponential,
-           sizeof(tng_data->distance_unit_exponential));
-    if(tng_data->output_endianness_swap_func_64)
+    fseeko(tng_data->input_file, block_start_pos, SEEK_SET);
+
+    contents = malloc(block_len);
+    if(!contents)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                      (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                block_len, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
     }
 
-    if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS)
+    if(fread(contents, block_len, 1, tng_data->input_file) == 0)
     {
-        fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n",
-               tng_data->output_file_path, __FILE__, __LINE__);
-        tng_block_destroy(&block);
+        fprintf(stderr, "TNG library: Cannot read data from file when migrating data. %s: %d\n",
+               __FILE__, __LINE__);
+        free(contents);
         return(TNG_CRITICAL);
     }
+    fseeko(tng_data->output_file, new_pos, SEEK_SET);
 
-    if(fwrite(block->block_contents, block->block_contents_size, 1,
-        tng_data->output_file) != 1)
+    if(fwrite(contents, block_len, 1, tng_data->output_file) != 1)
     {
-        fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, __LINE__);
-        tng_block_destroy(&block);
+        fprintf(stderr, "TNG library: Could not write data to file when migrating data. %s: %d\n",
+                __FILE__, __LINE__);
+        free(contents);
         return(TNG_CRITICAL);
     }
 
-    tng_block_destroy(&block);
+    tng_data->current_trajectory_frame_set_output_file_pos = new_pos;
+
+    tng_frame_set_pointers_update(tng_data, TNG_USE_HASH);
+
+    /* Update the general info block if needed */
+    if(block_start_pos == tng_data->first_trajectory_frame_set_output_file_pos)
+    {
+        tng_data->first_trajectory_frame_set_output_file_pos = new_pos;
+        updated = TNG_TRUE;
+    }
+    if(block_start_pos == tng_data->last_trajectory_frame_set_output_file_pos)
+    {
+        tng_data->last_trajectory_frame_set_output_file_pos = new_pos;
+        updated = TNG_TRUE;
+    }
+    if(updated)
+    {
+        tng_header_pointers_update(tng_data, TNG_USE_HASH);
+    }
+
+    /* Fill the block with NULL to avoid confusion. */
+    for(i = 0; i < block_len; i++)
+    {
+        contents[i] = '\0';
+    }
+    fseeko(tng_data->output_file, block_start_pos, SEEK_SET);
+
+    /* FIXME: casting block_len to size_t is dangerous */
+    fwrite(contents, 1, block_len, tng_data->output_file);
+
+    free(contents);
 
     return(TNG_SUCCESS);
 }
 
-/** Read the chain data of a molecules block.
- * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param chain is the chain data container.
- * @param offset is the offset of the block input and is updated when reading.
- * @return TNG_SUCCESS(0) is successful.
- */
-static tng_function_status tng_chain_data_read(tng_trajectory_t tng_data,
-                                               tng_gen_block_t block,
-                                               tng_chain_t chain,
-                                               int *offset)
+static tng_function_status tng_length_of_current_frame_set_contents_get
+                (tng_trajectory_t tng_data,
+                 int64_t *len)
 {
-    int len;
+    int64_t orig_pos, pos, curr_frame_set_pos;
+    tng_gen_block_t block;
+    tng_function_status stat;
 
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+    orig_pos = ftello(tng_data->input_file);
+    curr_frame_set_pos = pos = tng_data->current_trajectory_frame_set_input_file_pos;
 
-    memcpy(&chain->id, block->block_contents+*offset,
-            sizeof(chain->id));
-    if(tng_data->input_endianness_swap_func_64)
+    *len = 0;
+
+    fseeko(tng_data->input_file, curr_frame_set_pos, SEEK_SET);
+
+    tng_block_init(&block);
+    /* Read block headers first to see that a frame set block is found. */
+    stat = tng_block_header_read(tng_data, block);
+    if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   &chain->id)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
+                curr_frame_set_pos, __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_FAILURE);
     }
-    *offset += sizeof(chain->id);
-
-    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
-            TNG_MAX_STR_LEN);
-    chain->name = malloc(len);
-    strncpy(chain->name,
-            block->block_contents+*offset, len);
-    *offset += len;
 
-    memcpy(&chain->n_residues, block->block_contents+*offset,
-        sizeof(chain->n_residues));
-    if(tng_data->input_endianness_swap_func_64)
+    /* Read the headers of all blocks in the frame set (not the actual contents of them) */
+    while(stat == TNG_SUCCESS)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   &chain->n_residues)
-            != TNG_SUCCESS)
+        fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
+        *len += block->header_contents_size + block->block_contents_size;
+        pos += block->header_contents_size + block->block_contents_size;
+        if(pos >= tng_data->input_file_len)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            break;
+        }
+        stat = tng_block_header_read(tng_data, block);
+        if(block->id == TNG_TRAJECTORY_FRAME_SET)
+        {
+            break;
         }
     }
-    *offset += sizeof(chain->n_residues);
+
+    /* Re-read the frame set that used to be the current one */
+    tng_reread_frame_set_at_file_pos(tng_data, curr_frame_set_pos);
+
+    fseeko(tng_data->input_file, orig_pos, SEEK_SET);
+
+    tng_block_destroy(&block);
 
     return(TNG_SUCCESS);
 }
 
-/** Write the chain data of a molecules block.
+/** Migrate blocks in the file to make room for new data in a block. This
+ * is required e.g. when adding data to a block or extending strings in a
+ * block.
  * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param chain is the chain data container.
- * @param offset is the offset of the block output and is updated when writing.
- * @return TNG_SUCCESS(0) is successful.
+ * @param start_pos is the position from which to start moving data, usually
+ * the byte after the end of the block to which data was added.
+ * @param offset is the number of bytes that were inserted.
+ * @details Trajectory blocks (frame sets and their related blocks) are moved
+ * to the end of the file (if needed) in order to make room for non-trajectory
+ * data.
  */
-static tng_function_status tng_chain_data_write(tng_trajectory_t tng_data,
-                                                tng_gen_block_t block,
-                                                tng_chain_t chain,
-                                                int *offset)
+static tng_function_status tng_migrate_data_in_file
+                (tng_trajectory_t tng_data,
+                 int64_t start_pos,
+                 int64_t offset)
 {
-    int len;
-
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+    int64_t traj_start_pos, empty_space, orig_file_pos, frame_set_length;
+    tng_gen_block_t block;
+    tng_function_status stat;
+    FILE *temp;
 
-    memcpy(block->block_contents+*offset, &chain->id, sizeof(chain->id));
-    if(tng_data->output_endianness_swap_func_64)
+    if(offset <= 0)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                    (int64_t *)block->header_contents+*offset)
-            != TNG_SUCCESS)
+        return(TNG_SUCCESS);
+    }
+
+    temp = tng_data->input_file;
+
+    stat = tng_file_pos_of_subsequent_trajectory_block_get(tng_data, &traj_start_pos);
+    if(stat != TNG_SUCCESS)
+    {
+        tng_data->input_file = temp;
+        return(stat);
+    }
+
+    tng_data->current_trajectory_frame_set_input_file_pos = traj_start_pos;
+
+    empty_space = traj_start_pos - (start_pos - 1);
+
+    if(empty_space >= offset)
+    {
+        return(TNG_SUCCESS);
+    }
+
+    orig_file_pos = ftello(tng_data->input_file);
+    tng_block_init(&block);
+
+    while(empty_space < offset)
+    {
+        fseeko(tng_data->input_file, traj_start_pos, SEEK_SET);
+        stat = tng_block_header_read(tng_data, block);
+        if(stat == TNG_CRITICAL)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot read block header. %s: %d\n",
                     __FILE__, __LINE__);
+            tng_block_destroy(&block);
+            tng_data->input_file = temp;
+            return(TNG_CRITICAL);
+        }
+        if(stat != TNG_SUCCESS || block->id != TNG_TRAJECTORY_FRAME_SET)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(TNG_FAILURE);
+        }
+        stat = tng_length_of_current_frame_set_contents_get(tng_data, &frame_set_length);
+        if(stat != TNG_SUCCESS)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(stat);
+        }
+        stat = tng_frame_set_complete_migrate(tng_data, traj_start_pos,
+                                              frame_set_length, tng_data->input_file_len);
+        if(stat != TNG_SUCCESS)
+        {
+            tng_data->input_file = temp;
+            tng_block_destroy(&block);
+            return(stat);
         }
+
+        empty_space += frame_set_length;
     }
-    *offset += sizeof(chain->id);
+    fseeko(tng_data->input_file, orig_file_pos, SEEK_SET);
+    tng_block_destroy(&block);
 
-    len = tng_min_i((int)strlen(chain->name) + 1, TNG_MAX_STR_LEN);
-    strncpy(block->block_contents + *offset, chain->name, len);
-    *offset += len;
+    return(TNG_SUCCESS);
+}
 
-    memcpy(block->block_contents+*offset, &chain->n_residues,
-        sizeof(chain->n_residues));
-    if(tng_data->output_endianness_swap_func_64)
+static tng_function_status tng_block_header_len_calculate
+                (const tng_trajectory_t tng_data,
+                 tng_gen_block_t block,
+                 int64_t *len)
+{
+    int name_len;
+    (void)tng_data;
+
+    /* If the string is unallocated allocate memory for just string
+     * termination */
+    if(!block->name)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                    (int64_t *)block->header_contents+*offset)
-            != TNG_SUCCESS)
+        block->name = malloc(1);
+        if(!block->name)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
         }
+        block->name[0] = 0;
     }
-    *offset += sizeof(chain->n_residues);
 
-    return(TNG_SUCCESS);
+    name_len = tng_min_i((int)strlen(block->name) + 1, TNG_MAX_STR_LEN);
+
+    /* Calculate the size of the header to write */
+    *len = sizeof(block->header_contents_size) +
+                  sizeof(block->block_contents_size) +
+                  sizeof(block->id) +
+                  sizeof(block->block_version) +
+                  TNG_MD5_HASH_LEN +
+                  name_len;
+
+    return (TNG_SUCCESS);
 }
 
-/** Read the residue data of a molecules block.
+/** Write the header of a data block, regardless of its type
  * @param tng_data is a trajectory data container.
  * @param block is a general block container.
- * @param residue is the residue data container.
- * @param offset is the offset of the block input and is updated when reading.
- * @return TNG_SUCCESS(0) is successful.
+ * @param hash_mode is an option to decide whether to use the md5 hash or not.
+ * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
  */
-static tng_function_status tng_residue_data_read(tng_trajectory_t tng_data,
-                                                 tng_gen_block_t block,
-                                                 tng_residue_t residue,
-                                                 int *offset)
+static tng_function_status tng_block_header_write
+                (tng_trajectory_t tng_data,
+                 tng_gen_block_t block,
+                 const char hash_mode)
 {
-    int len;
+    int name_len, offset = 0;
 
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+    TNG_ASSERT(block != 0, "TNG library: Trying to write uninitialized block (NULL pointer).");
 
-    memcpy(&residue->id, block->block_contents+*offset,
-        sizeof(residue->id));
-    if(tng_data->input_endianness_swap_func_64)
+    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   &residue->id)
+        fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
+               __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    if(tng_block_header_len_calculate(tng_data, block, &block->header_contents_size) !=
+        TNG_SUCCESS)
+    {
+        fprintf(stderr, "TNG library: Cannot calculate length of block header. %s: %d\n",
+                __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    if(hash_mode == TNG_USE_HASH)
+    {
+        tng_block_md5_hash_generate(block);
+    }
+
+    if(block->header_contents)
+    {
+        free(block->header_contents);
+    }
+
+    block->header_contents = malloc(block->header_contents_size);
+    if(!block->header_contents)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+               block->header_contents_size, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    name_len = tng_min_i((int)strlen(block->name) + 1, TNG_MAX_STR_LEN);
+
+    /* First copy all data into the header_contents block and finally write
+     * the whole block at once. */
+    memcpy(block->header_contents, &block->header_contents_size,
+           sizeof(block->header_contents_size));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    *offset += sizeof(residue->id);
-
-    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
-            TNG_MAX_STR_LEN);
-    residue->name = malloc(len);
-    strncpy(residue->name,
-            block->block_contents+*offset, len);
-    *offset += len;
+    offset += sizeof(block->header_contents_size);
 
-    memcpy(&residue->n_atoms, block->block_contents+*offset,
-            sizeof(residue->n_atoms));
-    if(tng_data->input_endianness_swap_func_64)
+    memcpy(block->header_contents+offset, &block->block_contents_size,
+           sizeof(block->block_contents_size));
+    if(tng_data->output_endianness_swap_func_64)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   &residue->n_atoms)
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    *offset += sizeof(residue->n_atoms);
-
-    return(TNG_SUCCESS);
-}
-
-/** Write the residue data of a molecules block.
- * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param residue is the residue data container.
- * @param offset is the offset of the block output and is updated when writing.
- * @return TNG_SUCCESS(0) is successful.
- */
-static tng_function_status tng_residue_data_write(tng_trajectory_t tng_data,
-                                                  tng_gen_block_t block,
-                                                  tng_residue_t residue,
-                                                  int *offset)
-{
-    int len;
-
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+    offset += sizeof(block->block_contents_size);
 
-    memcpy(block->block_contents+*offset, &residue->id, sizeof(residue->id));
+    memcpy(block->header_contents+offset, &block->id, sizeof(block->id));
     if(tng_data->output_endianness_swap_func_64)
     {
         if(tng_data->output_endianness_swap_func_64(tng_data,
-                                    (int64_t *)block->header_contents+*offset)
+                                      (int64_t *)block->header_contents+offset)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    *offset += sizeof(residue->id);
+    offset += sizeof(block->id);
 
-    len = tng_min_i((int)strlen(residue->name) + 1, TNG_MAX_STR_LEN);
-    strncpy(block->block_contents + *offset, residue->name, len);
-    *offset += len;
+    memcpy(block->header_contents+offset, block->md5_hash, TNG_MD5_HASH_LEN);
+    offset += TNG_MD5_HASH_LEN;
 
-    memcpy(block->block_contents+*offset, &residue->n_atoms,
-        sizeof(residue->n_atoms));
+    strncpy(block->header_contents+offset, block->name, name_len);
+    offset += name_len;
+
+    memcpy(block->header_contents+offset, &block->block_version,
+           sizeof(block->block_version));
     if(tng_data->output_endianness_swap_func_64)
     {
         if(tng_data->output_endianness_swap_func_64(tng_data,
-                                    (int64_t *)block->header_contents+*offset)
+                                      (int64_t *)block->header_contents+offset)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    *offset += sizeof(residue->n_atoms);
 
+    if(fwrite(block->header_contents, block->header_contents_size,
+       1, tng_data->output_file) != 1)
+    {
+        fprintf(stderr, "TNG library: Could not write all header data. %s: %d\n", __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
     return(TNG_SUCCESS);
 }
 
-/** Read the atom data of a molecules block.
- * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param atom is the atom data container.
- * @param offset is the offset of the block input and is updated when reading.
- * @return TNG_SUCCESS(0) is successful.
- */
-static tng_function_status tng_atom_data_read(tng_trajectory_t tng_data,
-                                              tng_gen_block_t block,
-                                              tng_atom_t atom,
-                                              int *offset)
+static tng_function_status tng_general_info_block_len_calculate
+                (tng_trajectory_t tng_data,
+                 int64_t *len)
 {
-    int len;
-
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+    int first_program_name_len, first_user_name_len;
+    int first_computer_name_len, first_pgp_signature_len;
+    int last_program_name_len, last_user_name_len;
+    int last_computer_name_len, last_pgp_signature_len;
+    int forcefield_name_len;
 
-    memcpy(&atom->id, block->block_contents+*offset,
-        sizeof(atom->id));
-    if(tng_data->input_endianness_swap_func_64)
+    /* If the strings are unallocated allocate memory for just string
+     * termination */
+    if(!tng_data->first_program_name)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                    &atom->id)
-            != TNG_SUCCESS)
+        tng_data->first_program_name = malloc(1);
+        if(!tng_data->first_program_name)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
         }
+        tng_data->first_program_name[0] = 0;
     }
-    *offset += sizeof(atom->id);
-
-    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
-            TNG_MAX_STR_LEN);
-    atom->name = malloc(len);
-    strncpy(atom->name,
-            block->block_contents+*offset, len);
-    *offset += len;
-
-    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
-            TNG_MAX_STR_LEN);
-    atom->atom_type = malloc(len);
-    strncpy(atom->atom_type,
-            block->block_contents+*offset, len);
-    *offset += len;
-
-    return(TNG_SUCCESS);
-}
-
-/** Write the atom data of a molecules block.
- * @param tng_data is a trajectory data container.
- * @param block is a general block container.
- * @param atom is the atom data container.
- * @param offset is the offset of the block output and is updated when writing.
- * @return TNG_SUCCESS(0) is successful.
- */
-static tng_function_status tng_atom_data_write(tng_trajectory_t tng_data,
-                                               tng_gen_block_t block,
-                                               tng_atom_t atom,
-                                               int *offset)
-{
-    int len;
-
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
-
-    memcpy(block->block_contents+*offset, &atom->id,
-            sizeof(atom->id));
-    if(tng_data->output_endianness_swap_func_64)
+    if(!tng_data->last_program_name)
     {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-                                    (int64_t *)block->header_contents+*offset)
-            != TNG_SUCCESS)
+        tng_data->last_program_name = malloc(1);
+        if(!tng_data->last_program_name)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
         }
+        tng_data->last_program_name[0] = 0;
+    }
+    if(!tng_data->first_user_name)
+    {
+        tng_data->first_user_name = malloc(1);
+        if(!tng_data->first_user_name)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->first_user_name[0] = 0;
+    }
+    if(!tng_data->last_user_name)
+    {
+        tng_data->last_user_name = malloc(1);
+        if(!tng_data->last_user_name)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->last_user_name[0] = 0;
+    }
+    if(!tng_data->first_computer_name)
+    {
+        tng_data->first_computer_name = malloc(1);
+        if(!tng_data->first_computer_name)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->first_computer_name[0] = 0;
+    }
+    if(!tng_data->last_computer_name)
+    {
+        tng_data->last_computer_name = malloc(1);
+        if(!tng_data->last_computer_name)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->last_computer_name[0] = 0;
+    }
+    if(!tng_data->first_pgp_signature)
+    {
+        tng_data->first_pgp_signature = malloc(1);
+        if(!tng_data->first_pgp_signature)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->first_pgp_signature[0] = 0;
+    }
+    if(!tng_data->last_pgp_signature)
+    {
+        tng_data->last_pgp_signature = malloc(1);
+        if(!tng_data->last_pgp_signature)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->last_pgp_signature[0] = 0;
+    }
+    if(!tng_data->forcefield_name)
+    {
+        tng_data->forcefield_name = malloc(1);
+        if(!tng_data->forcefield_name)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+        tng_data->forcefield_name[0] = 0;
     }
-    *offset += sizeof(atom->id);
 
-    len = tng_min_i((int)strlen(atom->name) + 1, TNG_MAX_STR_LEN);
-    strncpy(block->block_contents + *offset, atom->name, len);
-    *offset += len;
+    first_program_name_len = tng_min_i((int)strlen(tng_data->first_program_name) + 1,
+                           TNG_MAX_STR_LEN);
+    last_program_name_len = tng_min_i((int)strlen(tng_data->last_program_name) + 1,
+                           TNG_MAX_STR_LEN);
+    first_user_name_len = tng_min_i((int)strlen(tng_data->first_user_name) + 1,
+                        TNG_MAX_STR_LEN);
+    last_user_name_len = tng_min_i((int)strlen(tng_data->last_user_name) + 1,
+                        TNG_MAX_STR_LEN);
+    first_computer_name_len = tng_min_i((int)strlen(tng_data->first_computer_name) + 1,
+                            TNG_MAX_STR_LEN);
+    last_computer_name_len = tng_min_i((int)strlen(tng_data->last_computer_name) + 1,
+                            TNG_MAX_STR_LEN);
+    first_pgp_signature_len = tng_min_i((int)strlen(tng_data->first_pgp_signature) + 1,
+                            TNG_MAX_STR_LEN);
+    last_pgp_signature_len = tng_min_i((int)strlen(tng_data->last_pgp_signature) + 1,
+                            TNG_MAX_STR_LEN);
+    forcefield_name_len = tng_min_i((int)strlen(tng_data->forcefield_name) + 1,
+                              TNG_MAX_STR_LEN);
 
-    len = tng_min_i((int)strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN);
-    strncpy(block->block_contents + *offset, atom->atom_type, len);
-    *offset += len;
+    *len = sizeof(tng_data->time) +
+                  sizeof(tng_data->var_num_atoms_flag) +
+                  sizeof(tng_data->frame_set_n_frames) +
+                  sizeof(tng_data->first_trajectory_frame_set_input_file_pos) +
+                  sizeof(tng_data->last_trajectory_frame_set_input_file_pos) +
+                  sizeof(tng_data->medium_stride_length) +
+                  sizeof(tng_data->long_stride_length) +
+                  sizeof(tng_data->distance_unit_exponential) +
+                  first_program_name_len +
+                  last_program_name_len +
+                  first_user_name_len +
+                  last_user_name_len +
+                  first_computer_name_len +
+                  last_computer_name_len +
+                  first_pgp_signature_len +
+                  last_pgp_signature_len +
+                  forcefield_name_len;
 
     return(TNG_SUCCESS);
 }
 
-/** Read a molecules block. Contains chain, residue and atom data
+/** Read a general info block. This is the first block of a TNG file.
+ *  Populate the fields in tng_data.
  * @param tng_data is a trajectory data container.
  * @param block is a general block container.
  * @param hash_mode is an option to decide whether to use the md5 hash or not.
@@ -2119,37 +2168,32 @@ static tng_function_status tng_atom_data_write(tng_trajectory_t tng_data,
  * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
  * error has occured.
  */
-static tng_function_status tng_molecules_block_read
-                (tng_trajectory_t tng_data,
-                 tng_gen_block_t block,
+static tng_function_status tng_general_info_block_read
+                (tng_trajectory_t tng_data, tng_gen_block_t block,
                  const char hash_mode)
 {
-    int64_t i, j, k, l;
     int len, offset = 0;
-    tng_molecule_t molecule;
-    tng_chain_t chain;
-    tng_residue_t residue;
-    tng_atom_t atom;
-    tng_bond_t bond;
     tng_bool same_hash;
 
+    void *temp;
+
+    TNG_ASSERT(block != 0, "TNG library: Trying to read data to an uninitialized block (NULL pointer)");
+
     if(tng_input_file_init(tng_data) != TNG_SUCCESS)
     {
         return(TNG_CRITICAL);
     }
 
-    if(block->block_contents)
-    {
-        free(block->block_contents);
-    }
-
-    block->block_contents = malloc(block->block_contents_size);
-    if(!block->block_contents)
+    temp = realloc(block->block_contents, block->block_contents_size);
+    if(!temp)
     {
         fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
                block->block_contents_size, __FILE__, __LINE__);
+        free(block->block_contents);
+        block->block_contents = 0;
         return(TNG_CRITICAL);
     }
+    block->block_contents = temp;
 
     /* Read the whole block into block_contents to be able to write it to disk
      * even if it cannot be interpreted. */
@@ -2157,6 +2201,7 @@ static tng_function_status tng_molecules_block_read
              tng_data->input_file) == 0)
     {
         fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
+        return(TNG_CRITICAL);
     }
 
     /* FIXME: Does not check if the size of the contents matches the expected
@@ -2167,202 +2212,1170 @@ static tng_function_status tng_molecules_block_read
         tng_md5_hash_match_verify(block, &same_hash);
         if(same_hash != TNG_TRUE)
         {
-            fprintf(stderr, "TNG library: Molecules block contents corrupt. Hashes do not match. "
+            fprintf(stderr, "TNG library: General info block contents corrupt. Hashes do not match. "
                 "%s: %d\n",
                 __FILE__, __LINE__);
+    /*         return(TNG_FAILURE); */
         }
     }
 
-    if(tng_data->molecules)
+    len = tng_min_i((int)strlen(block->block_contents) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->first_program_name, len);
+    if(!temp)
     {
-        for(i=tng_data->n_molecules; i--;)
-        {
-            tng_molecule_destroy(tng_data, &tng_data->molecules[i]);
-        }
-        free(tng_data->molecules);
-        tng_data->molecules = 0;
-        tng_data->n_molecules = 0;
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->first_program_name);
+        tng_data->first_program_name = 0;
+        return(TNG_CRITICAL);
     }
+    tng_data->first_program_name = temp;
+    strncpy(tng_data->first_program_name, block->block_contents, len);
+    offset += len;
 
-    memcpy(&tng_data->n_molecules, block->block_contents,
-           sizeof(tng_data->n_molecules));
-    if(tng_data->input_endianness_swap_func_64)
+    len = tng_min_i((int)strlen(block->block_contents + offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->last_program_name, len);
+    if(!temp)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   &tng_data->n_molecules)
-            != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
-        }
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->last_program_name);
+        tng_data->last_program_name = 0;
+        return(TNG_CRITICAL);
     }
-    offset += sizeof(tng_data->n_molecules);
+    tng_data->last_program_name = temp;
+    strncpy(tng_data->last_program_name, block->block_contents + offset, len);
+    offset += len;
 
-    if(tng_data->molecules)
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->first_user_name, len);
+    if(!temp)
     {
-        free(tng_data->molecules);
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->first_user_name);
+        tng_data->first_user_name = 0;
+        return(TNG_CRITICAL);
     }
+    tng_data->first_user_name = temp;
+    strncpy(tng_data->first_user_name, block->block_contents+offset, len);
+    offset += len;
 
-    tng_data->n_particles = 0;
-
-    tng_data->molecules = malloc(tng_data->n_molecules *
-                          sizeof(struct tng_molecule));
-    if(!tng_data->molecules)
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->last_user_name, len);
+    if(!temp)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               tng_data->n_molecules * sizeof(struct tng_molecule),
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
                __FILE__, __LINE__);
+        free(tng_data->last_user_name);
+        tng_data->last_user_name = 0;
         return(TNG_CRITICAL);
     }
+    tng_data->last_user_name = temp;
+    strncpy(tng_data->last_user_name, block->block_contents+offset, len);
+    offset += len;
 
-    if(!tng_data->var_num_atoms_flag)
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->first_computer_name, len);
+    if(!temp)
     {
-        if(tng_data->molecule_cnt_list)
-        {
-            free(tng_data->molecule_cnt_list);
-        }
-        tng_data->molecule_cnt_list = malloc(sizeof(int64_t) *
-                                      tng_data->n_molecules);
-        if(!tng_data->molecule_cnt_list)
-        {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-                   tng_data->n_molecules * sizeof(struct tng_molecule),
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
-        }
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->first_computer_name);
+        tng_data->first_computer_name = 0;
+        return(TNG_CRITICAL);
     }
+    tng_data->first_computer_name = temp;
+    strncpy(tng_data->first_computer_name, block->block_contents+offset, len);
+    offset += len;
 
-    /* Read each molecule from file */
-    for(i=0; i < tng_data->n_molecules; i++)
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->last_computer_name, len);
+    if(!temp)
     {
-        molecule = &tng_data->molecules[i];
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->last_computer_name);
+        tng_data->last_computer_name = 0;
+        return(TNG_CRITICAL);
+    }
+    tng_data->last_computer_name = temp;
+    strncpy(tng_data->last_computer_name, block->block_contents+offset, len);
+    offset += len;
 
-        memcpy(&molecule->id, block->block_contents+offset,
-               sizeof(molecule->id));
-        if(tng_data->input_endianness_swap_func_64)
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->first_pgp_signature, len);
+    if(!temp)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->first_pgp_signature);
+        tng_data->first_pgp_signature = 0;
+        return(TNG_CRITICAL);
+    }
+    tng_data->first_pgp_signature = temp;
+    strncpy(tng_data->first_pgp_signature, block->block_contents+offset, len);
+    offset += len;
+
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->last_pgp_signature, len);
+    if(!temp)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->last_pgp_signature);
+        tng_data->last_pgp_signature = 0;
+        return(TNG_CRITICAL);
+    }
+    tng_data->last_pgp_signature = temp;
+    strncpy(tng_data->last_pgp_signature, block->block_contents+offset, len);
+    offset += len;
+
+    len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+    temp = realloc(tng_data->forcefield_name, len);
+    if(!temp)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len,
+               __FILE__, __LINE__);
+        free(tng_data->forcefield_name);
+        tng_data->forcefield_name = 0;
+        return(TNG_CRITICAL);
+    }
+    tng_data->forcefield_name = temp;
+    strncpy(tng_data->forcefield_name, block->block_contents+offset, len);
+    offset += len;
+
+    memcpy(&tng_data->time, block->block_contents+offset,
+           sizeof(tng_data->time));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &tng_data->time)
+            != TNG_SUCCESS)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       &molecule->id)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
         }
-        offset += sizeof(molecule->id);
+    }
+    offset += sizeof(tng_data->time);
 
-/*         fprintf(stderr, "TNG library: Read id: %"PRId64" offset: %d\n", molecule->id, offset);*/
-        len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
-        molecule->name = malloc(len);
-        strncpy(molecule->name, block->block_contents+offset, len);
-        offset += len;
+    memcpy(&tng_data->var_num_atoms_flag, block->block_contents+offset,
+           sizeof(tng_data->var_num_atoms_flag));
+    offset += sizeof(tng_data->var_num_atoms_flag);
 
-        memcpy(&molecule->quaternary_str, block->block_contents+offset,
-               sizeof(molecule->quaternary_str));
-        if(tng_data->input_endianness_swap_func_64)
+    memcpy(&tng_data->frame_set_n_frames, block->block_contents+offset,
+           sizeof(tng_data->frame_set_n_frames));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                 &tng_data->frame_set_n_frames)
+            != TNG_SUCCESS)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                     &molecule->quaternary_str)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
         }
-        offset += sizeof(molecule->quaternary_str);
+    }
+    offset += sizeof(tng_data->frame_set_n_frames);
 
-        if(!tng_data->var_num_atoms_flag)
+    memcpy(&tng_data->first_trajectory_frame_set_input_file_pos,
+           block->block_contents+offset,
+           sizeof(tng_data->first_trajectory_frame_set_input_file_pos));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                          &tng_data->first_trajectory_frame_set_input_file_pos)
+            != TNG_SUCCESS)
         {
-            memcpy(&tng_data->molecule_cnt_list[i],
-                   block->block_contents+offset,
-                   sizeof(int64_t));
-            if(tng_data->input_endianness_swap_func_64)
-            {
-                if(tng_data->input_endianness_swap_func_64(tng_data,
-                                               &tng_data->molecule_cnt_list[i])
-                    != TNG_SUCCESS)
-                {
-                    fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                            __FILE__, __LINE__);
-                }
-            }
-            offset += sizeof(int64_t);
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
         }
+    }
+    offset += sizeof(tng_data->first_trajectory_frame_set_input_file_pos);
 
+    tng_data->current_trajectory_frame_set.next_frame_set_file_pos =
+    tng_data->first_trajectory_frame_set_input_file_pos;
 
-        memcpy(&molecule->n_chains, block->block_contents+offset,
-               sizeof(molecule->n_chains));
-        if(tng_data->input_endianness_swap_func_64)
+
+    memcpy(&tng_data->last_trajectory_frame_set_input_file_pos,
+           block->block_contents+offset,
+           sizeof(tng_data->last_trajectory_frame_set_input_file_pos));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                          &tng_data->last_trajectory_frame_set_input_file_pos)
+            != TNG_SUCCESS)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       &molecule->n_chains)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
         }
-        offset += sizeof(molecule->n_chains);
+    }
+    offset += sizeof(tng_data->last_trajectory_frame_set_input_file_pos);
 
-        memcpy(&molecule->n_residues, block->block_contents+offset,
-               sizeof(molecule->n_residues));
-        if(tng_data->input_endianness_swap_func_64)
+    memcpy(&tng_data->medium_stride_length, block->block_contents+offset,
+           sizeof(tng_data->medium_stride_length));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                               &tng_data->medium_stride_length)
+            != TNG_SUCCESS)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       &molecule->n_residues)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
         }
-        offset += sizeof(molecule->n_residues);
+    }
+    offset += sizeof(tng_data->medium_stride_length);
 
-        memcpy(&molecule->n_atoms, block->block_contents+offset,
-               sizeof(molecule->n_atoms));
+    memcpy(&tng_data->long_stride_length, block->block_contents+offset,
+           sizeof(tng_data->long_stride_length));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &tng_data->long_stride_length)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->long_stride_length);
+
+    if(block->block_version >= 3)
+    {
+        memcpy(&tng_data->distance_unit_exponential, block->block_contents+offset,
+            sizeof(tng_data->distance_unit_exponential));
         if(tng_data->input_endianness_swap_func_64)
         {
             if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       &molecule->n_atoms)
+                                          &tng_data->distance_unit_exponential)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
-        offset += sizeof(molecule->n_atoms);
-
-        tng_data->n_particles += molecule->n_atoms *
-                                 tng_data->molecule_cnt_list[i];
-
-        if(molecule->n_chains > 0)
-        {
-            molecule->chains = malloc(molecule->n_chains *
-                                    sizeof(struct tng_chain));
-            if(!molecule->chains)
-            {
-                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-                    molecule->n_chains * sizeof(struct tng_chain),
-                    __FILE__, __LINE__);
-                return(TNG_CRITICAL);
-            }
+    }
 
-            chain = molecule->chains;
-        }
-        else
-        {
-            chain = 0;
-        }
+    return(TNG_SUCCESS);
+}
 
-        if(molecule->n_residues > 0)
-        {
-            molecule->residues = malloc(molecule->n_residues *
-                                sizeof(struct tng_residue));
-            if(!molecule->residues)
-            {
-                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-                    molecule->n_residues * sizeof(struct tng_residue),
-                    __FILE__, __LINE__);
+/** Write a general info block. This is the first block of a TNG file.
+ * @param tng_data is a trajectory data container.
+ * @param hash_mode is an option to decide whether to use the md5 hash or not.
+ * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
+ */
+static tng_function_status tng_general_info_block_write
+                (tng_trajectory_t tng_data,
+                 const char hash_mode)
+{
+    int first_program_name_len, first_user_name_len;
+    int first_computer_name_len, first_pgp_signature_len;
+    int last_program_name_len, last_user_name_len;
+    int last_computer_name_len, last_pgp_signature_len;
+    int forcefield_name_len, name_len;
+    int offset = 0;
+    tng_gen_block_t block;
+
+    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
+    {
+        return(TNG_CRITICAL);
+    }
+
+    fseeko(tng_data->output_file, 0, SEEK_SET);
+
+    tng_block_init(&block);
+
+    name_len = (int)strlen("GENERAL INFO");
+
+    block->name = malloc(name_len + 1);
+    if(!block->name)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+                name_len+1, __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
+    }
+
+    strcpy(block->name, "GENERAL INFO");
+    block->id = TNG_GENERAL_INFO;
+
+    if(tng_general_info_block_len_calculate(tng_data, &block->block_contents_size) !=
+        TNG_SUCCESS)
+    {
+        fprintf(stderr, "TNG library: Cannot calculate length of general info block. %s: %d\n",
+                __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
+    }
+
+    first_program_name_len = tng_min_i((int)strlen(tng_data->first_program_name) + 1,
+                           TNG_MAX_STR_LEN);
+    last_program_name_len = tng_min_i((int)strlen(tng_data->last_program_name) + 1,
+                           TNG_MAX_STR_LEN);
+    first_user_name_len = tng_min_i((int)strlen(tng_data->first_user_name) + 1,
+                        TNG_MAX_STR_LEN);
+    last_user_name_len = tng_min_i((int)strlen(tng_data->last_user_name) + 1,
+                        TNG_MAX_STR_LEN);
+    first_computer_name_len = tng_min_i((int)strlen(tng_data->first_computer_name) + 1,
+                            TNG_MAX_STR_LEN);
+    last_computer_name_len = tng_min_i((int)strlen(tng_data->last_computer_name) + 1,
+                            TNG_MAX_STR_LEN);
+    first_pgp_signature_len = tng_min_i((int)strlen(tng_data->first_pgp_signature) + 1,
+                            TNG_MAX_STR_LEN);
+    last_pgp_signature_len = tng_min_i((int)strlen(tng_data->last_pgp_signature) + 1,
+                            TNG_MAX_STR_LEN);
+    forcefield_name_len = tng_min_i((int)strlen(tng_data->forcefield_name) + 1,
+                              TNG_MAX_STR_LEN);
+
+    if(block->block_contents)
+    {
+        free(block->block_contents);
+    }
+    block->block_contents = malloc(block->block_contents_size);
+    if(!block->block_contents)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+               block->block_contents_size, __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
+    }
+
+    strncpy(block->block_contents, tng_data->first_program_name, first_program_name_len);
+    offset += first_program_name_len;
+
+    strncpy(block->block_contents+offset, tng_data->last_program_name, last_program_name_len);
+    offset += last_program_name_len;
+
+    strncpy(block->block_contents+offset, tng_data->first_user_name, first_user_name_len);
+    offset += first_user_name_len;
+
+    strncpy(block->block_contents+offset, tng_data->last_user_name, last_user_name_len);
+    offset += last_user_name_len;
+
+    strncpy(block->block_contents+offset, tng_data->first_computer_name,
+            first_computer_name_len);
+    offset += first_computer_name_len;
+
+    strncpy(block->block_contents+offset, tng_data->last_computer_name,
+            last_computer_name_len);
+    offset += last_computer_name_len;
+
+    strncpy(block->block_contents+offset, tng_data->first_pgp_signature,
+            first_pgp_signature_len);
+    offset += first_pgp_signature_len;
+
+    strncpy(block->block_contents+offset, tng_data->last_pgp_signature,
+            last_pgp_signature_len);
+    offset += last_pgp_signature_len;
+
+    strncpy(block->block_contents+offset, tng_data->forcefield_name,
+            forcefield_name_len);
+    offset += forcefield_name_len;
+
+    memcpy(block->block_contents+offset, &tng_data->time,
+           sizeof(tng_data->time));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->time);
+
+    memcpy(block->block_contents+offset, &tng_data->var_num_atoms_flag,
+           sizeof(tng_data->var_num_atoms_flag));
+    offset += sizeof(tng_data->var_num_atoms_flag);
+
+    memcpy(block->block_contents+offset, &tng_data->frame_set_n_frames,
+           sizeof(tng_data->frame_set_n_frames));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->frame_set_n_frames);
+
+    memcpy(block->block_contents+offset,
+           &tng_data->first_trajectory_frame_set_output_file_pos,
+           sizeof(tng_data->first_trajectory_frame_set_output_file_pos));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->first_trajectory_frame_set_output_file_pos);
+
+    memcpy(block->block_contents+offset,
+           &tng_data->last_trajectory_frame_set_output_file_pos,
+           sizeof(tng_data->last_trajectory_frame_set_output_file_pos));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->last_trajectory_frame_set_output_file_pos);
+
+    memcpy(block->block_contents+offset, &tng_data->medium_stride_length,
+           sizeof(tng_data->medium_stride_length));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->medium_stride_length);
+
+    memcpy(block->block_contents+offset, &tng_data->long_stride_length,
+           sizeof(tng_data->long_stride_length));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->long_stride_length);
+
+    memcpy(block->block_contents+offset, &tng_data->distance_unit_exponential,
+           sizeof(tng_data->distance_unit_exponential));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                      (int64_t *)block->header_contents+offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+
+    if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS)
+    {
+        fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n",
+               tng_data->output_file_path, __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
+    }
+
+    if(fwrite(block->block_contents, block->block_contents_size, 1,
+        tng_data->output_file) != 1)
+    {
+        fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
+    }
+
+    tng_block_destroy(&block);
+
+    return(TNG_SUCCESS);
+}
+
+/** Read the chain data of a molecules block.
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param chain is the chain data container.
+ * @param offset is the offset of the block input and is updated when reading.
+ * @return TNG_SUCCESS(0) is successful.
+ */
+static tng_function_status tng_chain_data_read(tng_trajectory_t tng_data,
+                                               tng_gen_block_t block,
+                                               tng_chain_t chain,
+                                               int *offset)
+{
+    int len;
+
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+
+    memcpy(&chain->id, block->block_contents+*offset,
+            sizeof(chain->id));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &chain->id)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(chain->id);
+
+    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
+            TNG_MAX_STR_LEN);
+    chain->name = malloc(len);
+    strncpy(chain->name,
+            block->block_contents+*offset, len);
+    *offset += len;
+
+    memcpy(&chain->n_residues, block->block_contents+*offset,
+        sizeof(chain->n_residues));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &chain->n_residues)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(chain->n_residues);
+
+    return(TNG_SUCCESS);
+}
+
+/** Write the chain data of a molecules block.
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param chain is the chain data container.
+ * @param offset is the offset of the block output and is updated when writing.
+ * @return TNG_SUCCESS(0) is successful.
+ */
+static tng_function_status tng_chain_data_write(tng_trajectory_t tng_data,
+                                                tng_gen_block_t block,
+                                                tng_chain_t chain,
+                                                int *offset)
+{
+    int len;
+
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+
+    memcpy(block->block_contents+*offset, &chain->id, sizeof(chain->id));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                    (int64_t *)block->header_contents+*offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(chain->id);
+
+    len = tng_min_i((int)strlen(chain->name) + 1, TNG_MAX_STR_LEN);
+    strncpy(block->block_contents + *offset, chain->name, len);
+    *offset += len;
+
+    memcpy(block->block_contents+*offset, &chain->n_residues,
+        sizeof(chain->n_residues));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                    (int64_t *)block->header_contents+*offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(chain->n_residues);
+
+    return(TNG_SUCCESS);
+}
+
+/** Read the residue data of a molecules block.
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param residue is the residue data container.
+ * @param offset is the offset of the block input and is updated when reading.
+ * @return TNG_SUCCESS(0) is successful.
+ */
+static tng_function_status tng_residue_data_read(tng_trajectory_t tng_data,
+                                                 tng_gen_block_t block,
+                                                 tng_residue_t residue,
+                                                 int *offset)
+{
+    int len;
+
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+
+    memcpy(&residue->id, block->block_contents+*offset,
+        sizeof(residue->id));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &residue->id)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(residue->id);
+
+    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
+            TNG_MAX_STR_LEN);
+    residue->name = malloc(len);
+    strncpy(residue->name,
+            block->block_contents+*offset, len);
+    *offset += len;
+
+    memcpy(&residue->n_atoms, block->block_contents+*offset,
+            sizeof(residue->n_atoms));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &residue->n_atoms)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(residue->n_atoms);
+
+    return(TNG_SUCCESS);
+}
+
+/** Write the residue data of a molecules block.
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param residue is the residue data container.
+ * @param offset is the offset of the block output and is updated when writing.
+ * @return TNG_SUCCESS(0) is successful.
+ */
+static tng_function_status tng_residue_data_write(tng_trajectory_t tng_data,
+                                                  tng_gen_block_t block,
+                                                  tng_residue_t residue,
+                                                  int *offset)
+{
+    int len;
+
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+
+    memcpy(block->block_contents+*offset, &residue->id, sizeof(residue->id));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                    (int64_t *)block->header_contents+*offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(residue->id);
+
+    len = tng_min_i((int)strlen(residue->name) + 1, TNG_MAX_STR_LEN);
+    strncpy(block->block_contents + *offset, residue->name, len);
+    *offset += len;
+
+    memcpy(block->block_contents+*offset, &residue->n_atoms,
+        sizeof(residue->n_atoms));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                    (int64_t *)block->header_contents+*offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(residue->n_atoms);
+
+    return(TNG_SUCCESS);
+}
+
+/** Read the atom data of a molecules block.
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param atom is the atom data container.
+ * @param offset is the offset of the block input and is updated when reading.
+ * @return TNG_SUCCESS(0) is successful.
+ */
+static tng_function_status tng_atom_data_read(tng_trajectory_t tng_data,
+                                              tng_gen_block_t block,
+                                              tng_atom_t atom,
+                                              int *offset)
+{
+    int len;
+
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+
+    memcpy(&atom->id, block->block_contents+*offset,
+        sizeof(atom->id));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                    &atom->id)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(atom->id);
+
+    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
+            TNG_MAX_STR_LEN);
+    atom->name = malloc(len);
+    strncpy(atom->name,
+            block->block_contents+*offset, len);
+    *offset += len;
+
+    len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
+            TNG_MAX_STR_LEN);
+    atom->atom_type = malloc(len);
+    strncpy(atom->atom_type,
+            block->block_contents+*offset, len);
+    *offset += len;
+
+    return(TNG_SUCCESS);
+}
+
+/** Write the atom data of a molecules block.
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param atom is the atom data container.
+ * @param offset is the offset of the block output and is updated when writing.
+ * @return TNG_SUCCESS(0) is successful.
+ */
+static tng_function_status tng_atom_data_write(tng_trajectory_t tng_data,
+                                               tng_gen_block_t block,
+                                               tng_atom_t atom,
+                                               int *offset)
+{
+    int len;
+
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
+
+    memcpy(block->block_contents+*offset, &atom->id,
+            sizeof(atom->id));
+    if(tng_data->output_endianness_swap_func_64)
+    {
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+                                    (int64_t *)block->header_contents+*offset)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    *offset += sizeof(atom->id);
+
+    len = tng_min_i((int)strlen(atom->name) + 1, TNG_MAX_STR_LEN);
+    strncpy(block->block_contents + *offset, atom->name, len);
+    *offset += len;
+
+    len = tng_min_i((int)strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN);
+    strncpy(block->block_contents + *offset, atom->atom_type, len);
+    *offset += len;
+
+    return(TNG_SUCCESS);
+}
+
+static tng_function_status tng_molecules_block_len_calculate
+                (const tng_trajectory_t tng_data,
+                 int64_t *len)
+{
+    int64_t i, j;
+    tng_molecule_t molecule;
+    tng_chain_t chain;
+    tng_residue_t residue;
+    tng_atom_t atom;
+    tng_bond_t bond;
+
+    *len = 0;
+
+    for(i = 0; i < tng_data->n_molecules; i++)
+    {
+        molecule = &tng_data->molecules[i];
+        if(!molecule->name)
+        {
+            molecule->name = malloc(1);
+            if(!molecule->name)
+            {
+                fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                       __FILE__, __LINE__);
+                return(TNG_CRITICAL);
+            }
+            molecule->name[0] = 0;
+        }
+        *len += tng_min_i((int)strlen(molecule->name) + 1, TNG_MAX_STR_LEN);
+
+        chain = molecule->chains;
+        for(j = 0; j < molecule->n_chains; j++)
+        {
+            *len += sizeof(chain->id);
+
+            if(!chain->name)
+            {
+                chain->name = malloc(1);
+                if(!chain->name)
+                {
+                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                           __FILE__, __LINE__);
+                    return(TNG_CRITICAL);
+                }
+                chain->name[0] = 0;
+            }
+            *len += tng_min_i((int)strlen(chain->name) + 1, TNG_MAX_STR_LEN);
+
+            *len += sizeof(chain->n_residues);
+
+            chain++;
+        }
+
+        residue = molecule->residues;
+        for(j = 0; j < molecule->n_residues; j++)
+        {
+            *len += sizeof(residue->id);
+
+            if(!residue->name)
+            {
+                residue->name = malloc(1);
+                if(!residue->name)
+                {
+                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                           __FILE__, __LINE__);
+                    return(TNG_CRITICAL);
+                }
+                residue->name[0] = 0;
+            }
+            *len += tng_min_i((int)strlen(residue->name) + 1, TNG_MAX_STR_LEN);
+
+            *len += sizeof(residue->n_atoms);
+
+            residue++;
+        }
+
+        atom = molecule->atoms;
+        for(j = 0; j < molecule->n_atoms; j++)
+        {
+            *len += sizeof(atom->id);
+            if(!atom->name)
+            {
+                atom->name = malloc(1);
+                if(!atom->name)
+                {
+                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                           __FILE__, __LINE__);
+                    return(TNG_CRITICAL);
+                }
+                atom->name[0] = 0;
+            }
+            *len += tng_min_i((int)strlen(atom->name) + 1, TNG_MAX_STR_LEN);
+
+            if(!atom->atom_type)
+            {
+                atom->atom_type = malloc(1);
+                if(!atom->atom_type)
+                {
+                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
+                           __FILE__, __LINE__);
+                    return(TNG_CRITICAL);
+                }
+                atom->atom_type[0] = 0;
+            }
+            *len += tng_min_i((int)strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN);
+
+            atom++;
+        }
+
+        for(j = 0; j < molecule->n_bonds; j++)
+        {
+            *len += sizeof(bond->from_atom_id) + sizeof(bond->to_atom_id);
+        }
+    }
+    *len += sizeof(tng_data->n_molecules) +
+            (sizeof(molecule->id) +
+            sizeof(molecule->quaternary_str) +
+            sizeof(molecule->n_chains) +
+            sizeof(molecule->n_residues) +
+            sizeof(molecule->n_atoms) +
+            sizeof(molecule->n_bonds)) *
+            tng_data->n_molecules;
+
+    if(!tng_data->var_num_atoms_flag)
+    {
+        *len += tng_data->n_molecules * sizeof(int64_t);
+    }
+
+    return(TNG_SUCCESS);
+}
+
+/** Read a molecules block. Contains chain, residue and atom data
+ * @param tng_data is a trajectory data container.
+ * @param block is a general block container.
+ * @param hash_mode is an option to decide whether to use the md5 hash or not.
+ * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
+ * compared to the md5 hash of the read contents to ensure valid data.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
+ */
+static tng_function_status tng_molecules_block_read
+                (tng_trajectory_t tng_data,
+                 tng_gen_block_t block,
+                 const char hash_mode)
+{
+    int64_t i, j, k, l;
+    int len, offset = 0;
+    tng_molecule_t molecule;
+    tng_chain_t chain;
+    tng_residue_t residue;
+    tng_atom_t atom;
+    tng_bond_t bond;
+    tng_bool same_hash;
+
+    if(tng_input_file_init(tng_data) != TNG_SUCCESS)
+    {
+        return(TNG_CRITICAL);
+    }
+
+    if(block->block_contents)
+    {
+        free(block->block_contents);
+    }
+
+    block->block_contents = malloc(block->block_contents_size);
+    if(!block->block_contents)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+               block->block_contents_size, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    /* Read the whole block into block_contents to be able to write it to disk
+     * even if it cannot be interpreted. */
+    if(fread(block->block_contents, block->block_contents_size, 1,
+             tng_data->input_file) == 0)
+    {
+        fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
+    }
+
+    /* FIXME: Does not check if the size of the contents matches the expected
+     * size or if the contents can be read. */
+
+    if(hash_mode == TNG_USE_HASH)
+    {
+        tng_md5_hash_match_verify(block, &same_hash);
+        if(same_hash != TNG_TRUE)
+        {
+            fprintf(stderr, "TNG library: Molecules block contents corrupt. Hashes do not match. "
+                "%s: %d\n",
+                __FILE__, __LINE__);
+        }
+    }
+
+    if(tng_data->molecules)
+    {
+        for(i=0; i<tng_data->n_molecules; i++)
+        {
+            tng_molecule_destroy(tng_data, &tng_data->molecules[i]);
+        }
+        free(tng_data->molecules);
+        tng_data->molecules = 0;
+        tng_data->n_molecules = 0;
+    }
+
+    memcpy(&tng_data->n_molecules, block->block_contents,
+           sizeof(tng_data->n_molecules));
+    if(tng_data->input_endianness_swap_func_64)
+    {
+        if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                   &tng_data->n_molecules)
+            != TNG_SUCCESS)
+        {
+            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                    __FILE__, __LINE__);
+        }
+    }
+    offset += sizeof(tng_data->n_molecules);
+
+    if(tng_data->molecules)
+    {
+        free(tng_data->molecules);
+    }
+
+    tng_data->n_particles = 0;
+
+    tng_data->molecules = malloc(tng_data->n_molecules *
+                          sizeof(struct tng_molecule));
+    if(!tng_data->molecules)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
+               tng_data->n_molecules * sizeof(struct tng_molecule),
+               __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    if(!tng_data->var_num_atoms_flag)
+    {
+        if(tng_data->molecule_cnt_list)
+        {
+            free(tng_data->molecule_cnt_list);
+        }
+        tng_data->molecule_cnt_list = malloc(sizeof(int64_t) *
+                                      tng_data->n_molecules);
+        if(!tng_data->molecule_cnt_list)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
+                   tng_data->n_molecules * sizeof(struct tng_molecule),
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
+        }
+    }
+
+    /* Read each molecule from file */
+    for(i=0; i < tng_data->n_molecules; i++)
+    {
+        molecule = &tng_data->molecules[i];
+
+        memcpy(&molecule->id, block->block_contents+offset,
+               sizeof(molecule->id));
+        if(tng_data->input_endianness_swap_func_64)
+        {
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                       &molecule->id)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+        offset += sizeof(molecule->id);
+
+/*         fprintf(stderr, "TNG library: Read id: %"PRId64" offset: %d\n", molecule->id, offset);*/
+        len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN);
+        molecule->name = malloc(len);
+        strncpy(molecule->name, block->block_contents+offset, len);
+        offset += len;
+
+        memcpy(&molecule->quaternary_str, block->block_contents+offset,
+               sizeof(molecule->quaternary_str));
+        if(tng_data->input_endianness_swap_func_64)
+        {
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                     &molecule->quaternary_str)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+        offset += sizeof(molecule->quaternary_str);
+
+        if(!tng_data->var_num_atoms_flag)
+        {
+            memcpy(&tng_data->molecule_cnt_list[i],
+                   block->block_contents+offset,
+                   sizeof(int64_t));
+            if(tng_data->input_endianness_swap_func_64)
+            {
+                if(tng_data->input_endianness_swap_func_64(tng_data,
+                                               &tng_data->molecule_cnt_list[i])
+                    != TNG_SUCCESS)
+                {
+                    fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                            __FILE__, __LINE__);
+                }
+            }
+            offset += sizeof(int64_t);
+        }
+
+
+        memcpy(&molecule->n_chains, block->block_contents+offset,
+               sizeof(molecule->n_chains));
+        if(tng_data->input_endianness_swap_func_64)
+        {
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                       &molecule->n_chains)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+        offset += sizeof(molecule->n_chains);
+
+        memcpy(&molecule->n_residues, block->block_contents+offset,
+               sizeof(molecule->n_residues));
+        if(tng_data->input_endianness_swap_func_64)
+        {
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                       &molecule->n_residues)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+        offset += sizeof(molecule->n_residues);
+
+        memcpy(&molecule->n_atoms, block->block_contents+offset,
+               sizeof(molecule->n_atoms));
+        if(tng_data->input_endianness_swap_func_64)
+        {
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                       &molecule->n_atoms)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
+        }
+        offset += sizeof(molecule->n_atoms);
+
+        tng_data->n_particles += molecule->n_atoms *
+                                 tng_data->molecule_cnt_list[i];
+
+        if(molecule->n_chains > 0)
+        {
+            molecule->chains = malloc(molecule->n_chains *
+                                    sizeof(struct tng_chain));
+            if(!molecule->chains)
+            {
+                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
+                    molecule->n_chains * sizeof(struct tng_chain),
+                    __FILE__, __LINE__);
+                return(TNG_CRITICAL);
+            }
+
+            chain = molecule->chains;
+        }
+        else
+        {
+            chain = 0;
+        }
+
+        if(molecule->n_residues > 0)
+        {
+            molecule->residues = malloc(molecule->n_residues *
+                                sizeof(struct tng_residue));
+            if(!molecule->residues)
+            {
+                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
+                    molecule->n_residues * sizeof(struct tng_residue),
+                    __FILE__, __LINE__);
                 if(molecule->chains)
                 {
                     free(molecule->chains);
@@ -2382,7 +3395,7 @@ static tng_function_status tng_molecules_block_read
                                  sizeof(struct tng_atom));
         if(!molecule->atoms)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                    molecule->n_atoms * sizeof(struct tng_atom),
                    __FILE__, __LINE__);
             if(molecule->chains)
@@ -2403,7 +3416,7 @@ static tng_function_status tng_molecules_block_read
         if(molecule->n_chains > 0)
         {
             /* Read the chains of the molecule */
-            for(j=molecule->n_chains; j--;)
+            for(j=0; j<molecule->n_chains; j++)
             {
                 chain->molecule = molecule;
 
@@ -2413,7 +3426,7 @@ static tng_function_status tng_molecules_block_read
                 residue = chain->residues;
 
                 /* Read the residues of the chain */
-                for(k=chain->n_residues; k--;)
+                for(k=0; k<chain->n_residues; k++)
                 {
                     residue->chain = chain;
 
@@ -2421,7 +3434,7 @@ static tng_function_status tng_molecules_block_read
 
                     residue->atoms_offset = atom - molecule->atoms;
                     /* Read the atoms of the residue */
-                    for(l=residue->n_atoms; l--;)
+                    for(l=0; l<residue->n_atoms; l++)
                     {
                         atom->residue = residue;
 
@@ -2438,7 +3451,7 @@ static tng_function_status tng_molecules_block_read
         {
             if(molecule->n_residues > 0)
             {
-                for(k=molecule->n_residues; k--;)
+                for(k=0; k<molecule->n_residues; k++)
                 {
                     residue->chain = 0;
 
@@ -2446,7 +3459,7 @@ static tng_function_status tng_molecules_block_read
 
                     residue->atoms_offset = atom - molecule->atoms;
                     /* Read the atoms of the residue */
-                    for(l=residue->n_atoms; l--;)
+                    for(l=0; l<residue->n_atoms; l++)
                     {
                         atom->residue = residue;
 
@@ -2459,7 +3472,7 @@ static tng_function_status tng_molecules_block_read
             }
             else
             {
-                for(l=molecule->n_atoms; l--;)
+                for(l=0; l<molecule->n_atoms; l++)
                 {
                     atom->residue = 0;
 
@@ -2490,7 +3503,7 @@ static tng_function_status tng_molecules_block_read
                                            sizeof(struct tng_bond));
             if(!molecule->bonds)
             {
-                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                        molecule->n_bonds * sizeof(struct tng_bond),
                        __FILE__, __LINE__);
                 if(molecule->chains)
@@ -2513,7 +3526,7 @@ static tng_function_status tng_molecules_block_read
 
             bond = molecule->bonds;
 
-            for(j=molecule->n_bonds; j--;)
+            for(j=0; j<molecule->n_bonds; j++)
             {
                 memcpy(&bond->from_atom_id, block->block_contents+offset,
                     sizeof(bond->from_atom_id));
@@ -2580,108 +3593,6 @@ static tng_function_status tng_molecules_block_write
         return(TNG_CRITICAL);
     }
 
-    /* First predict the size of the block */
-    for(i = 0; i < tng_data->n_molecules; i++)
-    {
-        molecule = &tng_data->molecules[i];
-        if(!molecule->name)
-        {
-            molecule->name = malloc(1);
-            if(!molecule->name)
-            {
-                fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                       __FILE__, __LINE__);
-                return(TNG_CRITICAL);
-            }
-            molecule->name[0] = 0;
-        }
-        len += tng_min_i((int)strlen(molecule->name) + 1, TNG_MAX_STR_LEN);
-
-        chain = molecule->chains;
-        for(j = molecule->n_chains; j--;)
-        {
-            len += sizeof(chain->id);
-
-            if(!chain->name)
-            {
-                chain->name = malloc(1);
-                if(!chain->name)
-                {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                           __FILE__, __LINE__);
-                    return(TNG_CRITICAL);
-                }
-                chain->name[0] = 0;
-            }
-            len += tng_min_i((int)strlen(chain->name) + 1, TNG_MAX_STR_LEN);
-
-            len += sizeof(chain->n_residues);
-
-            chain++;
-        }
-
-        residue = molecule->residues;
-        for(j = molecule->n_residues; j--;)
-        {
-            len += sizeof(residue->id);
-
-            if(!residue->name)
-            {
-                residue->name = malloc(1);
-                if(!residue->name)
-                {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                           __FILE__, __LINE__);
-                    return(TNG_CRITICAL);
-                }
-                residue->name[0] = 0;
-            }
-            len += tng_min_i((int)strlen(residue->name) + 1, TNG_MAX_STR_LEN);
-
-            len += sizeof(residue->n_atoms);
-
-            residue++;
-        }
-
-        atom = molecule->atoms;
-        for(j = molecule->n_atoms; j--;)
-        {
-            len += sizeof(atom->id);
-            if(!atom->name)
-            {
-                atom->name = malloc(1);
-                if(!atom->name)
-                {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                           __FILE__, __LINE__);
-                    return(TNG_CRITICAL);
-                }
-                atom->name[0] = 0;
-            }
-            len += tng_min_i((int)strlen(atom->name) + 1, TNG_MAX_STR_LEN);
-
-            if(!atom->atom_type)
-            {
-                atom->atom_type = malloc(1);
-                if(!atom->atom_type)
-                {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (1 byte). %s: %d\n",
-                           __FILE__, __LINE__);
-                    return(TNG_CRITICAL);
-                }
-                atom->atom_type[0] = 0;
-            }
-            len += tng_min_i((int)strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN);
-
-            atom++;
-        }
-
-        for(j = molecule->n_bonds; j--;)
-        {
-            len += sizeof(bond->from_atom_id) + sizeof(bond->to_atom_id);
-        }
-    }
-
     tng_block_init(&block);
 
     name_len = (int)strlen("MOLECULES");
@@ -2698,19 +3609,13 @@ static tng_function_status tng_molecules_block_write
     strcpy(block->name, "MOLECULES");
     block->id = TNG_MOLECULES;
 
-    block->block_contents_size = sizeof(tng_data->n_molecules) +
-                                 (sizeof(molecule->id) +
-                                 sizeof(molecule->quaternary_str) +
-                                 sizeof(molecule->n_chains) +
-                                 sizeof(molecule->n_residues) +
-                                 sizeof(molecule->n_atoms) +
-                                 sizeof(molecule->n_bonds)) *
-                                 tng_data->n_molecules +
-                                 len;
-
-    if(!tng_data->var_num_atoms_flag)
+    if(tng_molecules_block_len_calculate(tng_data, &block->block_contents_size) !=
+        TNG_SUCCESS)
     {
-        block->block_contents_size += tng_data->n_molecules * sizeof(int64_t);
+        fprintf(stderr, "TNG library: Cannot calculate length of molecules block. %s: %d\n",
+                __FILE__, __LINE__);
+        tng_block_destroy(&block);
+        return(TNG_CRITICAL);
     }
 
     block->block_contents = malloc(block->block_contents_size);
@@ -2834,17 +3739,17 @@ static tng_function_status tng_molecules_block_write
         if(molecule->n_chains > 0)
         {
             chain = molecule->chains;
-            for(j = molecule->n_chains; j--;)
+            for(j = 0; j < molecule->n_chains; j++)
             {
                 tng_chain_data_write(tng_data, block, chain, &offset);
 
                 residue = chain->residues;
-                for(k = chain->n_residues; k--;)
+                for(k = 0; k < chain->n_residues; k++)
                 {
                     tng_residue_data_write(tng_data, block, residue, &offset);
 
                     atom = molecule->atoms + residue->atoms_offset;
-                    for(l = residue->n_atoms; l--;)
+                    for(l = 0; l < residue->n_atoms; l++)
                     {
                         tng_atom_data_write(tng_data, block, atom, &offset);
 
@@ -2860,12 +3765,12 @@ static tng_function_status tng_molecules_block_write
             if(molecule->n_residues > 0)
             {
                 residue = molecule->residues;
-                for(k = molecule->n_residues; k--;)
+                for(k = 0; k < molecule->n_residues; k++)
                 {
                     tng_residue_data_write(tng_data, block, residue, &offset);
 
                     atom = molecule->atoms + residue->atoms_offset;
-                    for(l = residue->n_atoms; l--;)
+                    for(l = 0; l < residue->n_atoms; l++)
                     {
                         tng_atom_data_write(tng_data, block, atom, &offset);
 
@@ -2877,7 +3782,7 @@ static tng_function_status tng_molecules_block_write
             else
             {
                 atom = molecule->atoms;
-                for(l = molecule->n_atoms; l--;)
+                for(l = 0; l < molecule->n_atoms; l++)
                 {
                     tng_atom_data_write(tng_data, block, atom, &offset);
 
@@ -2901,7 +3806,7 @@ static tng_function_status tng_molecules_block_write
         offset += sizeof(molecule->n_bonds);
 
         bond = molecule->bonds;
-        for(j = molecule->n_bonds; j--;)
+        for(j = 0; j < molecule->n_bonds; j++)
         {
             memcpy(block->block_contents+offset, &bond->from_atom_id,
                    sizeof(bond->from_atom_id));
@@ -2957,6 +3862,20 @@ static tng_function_status tng_molecules_block_write
     return(TNG_SUCCESS);
 }
 
+static tng_function_status tng_frame_set_block_len_calculate
+                (const tng_trajectory_t tng_data,
+                 int64_t *len)
+{
+    *len = sizeof(int64_t) * 8;
+    *len += sizeof(double) * 2;
+
+    if(tng_data->var_num_atoms_flag)
+    {
+        *len += sizeof(int64_t) * tng_data->n_molecules;
+    }
+    return(TNG_SUCCESS);
+}
+
 /** Read a frame set block. Update tng_data->current_trajectory_frame_set
  * @param tng_data is a trajectory data container.
  * @param block is a general block container.
@@ -2971,9 +3890,8 @@ static tng_function_status tng_frame_set_block_read
                  tng_gen_block_t block,
                  const char hash_mode)
 {
-    long file_pos;
     int offset = 0;
-    int64_t i, prev_n_particles;
+    int64_t file_pos, i, prev_n_particles;
     tng_bool same_hash;
     tng_trajectory_frame_set_t frame_set =
     &tng_data->current_trajectory_frame_set;
@@ -3008,15 +3926,15 @@ static tng_function_status tng_frame_set_block_read
     /* FIXME: Does not check if the size of the contents matches the expected
      * size or if the contents can be read. */
 
-    file_pos = (int64_t)ftell(tng_data->input_file) -
-               (long)(block->block_contents_size + block->header_contents_size);
+    file_pos = (int64_t)ftello(tng_data->input_file) -
+               (block->block_contents_size + block->header_contents_size);
 
     if(hash_mode == TNG_USE_HASH)
     {
         tng_md5_hash_match_verify(block, &same_hash);
         if(same_hash != TNG_TRUE)
         {
-            fprintf(stderr, "TNG library: Frame set block contents corrupt. File pos %ld Hashes do not match. "
+            fprintf(stderr, "TNG library: Frame set block contents corrupt. File pos %"PRId64" Hashes do not match. "
                 "%s: %d\n",
                 file_pos, __FILE__, __LINE__);
     /*         return(TNG_FAILURE); */
@@ -3079,7 +3997,7 @@ static tng_function_status tng_frame_set_block_read
 
                 if(!frame_set->molecule_cnt_list)
                 {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                            sizeof(int64_t) * tng_data->n_molecules,
                            __FILE__, __LINE__);
                     return(TNG_CRITICAL);
@@ -3237,7 +4155,14 @@ static tng_function_status tng_frame_set_block_read
         tng_data->time_per_frame = -1;
     }
 
-    frame_set->n_written_frames = frame_set->n_frames;
+    /* If the output file and the input files are the same the number of
+     * frames in the file are the same number as has just been read.
+     * This is updated here to later on see if there have been new frames
+     * added and thereby the frame set needs to be rewritten. */
+    if(tng_data->output_file == tng_data->input_file)
+    {
+        frame_set->n_written_frames = frame_set->n_frames;
+    }
 
     return(TNG_SUCCESS);
 }
@@ -3274,7 +4199,7 @@ static tng_function_status tng_frame_set_block_write
         temp_name = realloc(block->name, name_len + 1);
         if(!temp_name)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%u bytes). %s: %d\n",
                    name_len+1, __FILE__, __LINE__);
             free(block->name);
             block->name = 0;
@@ -3285,12 +4210,12 @@ static tng_function_status tng_frame_set_block_write
     strcpy(block->name, "TRAJECTORY FRAME SET");
     block->id = TNG_TRAJECTORY_FRAME_SET;
 
-    block->block_contents_size = sizeof(int64_t) * 8;
-    block->block_contents_size += sizeof(double) * 2;
-
-    if(tng_data->var_num_atoms_flag)
+    if(tng_frame_set_block_len_calculate(tng_data, &block->block_contents_size) !=
+        TNG_SUCCESS)
     {
-        block->block_contents_size += sizeof(int64_t) * tng_data->n_molecules;
+        fprintf(stderr, "TNG library: Cannot calculate length of frame set block. %s: %d\n",
+                __FILE__, __LINE__);
+        return(TNG_CRITICAL);
     }
 
     if(block->block_contents)
@@ -3489,6 +4414,16 @@ static tng_function_status tng_frame_set_block_write
     return(TNG_SUCCESS);
 }
 
+static tng_function_status tng_trajectory_mapping_block_len_calculate
+                (const tng_trajectory_t tng_data,
+                 const int64_t n_particles,
+                 int64_t *len)
+{
+    (void)tng_data;
+    *len = sizeof(int64_t) * (2 + n_particles);
+
+    return(TNG_SUCCESS);
+}
 
 /** Read an atom mappings block (translating between real atom indexes and how
  *  the atom info is written in this frame set).
@@ -3603,7 +4538,7 @@ static tng_function_status tng_trajectory_mapping_block_read
                                             sizeof(int64_t));
     if(!mapping->real_particle_numbers)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                 mapping->n_particles * sizeof(int64_t), __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -3679,7 +4614,7 @@ static tng_function_status tng_trajectory_mapping_block_write
         temp_name = realloc(block->name, name_len + 1);
         if(!temp_name)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%u bytes). %s: %d\n",
                    name_len+1, __FILE__, __LINE__);
             free(block->name);
             block->name = 0;
@@ -3690,7 +4625,15 @@ static tng_function_status tng_trajectory_mapping_block_write
     strcpy(block->name, "PARTICLE MAPPING");
     block->id = TNG_PARTICLE_MAPPING;
 
-    block->block_contents_size = sizeof(int64_t) * (2 + mapping->n_particles);
+    if(tng_trajectory_mapping_block_len_calculate(tng_data,
+                                                  mapping->n_particles,
+                                                  &block->block_contents_size) !=
+        TNG_SUCCESS)
+    {
+        fprintf(stderr, "TNG library: Cannot calculate length of atom mapping block. %s: %d\n",
+                __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
 
     if(block->block_contents)
     {
@@ -3796,7 +4739,7 @@ static tng_function_status tng_particle_data_block_create
                     frame_set->n_particle_data_blocks);
         if(!data)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                 sizeof(struct tng_particle_data) *
                 frame_set->n_particle_data_blocks,
                 __FILE__, __LINE__);
@@ -3814,7 +4757,7 @@ static tng_function_status tng_particle_data_block_create
                         tng_data->n_particle_data_blocks);
         if(!data)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                     sizeof(struct tng_particle_data) *
                     tng_data->n_particle_data_blocks,
                     __FILE__, __LINE__);
@@ -3838,9 +4781,8 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
     int nalgo;
     int new_len;
     int *alt_algo = 0;
-    char *dest, *temp;
-    int64_t algo_find_n_frames;
-    unsigned long offset;
+    char *dest, *temp, *temp_data_contents;
+    int64_t algo_find_n_frames, compressed_len, offset;
     float f_precision;
     double d_precision;
 
@@ -3867,6 +4809,17 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
     f_precision = 1/(float)tng_data->compression_precision;
     d_precision = 1/tng_data->compression_precision;
 
+    compressed_len = block->block_contents_size - (int64_t)((char *)start_pos - (char *)block->block_contents);
+    temp_data_contents = malloc(compressed_len);
+    if(!temp_data_contents)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                compressed_len, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    memcpy(temp_data_contents, (char *)start_pos, compressed_len);
+
     if(block->id == TNG_TRAJ_POSITIONS)
     {
         /* If there is only one frame in this frame set and there might be more
@@ -3878,7 +4831,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
             alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_pos);
             if(type == TNG_FLOAT_DATA)
             {
-                dest = tng_compress_pos_float_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_pos_float_find_algo((float *)temp_data_contents, (int)n_particles,
                                                         (int)n_frames,
                                                         f_precision,
                                                         0, alt_algo,
@@ -3887,7 +4840,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
             }
             else
             {
-                dest = tng_compress_pos_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_pos_find_algo((double *)temp_data_contents, (int)n_particles,
                                            (int)n_frames,
                                            d_precision,
                                            0, alt_algo,
@@ -3910,7 +4863,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
                                            sizeof *tng_data->compress_algo_pos);
             if(type == TNG_FLOAT_DATA)
             {
-                dest = tng_compress_pos_float_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_pos_float_find_algo((float *)temp_data_contents, (int)n_particles,
                                                         (int)algo_find_n_frames,
                                                         f_precision,
                                                         0, tng_data->
@@ -3919,7 +4872,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
 
                 if(algo_find_n_frames < n_frames)
                 {
-                    dest = tng_compress_pos_float(start_pos, (int)n_particles,
+                    dest = tng_compress_pos_float((float *)temp_data_contents, (int)n_particles,
                                                   (int)n_frames,
                                                   f_precision,
                                                   0, tng_data->compress_algo_pos,
@@ -3928,7 +4881,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
             }
             else
             {
-                dest = tng_compress_pos_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_pos_find_algo((double *)temp_data_contents, (int)n_particles,
                                            (int)algo_find_n_frames,
                                            d_precision,
                                            0, tng_data->
@@ -3937,7 +4890,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
 
                 if(algo_find_n_frames < n_frames)
                 {
-                    dest = tng_compress_pos(start_pos, (int)n_particles,
+                    dest = tng_compress_pos((double *)temp_data_contents, (int)n_particles,
                                             (int)n_frames,
                                             d_precision, 0,
                                             tng_data->compress_algo_pos,
@@ -3949,14 +4902,14 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
         {
             if(type == TNG_FLOAT_DATA)
             {
-                dest = tng_compress_pos_float(start_pos, (int)n_particles,
+                dest = tng_compress_pos_float((float *)temp_data_contents, (int)n_particles,
                                               (int)n_frames,
                                               f_precision, 0,
                                               tng_data->compress_algo_pos, &new_len);
             }
             else
             {
-                dest = tng_compress_pos(start_pos, (int)n_particles,
+                dest = tng_compress_pos((double *)temp_data_contents, (int)n_particles,
                                         (int)n_frames,
                                         d_precision, 0,
                                         tng_data->compress_algo_pos,
@@ -3972,10 +4925,10 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
         if(n_frames == 1 && tng_data->frame_set_n_frames > 1)
         {
             nalgo = tng_compress_nalgo();
-            alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_pos);
+            alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_vel);
             if(type == TNG_FLOAT_DATA)
             {
-                dest = tng_compress_vel_float_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_vel_float_find_algo((float *)temp_data_contents, (int)n_particles,
                                                         (int)n_frames,
                                                         f_precision,
                                                         0, alt_algo,
@@ -3984,7 +4937,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
             }
             else
             {
-                dest = tng_compress_vel_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_vel_find_algo((double *)temp_data_contents, (int)n_particles,
                                                   (int)n_frames,
                                                   d_precision,
                                                   0, alt_algo,
@@ -4008,7 +4961,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
 
             if(type == TNG_FLOAT_DATA)
             {
-                dest = tng_compress_vel_float_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_vel_float_find_algo((float *)temp_data_contents, (int)n_particles,
                                                         (int)algo_find_n_frames,
                                                         f_precision,
                                                         0, tng_data->
@@ -4016,7 +4969,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
                                                         &new_len);
                 if(algo_find_n_frames < n_frames)
                 {
-                    dest = tng_compress_vel_float(start_pos, (int)n_particles,
+                    dest = tng_compress_vel_float((float *)temp_data_contents, (int)n_particles,
                                                   (int)n_frames,
                                                   f_precision,
                                                   0, tng_data->compress_algo_vel,
@@ -4025,7 +4978,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
             }
             else
             {
-                dest = tng_compress_vel_find_algo(start_pos, (int)n_particles,
+                dest = tng_compress_vel_find_algo((double *)temp_data_contents, (int)n_particles,
                                                   (int)algo_find_n_frames,
                                                   d_precision,
                                                   0, tng_data->
@@ -4033,7 +4986,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
                                                   &new_len);
                 if(algo_find_n_frames < n_frames)
                 {
-                    dest = tng_compress_vel(start_pos, (int)n_particles,
+                    dest = tng_compress_vel((double *)temp_data_contents, (int)n_particles,
                                             (int)n_frames,
                                             d_precision,
                                             0, tng_data->compress_algo_vel,
@@ -4045,7 +4998,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
         {
             if(type == TNG_FLOAT_DATA)
             {
-                dest = tng_compress_vel_float(start_pos, (int)n_particles,
+                dest = tng_compress_vel_float((float *)temp_data_contents, (int)n_particles,
                                               (int)n_frames,
                                               f_precision,
                                               0, tng_data->
@@ -4054,7 +5007,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
             }
             else
             {
-                dest = tng_compress_vel(start_pos, (int)n_particles,
+                dest = tng_compress_vel((double *)temp_data_contents, (int)n_particles,
                                         (int)n_frames,
                                         d_precision,
                                         0, tng_data->
@@ -4066,6 +5019,7 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
     else
     {
         fprintf(stderr, "TNG library: Can only compress positions and velocities using TNG-MF1 algorithms.\n");
+        free(temp_data_contents);
         return(TNG_FAILURE);
     }
 
@@ -4078,6 +5032,8 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data,
 
     block->block_contents_size = new_len + offset;
 
+    free(temp_data_contents);
+
     temp = realloc(block->block_contents, block->block_contents_size);
     if(!temp)
     {
@@ -4106,12 +5062,13 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data,
                                           tng_gen_block_t block,
                                           const char type,
                                           void *start_pos,
-                                          const unsigned long uncompressed_len)
+                                          const int64_t uncompressed_len)
 {
-    char *temp;
+    char *temp, *temp_data_contents;
+    int64_t compressed_len;
     double *d_dest = 0;
     float *f_dest = 0;
-    unsigned long offset;
+    int64_t offset;
     int result;
     (void)tng_data;
 
@@ -4130,32 +5087,46 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data,
         return(TNG_FAILURE);
     }
 
+    compressed_len = block->block_contents_size - (int64_t)((char *)start_pos - (char *)block->block_contents);
+    temp_data_contents = malloc(compressed_len);
+    if(!temp_data_contents)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                uncompressed_len, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
+
+    memcpy(temp_data_contents, (char *)start_pos, compressed_len);
+
     if(type == TNG_FLOAT_DATA)
     {
         f_dest = malloc(uncompressed_len);
         if(!f_dest)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
                 uncompressed_len, __FILE__, __LINE__);
+            free(temp_data_contents);
             return(TNG_CRITICAL);
         }
-        result = tng_compress_uncompress_float(start_pos, f_dest);
+        result = tng_compress_uncompress_float(temp_data_contents, f_dest);
     }
     else
     {
         d_dest = malloc(uncompressed_len);
         if(!d_dest)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
                 uncompressed_len, __FILE__, __LINE__);
+            free(temp_data_contents);
             return(TNG_CRITICAL);
         }
-        result = tng_compress_uncompress(start_pos, d_dest);
+        result = tng_compress_uncompress(temp_data_contents, d_dest);
     }
 
     if(result == 1)
     {
         fprintf(stderr, "TNG library: Cannot uncompress TNG compressed block.\n");
+        free(temp_data_contents);
         return(TNG_FAILURE);
     }
 
@@ -4178,6 +5149,7 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data,
         }
         fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
                block->block_contents_size, __FILE__, __LINE__);
+        free(temp_data_contents);
         return(TNG_CRITICAL);
     }
 
@@ -4192,6 +5164,7 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data,
 
     block->block_contents = temp;
 
+    free(temp_data_contents);
     if(d_dest)
     {
         free(d_dest);
@@ -4217,7 +5190,7 @@ static tng_function_status tng_gzip_compress(tng_trajectory_t tng_data,
     dest = malloc(max_len);
     if(!dest)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%ld bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
                max_len, __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -4360,11 +5333,11 @@ static tng_function_status tng_allocate_particle_data_mem
 
     if(data->strings && data->datatype == TNG_CHAR_DATA)
     {
-        for(i = data->n_frames; i--;)
+        for(i = 0; i < data->n_frames; i++)
         {
-            for(j = n_particles; j--;)
+            for(j = 0; j < n_particles; j++)
             {
-                for(k = data->n_values_per_frame; k--;)
+                for(k = 0; k < data->n_values_per_frame; k++)
                 {
                     if(data->strings[i][j][k])
                     {
@@ -4386,29 +5359,29 @@ static tng_function_status tng_allocate_particle_data_mem
     if(data->datatype == TNG_CHAR_DATA)
     {
         data->strings = malloc(sizeof(char ***) * frame_alloc);
-        for(i = frame_alloc; i-- ;)
+        for(i = 0; i < frame_alloc; i++)
         {
             data->strings[i] = malloc(sizeof(char **) *
                                     n_particles);
             if(!data->strings[i])
             {
-                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                     sizeof(union data_values *) * n_particles,
                     __FILE__, __LINE__);
                 return(TNG_CRITICAL);
             }
-            for(j = n_particles; j--;)
+            for(j = 0; j < n_particles; j++)
             {
                 data->strings[i][j] = malloc(sizeof(char *) *
                                             n_values_per_frame);
                 if(!data->strings[i][j])
                 {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                         sizeof(union data_values) * n_values_per_frame,
                         __FILE__, __LINE__);
                     return(TNG_CRITICAL);
                 }
-                for(k = n_values_per_frame; k--;)
+                for(k = 0; k < n_values_per_frame; k++)
                 {
                     data->strings[i][j][k] = 0;
                 }
@@ -4471,7 +5444,7 @@ static tng_function_status tng_particle_data_find
     block_index = -1;
     if(block_type_flag == TNG_TRAJECTORY_BLOCK)
     {
-        for(i = frame_set->n_particle_data_blocks; i-- ;)
+        for(i = 0; i < frame_set->n_particle_data_blocks; i++)
         {
             *data = &frame_set->tr_particle_data[i];
             if((*data)->block_id == id)
@@ -4483,7 +5456,7 @@ static tng_function_status tng_particle_data_find
     }
     else
     {
-        for(i = tng_data->n_particle_data_blocks; i-- ;)
+        for(i = 0; i < tng_data->n_particle_data_blocks; i++)
         {
             *data = &tng_data->non_tr_particle_data[i];
             if((*data)->block_id == id)
@@ -4523,7 +5496,7 @@ static tng_function_status tng_data_find
     block_index = -1;
     if(block_type_flag == TNG_TRAJECTORY_BLOCK)
     {
-        for(i = frame_set->n_data_blocks; i-- ;)
+        for(i = 0; i < frame_set->n_data_blocks; i++)
         {
             *data = &frame_set->tr_data[i];
             if((*data)->block_id == id)
@@ -4534,7 +5507,7 @@ static tng_function_status tng_data_find
         }
         if(block_index == -1)
         {
-            for(i = tng_data->n_data_blocks; i-- ;)
+            for(i = 0; i < tng_data->n_data_blocks; i++)
             {
                 *data = &tng_data->non_tr_data[i];
                 if((*data)->block_id == id)
@@ -4547,7 +5520,7 @@ static tng_function_status tng_data_find
     }
     else
     {
-        for(i = tng_data->n_data_blocks; i-- ;)
+        for(i = 0; i < tng_data->n_data_blocks; i++)
         {
             *data = &tng_data->non_tr_data[i];
             if((*data)->block_id == id)
@@ -4564,6 +5537,108 @@ static tng_function_status tng_data_find
     return(TNG_SUCCESS);
 }
 
+static tng_function_status tng_data_block_len_calculate
+                (const tng_trajectory_t tng_data,
+                 const tng_particle_data_t data,
+                 const tng_bool is_particle_data,
+                 const int64_t n_frames,
+                 const int64_t frame_step,
+                 const int64_t stride_length,
+                 const int64_t num_first_particle,
+                 const int64_t n_particles,
+                 const char dependency,
+                 int64_t *data_start_pos,
+                 int64_t *len)
+{
+    int size;
+    int64_t i, j, k;
+    char ***first_dim_values, **second_dim_values;
+    (void)tng_data;
+
+    if(data == 0)
+    {
+        return(TNG_SUCCESS);
+    }
+
+    switch(data->datatype)
+    {
+    case TNG_CHAR_DATA:
+        size = 1;
+        break;
+    case TNG_INT_DATA:
+        size = sizeof(int64_t);
+        break;
+    case TNG_FLOAT_DATA:
+        size = sizeof(float);
+        break;
+    case TNG_DOUBLE_DATA:
+    default:
+        size = sizeof(double);
+    }
+
+    *len = sizeof(char) * 2 + sizeof(data->n_values_per_frame) +
+           sizeof(data->codec_id);
+    if(is_particle_data)
+    {
+        *len += sizeof(num_first_particle) + sizeof(n_particles);
+    }
+
+    if(stride_length > 1)
+    {
+        *len += sizeof(data->first_frame_with_data) +
+                sizeof(data->stride_length);
+    }
+
+    if(data->codec_id != TNG_UNCOMPRESSED)
+    {
+        *len += sizeof(data->compression_multiplier);
+    }
+
+    if(dependency & TNG_FRAME_DEPENDENT)
+    {
+        *len += sizeof(char);
+    }
+
+    *data_start_pos = *len;
+
+    if(data->datatype == TNG_CHAR_DATA)
+    {
+        if(is_particle_data)
+        {
+            for(i = 0; i < n_frames; i++)
+            {
+                first_dim_values = data->strings[i];
+                for(j = num_first_particle; j < num_first_particle + n_particles;
+                    j++)
+                {
+                    second_dim_values = first_dim_values[j];
+                    for(k = 0; k < data->n_values_per_frame; k++)
+                    {
+                        *len += strlen(second_dim_values[k]) + 1;
+                    }
+                }
+            }
+        }
+        else
+        {
+            for(i = 0; i < n_frames; i++)
+            {
+                second_dim_values = ((tng_non_particle_data_t)data)->strings[i];
+                for(j = 0; j < data->n_values_per_frame; j++)
+                {
+                    *len += strlen(second_dim_values[j]) + 1;
+                }
+            }
+        }
+    }
+    else
+    {
+        *len += size * frame_step * n_particles * data->n_values_per_frame;
+    }
+
+    return(TNG_SUCCESS);
+}
+
 /** Read the values of a particle data block
  * @param tng_data is a trajectory data container.
  * @param block is the block to store the data (should already contain
@@ -4607,7 +5682,7 @@ static tng_function_status tng_particle_data_read
 {
     int64_t i, j, k, tot_n_particles, n_frames_div;
     int size, len;
-    unsigned long data_size;
+    int64_t data_size;
     char ***first_dim_values, **second_dim_values;
     tng_particle_data_t data;
     tng_trajectory_frame_set_t frame_set =
@@ -4616,6 +5691,16 @@ static tng_function_status tng_particle_data_read
 
     TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
 
+    /* This must be caught early to avoid creating a data block if not necessary. */
+#ifndef USE_ZLIB
+    if(codec_id == TNG_GZIP_COMPRESSION)
+    {
+        fprintf(stderr, "TNG library: Cannot uncompress data block. %s: %d\n", __FILE__,
+                __LINE__);
+        return(TNG_FAILURE);
+    }
+#endif
+
     switch(datatype)
     {
     case TNG_CHAR_DATA:
@@ -4918,7 +6003,7 @@ static tng_function_status tng_particle_data_block_write
         temp_name = realloc(block->name, len);
         if(!temp_name)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lud bytes). %s: %d\n", len,
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", len,
                    __FILE__, __LINE__);
             free(block->name);
             block->name = 0;
@@ -4978,23 +6063,6 @@ static tng_function_status tng_particle_data_block_write
         }
     }
 
-    block->block_contents_size = sizeof(char) * 2 +
-                                 sizeof(data->n_values_per_frame) +
-                                 sizeof(data->codec_id) +
-                                 sizeof(num_first_particle) +
-                                 sizeof(n_particles);
-
-    if(stride_length > 1)
-    {
-        block->block_contents_size += sizeof(data->first_frame_with_data) +
-                                      sizeof(data->stride_length);
-    }
-
-    if(data->codec_id != TNG_UNCOMPRESSED)
-    {
-        block->block_contents_size += sizeof(data->compression_multiplier);
-    }
-
     if(block_type_flag == TNG_TRAJECTORY_BLOCK && data->n_frames > 0)
     {
         dependency = TNG_FRAME_DEPENDENT + TNG_PARTICLE_DEPENDENT;
@@ -5003,34 +6071,15 @@ static tng_function_status tng_particle_data_block_write
     {
         dependency = TNG_PARTICLE_DEPENDENT;
     }
-    if(dependency & TNG_FRAME_DEPENDENT)
-    {
-        block->block_contents_size += sizeof(char);
-    }
 
-    data_start_pos = block->block_contents_size;
-
-    if(data->datatype == TNG_CHAR_DATA)
-    {
-        for(i = n_frames; i--;)
-        {
-            first_dim_values = data->strings[i];
-            for(j = num_first_particle; j < num_first_particle + n_particles;
-                j++)
-            {
-                second_dim_values = first_dim_values[j];
-                for(k = data->n_values_per_frame; k--;)
-                {
-                    block->block_contents_size +=
-                    strlen(second_dim_values[k]) + 1;
-                }
-            }
-        }
-    }
-    else
+    if(tng_data_block_len_calculate(tng_data, data, TNG_TRUE, n_frames,
+                                    frame_step, stride_length, num_first_particle,
+                                    n_particles, dependency, &data_start_pos,
+                                    &block->block_contents_size) != TNG_SUCCESS)
     {
-        block->block_contents_size += size * frame_step *
-                                      n_particles * data->n_values_per_frame;
+        fprintf(stderr, "TNG library: Cannot calculate length of particle data block. %s: %d\n",
+                __FILE__, __LINE__);
+        return(TNG_CRITICAL);
     }
 
     if(block->block_contents)
@@ -5408,7 +6457,7 @@ static tng_function_status tng_data_block_create
                        frame_set->n_data_blocks);
         if(!data)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                 sizeof(struct tng_non_particle_data) * frame_set->n_data_blocks,
                 __FILE__, __LINE__);
             free(frame_set->tr_data);
@@ -5424,7 +6473,7 @@ static tng_function_status tng_data_block_create
                         tng_data->n_data_blocks);
         if(!data)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                 sizeof(struct tng_non_particle_data) * tng_data->n_data_blocks,
                 __FILE__, __LINE__);
             free(tng_data->non_tr_data);
@@ -5466,9 +6515,9 @@ static tng_function_status tng_allocate_data_mem
 
     if(data->strings && data->datatype == TNG_CHAR_DATA)
     {
-        for(i = data->n_frames; i--;)
+        for(i = 0; i < data->n_frames; i++)
         {
-            for(j = data->n_values_per_frame; j--;)
+            for(j = 0; j < data->n_values_per_frame; j++)
             {
                 if(data->strings[i][j])
                 {
@@ -5490,7 +6539,7 @@ static tng_function_status tng_allocate_data_mem
     if(data->datatype == TNG_CHAR_DATA)
     {
         data->strings = malloc(sizeof(char **) * frame_alloc);
-        for(i = frame_alloc; i-- ;)
+        for(i = 0; i < frame_alloc; i++)
         {
             data->strings[i] = malloc(sizeof(char *) * n_values_per_frame);
             if(!data->strings[i])
@@ -5500,7 +6549,7 @@ static tng_function_status tng_allocate_data_mem
                        __FILE__, __LINE__);
                 return(TNG_CRITICAL);
             }
-            for(j = n_values_per_frame; j--;)
+            for(j = 0; j < n_values_per_frame; j++)
             {
                 data->strings[i][j] = 0;
             }
@@ -5527,306 +6576,76 @@ static tng_function_status tng_allocate_data_mem
         if(!values)
         {
             fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-                   size * frame_alloc *
-                   n_values_per_frame,
-                   __FILE__, __LINE__);
-            free(data->values);
-            data->values = 0;
-            return(TNG_CRITICAL);
-        }
-        data->values = values;
-    }
-
-    return(TNG_SUCCESS);
-}
-
-/** Read the values of a non-particle data block
- * @param tng_data is a trajectory data container.
- * @param block is the block to store the data (should already contain
- * the block headers and the block contents).
- * @param offset is the reading offset to point at the place where the actual
- * values are stored, starting from the beginning of the block_contents. The
- * offset is changed during the reading.
- * @param datatype is the type of data of the data block (char, int, float or
- * double).
- * @param first_frame_with_data is the frame number of the first frame with data
- * in this data block.
- * @param stride_length is the number of frames between each data entry.
- * @param n_frames is the number of frames in this data block.
- * @param n_values is the number of values per frame stored in this data block.
- * @param codec_id is the ID of the codec to compress the data.
- * @param multiplier is the multiplication factor applied to each data value
- * before compression. This factor is applied since some compression algorithms
- * work only on integers.
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
- */
-static tng_function_status tng_data_read(tng_trajectory_t tng_data,
-                                         tng_gen_block_t block,
-                                         int *offset,
-                                         const char datatype,
-                                         const int64_t first_frame_with_data,
-                                         const int64_t stride_length,
-                                         int64_t n_frames,
-                                         const int64_t n_values,
-                                         const int64_t codec_id,
-                                         const double multiplier)
-{
-    int64_t i, j, n_frames_div;
-    int size, len;
-#ifdef USE_ZLIB
-    unsigned long data_size;
-#endif
-    tng_non_particle_data_t data;
-    tng_trajectory_frame_set_t frame_set =
-    &tng_data->current_trajectory_frame_set;
-    char block_type_flag;
-
-    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
-
-/*     fprintf(stderr, "TNG library: %s\n", block->name);*/
-
-    switch(datatype)
-    {
-    case TNG_CHAR_DATA:
-        size = 1;
-        break;
-    case TNG_INT_DATA:
-        size = sizeof(int64_t);
-        break;
-    case TNG_FLOAT_DATA:
-        size = sizeof(float);
-        break;
-    case TNG_DOUBLE_DATA:
-    default:
-        size = sizeof(double);
-    }
-
-    /* If the block does not exist, create it */
-    if(tng_data_find(tng_data, block->id, &data) != TNG_SUCCESS)
-    {
-        if(tng_data->current_trajectory_frame_set_input_file_pos > 0)
-        {
-            block_type_flag = TNG_TRAJECTORY_BLOCK;
-        }
-        else
-        {
-            block_type_flag = TNG_NON_TRAJECTORY_BLOCK;
-        }
-
-        if(tng_data_block_create(tng_data, block_type_flag) !=
-            TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot create particle data block. %s: %d\n",
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
-        }
-        if(block_type_flag == TNG_TRAJECTORY_BLOCK)
-        {
-            data = &frame_set->tr_data[frame_set->n_data_blocks - 1];
-        }
-        else
-        {
-            data = &tng_data->non_tr_data[tng_data->n_data_blocks - 1];
-        }
-        data->block_id = block->id;
-
-        data->block_name = malloc(strlen(block->name) + 1);
-        if(!data->block_name)
-        {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
-                   (int)strlen(block->name)+1, __FILE__, __LINE__);
-            return(TNG_CRITICAL);
-        }
-        strcpy(data->block_name, block->name);
-
-        data->datatype = datatype;
-
-        data->values = 0;
-        /* FIXME: Memory leak from strings. */
-        data->strings = 0;
-        data->n_frames = 0;
-        data->codec_id = codec_id;
-        data->compression_multiplier = multiplier;
-        data->last_retrieved_frame = -1;
-    }
-
-    n_frames_div = (n_frames % stride_length) ? n_frames / stride_length + 1 : n_frames / stride_length;
-
-    if(codec_id != TNG_UNCOMPRESSED)
-    {
-        switch(codec_id)
-        {
-#ifdef USE_ZLIB
-        case TNG_GZIP_COMPRESSION:
-            data_size = n_frames_div * size * n_values;
-    /*         fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
-            if(tng_gzip_uncompress(tng_data, block,
-                                   block->block_contents + *offset,
-                                   data_size) != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__,
-                    __LINE__);
-                return(TNG_CRITICAL);
-            }
-    /*         fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
-            break;
-#endif
-        }
-    }
-
-    /* Allocate memory */
-    if(!data->values || data->n_frames != n_frames ||
-       data->n_values_per_frame != n_values)
-    {
-        if(tng_allocate_data_mem(tng_data, data, n_frames, stride_length,
-                                 n_values) !=
-           TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot allocate memory for data. %s: %d\n",
-                   __FILE__, __LINE__);
-            return(TNG_CRITICAL);
-        }
-    }
-
-    data->first_frame_with_data = first_frame_with_data;
-
-    if(datatype == TNG_CHAR_DATA)
-    {
-        for(i = 0; i < n_frames_div; i++)
-        {
-            for(j = 0; j < n_values; j++)
-            {
-                len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
-                              TNG_MAX_STR_LEN);
-                if(data->strings[i][j])
-                {
-                    free(data->strings[i][j]);
-                }
-                data->strings[i][j] = malloc(len);
-                if(!data->strings[i][j])
-                {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
-                           len, __FILE__, __LINE__);
-                    return(TNG_CRITICAL);
-                }
-                strncpy(data->strings[i][j], block->block_contents+*offset,
-                        len);
-                *offset += len;
-            }
-        }
-    }
-    else
-    {
-        memcpy(data->values, block->block_contents + *offset,
-               block->block_contents_size - *offset);
-        switch(datatype)
-        {
-        case TNG_FLOAT_DATA:
-            if(tng_data->input_endianness_swap_func_32)
-            {
-                for(i = 0; i < (block->block_contents_size - *offset); i+=size)
-                {
-                    if(tng_data->input_endianness_swap_func_32(tng_data,
-                        (int32_t *)((char *)data->values + i))
-                        != TNG_SUCCESS)
-                    {
-                        fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                                __FILE__, __LINE__);
-                    }
-                }
-            }
-            break;
-        case TNG_INT_DATA:
-        case TNG_DOUBLE_DATA:
-            if(tng_data->input_endianness_swap_func_64)
-            {
-                for(i = 0; i < (block->block_contents_size - *offset); i+=size)
-                {
-                    if(tng_data->input_endianness_swap_func_64(tng_data,
-                        (int64_t *)((char *)data->values + i))
-                        != TNG_SUCCESS)
-                    {
-                        fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                                __FILE__, __LINE__);
-                    }
-                }
-            }
-            break;
-        case TNG_CHAR_DATA:
-            break;
+                   size * frame_alloc *
+                   n_values_per_frame,
+                   __FILE__, __LINE__);
+            free(data->values);
+            data->values = 0;
+            return(TNG_CRITICAL);
         }
+        data->values = values;
     }
+
     return(TNG_SUCCESS);
 }
 
-/** Write a non-particle data block
+/** Read the values of a non-particle data block
  * @param tng_data is a trajectory data container.
  * @param block is the block to store the data (should already contain
  * the block headers and the block contents).
- * @param block_index is the index number of the data block in the frame set.
- * @param hash_mode is an option to decide whether to use the md5 hash or not.
- * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
+ * @param offset is the reading offset to point at the place where the actual
+ * values are stored, starting from the beginning of the block_contents. The
+ * offset is changed during the reading.
+ * @param datatype is the type of data of the data block (char, int, float or
+ * double).
+ * @param first_frame_with_data is the frame number of the first frame with data
+ * in this data block.
+ * @param stride_length is the number of frames between each data entry.
+ * @param n_frames is the number of frames in this data block.
+ * @param n_values is the number of values per frame stored in this data block.
+ * @param codec_id is the ID of the codec to compress the data.
+ * @param multiplier is the multiplication factor applied to each data value
+ * before compression. This factor is applied since some compression algorithms
+ * work only on integers.
  * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
  * error has occured.
  */
-static tng_function_status tng_data_block_write(tng_trajectory_t tng_data,
-                                                tng_gen_block_t block,
-                                                const int64_t block_index,
-                                                const char hash_mode)
+static tng_function_status tng_data_read(tng_trajectory_t tng_data,
+                                         tng_gen_block_t block,
+                                         int *offset,
+                                         const char datatype,
+                                         const int64_t first_frame_with_data,
+                                         const int64_t stride_length,
+                                         int64_t n_frames,
+                                         const int64_t n_values,
+                                         const int64_t codec_id,
+                                         const double multiplier)
 {
-    int64_t n_frames, stride_length, frame_step;
-    int64_t i, j;
-    int offset = 0, size;
-    unsigned int len;
+    int64_t i, j, n_frames_div;
+    int size, len;
 #ifdef USE_ZLIB
-    int data_start_pos;
-    tng_function_status stat;
+    int64_t data_size;
 #endif
-    char temp, dependency, *temp_name;
-    double multiplier;
+    tng_non_particle_data_t data;
     tng_trajectory_frame_set_t frame_set =
     &tng_data->current_trajectory_frame_set;
-
-    tng_non_particle_data_t data;
     char block_type_flag;
 
-    /* If we have already started writing frame sets it is too late to write
-     * non-trajectory data blocks */
-    if(tng_data->current_trajectory_frame_set_output_file_pos > 0)
-    {
-        block_type_flag = TNG_TRAJECTORY_BLOCK;
-    }
-    else
-    {
-        block_type_flag = TNG_NON_TRAJECTORY_BLOCK;
-    }
-
-    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
-    {
-        return(TNG_CRITICAL);
-    }
-
-    if(block_type_flag == TNG_TRAJECTORY_BLOCK)
-    {
-        data = &frame_set->tr_data[block_index];
+    TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer.");
 
-        /* If this data block has not had any data added in this frame set
-         * do not write it. */
-        if(data->first_frame_with_data < frame_set->first_frame)
-        {
-            return(TNG_SUCCESS);
-        }
+/*     fprintf(stderr, "TNG library: %s\n", block->name);*/
 
-        stride_length = tng_max_i64(1, data->stride_length);
-    }
-    else
+    /* This must be caught early to avoid creating a data block if not necessary. */
+#ifndef USE_ZLIB
+    if(codec_id == TNG_GZIP_COMPRESSION)
     {
-        data = &tng_data->non_tr_data[block_index];
-        stride_length = 1;
+        fprintf(stderr, "TNG library: Cannot uncompress data block. %s: %d\n", __FILE__,
+                __LINE__);
+        return(TNG_FAILURE);
     }
+#endif
 
-    switch(data->datatype)
+    switch(datatype)
     {
     case TNG_CHAR_DATA:
         size = 1;
@@ -5842,286 +6661,150 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data,
         size = sizeof(double);
     }
 
-    len = (unsigned int)strlen(data->block_name) + 1;
-
-    if(!block->name || strlen(block->name) < len)
+    /* If the block does not exist, create it */
+    if(tng_data_find(tng_data, block->id, &data) != TNG_SUCCESS)
     {
-        temp_name = realloc(block->name, len);
-        if(!temp_name)
+        if(tng_data->current_trajectory_frame_set_input_file_pos > 0)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len+1,
-                   __FILE__, __LINE__);
-            free(block->name);
-            block->name = 0;
-            return(TNG_CRITICAL);
+            block_type_flag = TNG_TRAJECTORY_BLOCK;
         }
-        block->name = temp_name;
-    }
-    strncpy(block->name, data->block_name, len);
-    block->id = data->block_id;
-
-    /* If writing frame independent data data->n_frames is 0, but n_frames
-       is used for the loop writing the data (and reserving memory) and needs
-       to be at least 1 */
-    n_frames = tng_max_i64(1, data->n_frames);
-
-    if(block_type_flag == TNG_TRAJECTORY_BLOCK)
-    {
-        /* If the frame set is finished before writing the full number of frames
-           make sure the data block is not longer than the frame set. */
-        n_frames = tng_min_i64(n_frames, frame_set->n_frames);
-
-        n_frames -= (data->first_frame_with_data - frame_set->first_frame);
-    }
-
-    frame_step = (n_frames % stride_length) ? n_frames / stride_length + 1:
-                 n_frames / stride_length;
-
-    /* TNG compression will use compression precision to get integers from
-     * floating point data. The compression multiplier stores that information
-     * to be able to return the precision of the compressed data. */
-    if(data->codec_id == TNG_TNG_COMPRESSION)
-    {
-        data->compression_multiplier = tng_data->compression_precision;
-    }
-    /* Uncompressed data blocks do not use compression multipliers at all.
-     * GZip compression does not need it either. */
-    else if(data->codec_id == TNG_UNCOMPRESSED || data->codec_id == TNG_GZIP_COMPRESSION)
-    {
-        data->compression_multiplier = 1.0;
-    }
-
-    block->block_contents_size = sizeof(char) * 2 +
-                                 sizeof(data->n_values_per_frame) +
-                                 sizeof(data->codec_id);
-
-    if(stride_length > 1)
-    {
-        block->block_contents_size += sizeof(data->first_frame_with_data) +
-                                      sizeof(data->stride_length);
-    }
-
-    if(data->codec_id != TNG_UNCOMPRESSED)
-    {
-        block->block_contents_size += sizeof(data->compression_multiplier);
-    }
-
-    if(block_type_flag == TNG_TRAJECTORY_BLOCK && data->n_frames > 0)
-    {
-        dependency = TNG_FRAME_DEPENDENT;
-    }
-    else
-    {
-        dependency = 0;
-    }
-    if(dependency & TNG_FRAME_DEPENDENT)
-    {
-        block->block_contents_size += sizeof(char);
-    }
-
-#ifdef USE_ZLIB
-    data_start_pos = block->block_contents_size;
-#endif
-
-    if(data->datatype == TNG_CHAR_DATA)
-    {
-        for(i = n_frames; i--;)
+        else
         {
-            for(j = data->n_values_per_frame; j--;)
-            {
-                block->block_contents_size += strlen(data->strings[i][j]) + 1;
-            }
+            block_type_flag = TNG_NON_TRAJECTORY_BLOCK;
         }
-    }
-    else
-    {
-        block->block_contents_size += size * frame_step *
-        data->n_values_per_frame;
-    }
-
-    if(block->block_contents)
-    {
-        free(block->block_contents);
-    }
-    block->block_contents = malloc(block->block_contents_size);
-    if(!block->block_contents)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               block->block_contents_size, __FILE__, __LINE__);
-        return(TNG_CRITICAL);
-    }
 
-
-    memcpy(block->block_contents, &data->datatype, sizeof(char));
-    offset += sizeof(char);
-
-    memcpy(block->block_contents+offset, &dependency, sizeof(char));
-    offset += sizeof(char);
-
-    if(dependency & TNG_FRAME_DEPENDENT)
-    {
-        if(stride_length > 1)
+        if(tng_data_block_create(tng_data, block_type_flag) !=
+            TNG_SUCCESS)
         {
-            temp = 1;
+            fprintf(stderr, "TNG library: Cannot create particle data block. %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
         }
-        else
+        if(block_type_flag == TNG_TRAJECTORY_BLOCK)
         {
-            temp = 0;
+            data = &frame_set->tr_data[frame_set->n_data_blocks - 1];
         }
-        memcpy(block->block_contents+offset, &temp, sizeof(char));
-        offset += sizeof(char);
-    }
-
-    memcpy(block->block_contents+offset, &data->n_values_per_frame,
-           sizeof(data->n_values_per_frame));
-    if(tng_data->output_endianness_swap_func_64)
-    {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-           (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
+        else
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            data = &tng_data->non_tr_data[tng_data->n_data_blocks - 1];
         }
-    }
-    offset += sizeof(data->n_values_per_frame);
+        data->block_id = block->id;
 
-    memcpy(block->block_contents+offset, &data->codec_id,
-           sizeof(data->codec_id));
-    if(tng_data->output_endianness_swap_func_64)
-    {
-        if(tng_data->output_endianness_swap_func_64(tng_data,
-           (int64_t *)block->header_contents+offset)
-            != TNG_SUCCESS)
+        data->block_name = malloc(strlen(block->name) + 1);
+        if(!data->block_name)
         {
-            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                    __FILE__, __LINE__);
+            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+                   (int)strlen(block->name)+1, __FILE__, __LINE__);
+            return(TNG_CRITICAL);
         }
-    }
-    offset += sizeof(data->codec_id);
+        strcpy(data->block_name, block->name);
 
-    if(data->codec_id != TNG_UNCOMPRESSED)
-    {
-        memcpy(block->block_contents+offset, &data->compression_multiplier,
-               sizeof(data->compression_multiplier));
-        if(tng_data->output_endianness_swap_func_64)
-        {
-            if(tng_data->output_endianness_swap_func_64(tng_data,
-            (int64_t *)block->header_contents+offset)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
-        }
-        offset += sizeof(data->compression_multiplier);
+        data->datatype = datatype;
+
+        data->values = 0;
+        /* FIXME: Memory leak from strings. */
+        data->strings = 0;
+        data->n_frames = 0;
+        data->codec_id = codec_id;
+        data->compression_multiplier = multiplier;
+        data->last_retrieved_frame = -1;
     }
 
-    if(data->n_frames > 0 && stride_length > 1)
+    n_frames_div = (n_frames % stride_length) ? n_frames / stride_length + 1 : n_frames / stride_length;
+
+    if(codec_id != TNG_UNCOMPRESSED)
     {
-        /* FIXME: first_frame_with_data is not reliably set */
-        if(data->first_frame_with_data == 0)
-        {
-            data->first_frame_with_data = frame_set->first_frame;
-        }
-        memcpy(block->block_contents+offset, &data->first_frame_with_data,
-               sizeof(data->first_frame_with_data));
-        if(tng_data->output_endianness_swap_func_64)
+        switch(codec_id)
         {
-            if(tng_data->output_endianness_swap_func_64(tng_data,
-            (int64_t *)block->header_contents+offset)
-                != TNG_SUCCESS)
+#ifdef USE_ZLIB
+        case TNG_GZIP_COMPRESSION:
+            data_size = n_frames_div * size * n_values;
+    /*         fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
+            if(tng_gzip_uncompress(tng_data, block,
+                                   block->block_contents + *offset,
+                                   data_size) != TNG_SUCCESS)
             {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
+                fprintf(stderr, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__,
+                    __LINE__);
+                return(TNG_CRITICAL);
             }
+    /*         fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
+            break;
+#endif
         }
-        offset += sizeof(data->first_frame_with_data);
+    }
 
-        memcpy(block->block_contents+offset, &stride_length,
-               sizeof(data->stride_length));
-        if(tng_data->output_endianness_swap_func_64)
+    /* Allocate memory */
+    if(!data->values || data->n_frames != n_frames ||
+       data->n_values_per_frame != n_values)
+    {
+        if(tng_allocate_data_mem(tng_data, data, n_frames, stride_length,
+                                 n_values) !=
+           TNG_SUCCESS)
         {
-            if(tng_data->output_endianness_swap_func_64(tng_data,
-            (int64_t *)block->header_contents+offset)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
+            fprintf(stderr, "TNG library: Cannot allocate memory for data. %s: %d\n",
+                   __FILE__, __LINE__);
+            return(TNG_CRITICAL);
         }
-        offset += sizeof(data->stride_length);
     }
 
-    if(data->datatype == TNG_CHAR_DATA)
+    data->first_frame_with_data = first_frame_with_data;
+
+    if(datatype == TNG_CHAR_DATA)
     {
-        if(data->strings)
+        for(i = 0; i < n_frames_div; i++)
         {
-            for(i = 0; i < frame_step; i++)
+            for(j = 0; j < n_values; j++)
             {
-                for(j = 0; j < data->n_values_per_frame; j++)
+                len = tng_min_i((int)strlen(block->block_contents+*offset) + 1,
+                              TNG_MAX_STR_LEN);
+                if(data->strings[i][j])
                 {
-                    len = (unsigned int)strlen(data->strings[i][j]) + 1;
-                    strncpy(block->block_contents+offset, data->strings[i][j],
-                            len);
-                    offset += len;
+                    free(data->strings[i][j]);
+                }
+                data->strings[i][j] = malloc(len);
+                if(!data->strings[i][j])
+                {
+                    fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+                           len, __FILE__, __LINE__);
+                    return(TNG_CRITICAL);
                 }
+                strncpy(data->strings[i][j], block->block_contents+*offset,
+                        len);
+                *offset += len;
             }
         }
     }
-    else if(data->values)
+    else
     {
-        memcpy(block->block_contents + offset, data->values,
-               block->block_contents_size - offset);
-        switch(data->datatype)
+        memcpy(data->values, block->block_contents + *offset,
+               block->block_contents_size - *offset);
+        switch(datatype)
         {
         case TNG_FLOAT_DATA:
-            if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION ||
-               data->codec_id == TNG_TNG_COMPRESSION)
-            {
-                if(tng_data->input_endianness_swap_func_32)
-                {
-                    for(i = offset; i < block->block_contents_size; i+=size)
-                    {
-                        if(tng_data->input_endianness_swap_func_32(tng_data,
-                           (int32_t *)(block->block_contents + i))
-                           != TNG_SUCCESS)
-                        {
-                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                                    __FILE__, __LINE__);
-                        }
-                    }
-                }
-            }
-            else
+            if(tng_data->input_endianness_swap_func_32)
             {
-                multiplier = data->compression_multiplier;
-                if(fabs(multiplier - 1.0) > 0.00001 ||
-                   tng_data->input_endianness_swap_func_32)
+                for(i = 0; i < (block->block_contents_size - *offset); i+=size)
                 {
-                    for(i = offset; block->block_contents_size; i+=size)
-                    {
-                        *(float *)(block->block_contents + i) *= (float)multiplier;
-                        if(tng_data->input_endianness_swap_func_32 &&
-                        tng_data->input_endianness_swap_func_32(tng_data,
-                        (int32_t *)(block->block_contents + i))
+                    if(tng_data->input_endianness_swap_func_32(tng_data,
+                        (int32_t *)((char *)data->values + i))
                         != TNG_SUCCESS)
-                        {
-                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                                    __FILE__, __LINE__);
-                        }
+                    {
+                        fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                                __FILE__, __LINE__);
                     }
                 }
             }
             break;
         case TNG_INT_DATA:
+        case TNG_DOUBLE_DATA:
             if(tng_data->input_endianness_swap_func_64)
             {
-                for(i = offset; i < block->block_contents_size; i+=size)
+                for(i = 0; i < (block->block_contents_size - *offset); i+=size)
                 {
                     if(tng_data->input_endianness_swap_func_64(tng_data,
-                       (int64_t *)(block->block_contents + i))
-                       != TNG_SUCCESS)
+                        (int64_t *)((char *)data->values + i))
+                        != TNG_SUCCESS)
                     {
                         fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                                 __FILE__, __LINE__);
@@ -6129,730 +6812,746 @@ static tng_function_status tng_data_block_write(tng_trajectory_t tng_data,
                 }
             }
             break;
-        case TNG_DOUBLE_DATA:
-            if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION ||
-               data->codec_id == TNG_TNG_COMPRESSION)
-            {
-                if(tng_data->input_endianness_swap_func_64)
-                {
-                    for(i = offset; i < block->block_contents_size; i+=size)
-                    {
-                        if(tng_data->input_endianness_swap_func_64(tng_data,
-                           (int64_t *)(block->block_contents + i))
-                           != TNG_SUCCESS)
-                        {
-                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                                    __FILE__, __LINE__);
-                        }
-                    }
-                }
-            }
-            else
-            {
-                multiplier = data->compression_multiplier;
-                if(fabs(multiplier - 1.0) > 0.00001 ||
-                   tng_data->input_endianness_swap_func_64)
-                {
-                    for(i = offset; i < block->block_contents_size; i+=size)
-                    {
-                        *(double *)(block->block_contents + i) *= multiplier;
-                        if(tng_data->input_endianness_swap_func_64 &&
-                        tng_data->input_endianness_swap_func_64(tng_data,
-                        (int64_t *)(block->block_contents + i))
-                        != TNG_SUCCESS)
-                        {
-                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                                    __FILE__, __LINE__);
-                        }
-                    }
-                }
-            }
-            break;
         case TNG_CHAR_DATA:
             break;
         }
     }
+    return(TNG_SUCCESS);
+}
+
+/** Write a non-particle data block
+ * @param tng_data is a trajectory data container.
+ * @param block is the block to store the data (should already contain
+ * the block headers and the block contents).
+ * @param block_index is the index number of the data block in the frame set.
+ * @param hash_mode is an option to decide whether to use the md5 hash or not.
+ * If hash_mode == TNG_USE_HASH an md5 hash will be generated and written.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
+ */
+static tng_function_status tng_data_block_write(tng_trajectory_t tng_data,
+                                                tng_gen_block_t block,
+                                                const int64_t block_index,
+                                                const char hash_mode)
+{
+    int64_t n_frames, stride_length, frame_step, data_start_pos;
+    int64_t i, j;
+    int offset = 0, size;
+    unsigned int len;
+#ifdef USE_ZLIB
+    tng_function_status stat;
+#endif
+    char temp, dependency, *temp_name;
+    double multiplier;
+    tng_trajectory_frame_set_t frame_set =
+    &tng_data->current_trajectory_frame_set;
+
+    tng_non_particle_data_t data;
+    char block_type_flag;
+
+    /* If we have already started writing frame sets it is too late to write
+     * non-trajectory data blocks */
+    if(tng_data->current_trajectory_frame_set_output_file_pos > 0)
+    {
+        block_type_flag = TNG_TRAJECTORY_BLOCK;
+    }
+    else
+    {
+        block_type_flag = TNG_NON_TRAJECTORY_BLOCK;
+    }
+
+    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
+    {
+        return(TNG_CRITICAL);
+    }
+
+    if(block_type_flag == TNG_TRAJECTORY_BLOCK)
+    {
+        data = &frame_set->tr_data[block_index];
+
+        /* If this data block has not had any data added in this frame set
+         * do not write it. */
+        if(data->first_frame_with_data < frame_set->first_frame)
+        {
+            return(TNG_SUCCESS);
+        }
+
+        stride_length = tng_max_i64(1, data->stride_length);
+    }
     else
     {
-        memset(block->block_contents+offset, 0, block->block_contents_size - offset);
+        data = &tng_data->non_tr_data[block_index];
+        stride_length = 1;
+    }
+
+    switch(data->datatype)
+    {
+    case TNG_CHAR_DATA:
+        size = 1;
+        break;
+    case TNG_INT_DATA:
+        size = sizeof(int64_t);
+        break;
+    case TNG_FLOAT_DATA:
+        size = sizeof(float);
+        break;
+    case TNG_DOUBLE_DATA:
+    default:
+        size = sizeof(double);
     }
 
-    frame_set->n_written_frames += frame_set->n_unwritten_frames;
-    frame_set->n_unwritten_frames = 0;
+    len = (unsigned int)strlen(data->block_name) + 1;
 
-    if(block_type_flag == TNG_NON_TRAJECTORY_BLOCK || frame_set->n_written_frames > 0)
+    if(!block->name || strlen(block->name) < len)
     {
-        switch(data->codec_id)
+        temp_name = realloc(block->name, len);
+        if(!temp_name)
         {
-#ifdef USE_ZLIB
-        case TNG_GZIP_COMPRESSION:
-    /*         fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
-            stat = tng_gzip_compress(tng_data, block,
-                                     block->block_contents + data_start_pos,
-                                     block->block_contents_size - data_start_pos);
-            if(stat != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__,
-                    __LINE__);
-                if(stat == TNG_CRITICAL)
-                {
-                    return(TNG_CRITICAL);
-                }
-                data->codec_id = TNG_UNCOMPRESSED;
-            }
-    /*         fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
-            break;
-#endif
+            fprintf(stderr, "TNG library: Cannot allocate memory (%u bytes). %s: %d\n", len+1,
+                   __FILE__, __LINE__);
+            free(block->name);
+            block->name = 0;
+            return(TNG_CRITICAL);
         }
+        block->name = temp_name;
     }
+    strncpy(block->name, data->block_name, len);
+    block->id = data->block_id;
 
-    if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS)
+    /* If writing frame independent data data->n_frames is 0, but n_frames
+       is used for the loop writing the data (and reserving memory) and needs
+       to be at least 1 */
+    n_frames = tng_max_i64(1, data->n_frames);
+
+    if(block_type_flag == TNG_TRAJECTORY_BLOCK)
     {
-        fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n",
-               tng_data->output_file_path, __FILE__, __LINE__);
-        return(TNG_CRITICAL);
+        /* If the frame set is finished before writing the full number of frames
+           make sure the data block is not longer than the frame set. */
+        n_frames = tng_min_i64(n_frames, frame_set->n_frames);
+
+        n_frames -= (data->first_frame_with_data - frame_set->first_frame);
     }
 
-    if(fwrite(block->block_contents, block->block_contents_size, 1,
-              tng_data->output_file) != 1)
+    frame_step = (n_frames % stride_length) ? n_frames / stride_length + 1:
+                 n_frames / stride_length;
+
+    /* TNG compression will use compression precision to get integers from
+     * floating point data. The compression multiplier stores that information
+     * to be able to return the precision of the compressed data. */
+    if(data->codec_id == TNG_TNG_COMPRESSION)
     {
-        fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n",
-               __FILE__, __LINE__);
-        return(TNG_CRITICAL);
+        data->compression_multiplier = tng_data->compression_precision;
+    }
+    /* Uncompressed data blocks do not use compression multipliers at all.
+     * GZip compression does not need it either. */
+    else if(data->codec_id == TNG_UNCOMPRESSED || data->codec_id == TNG_GZIP_COMPRESSION)
+    {
+        data->compression_multiplier = 1.0;
     }
 
-    return(TNG_SUCCESS);
-}
+    if(block_type_flag == TNG_TRAJECTORY_BLOCK && data->n_frames > 0)
+    {
+        dependency = TNG_FRAME_DEPENDENT;
+    }
+    else
+    {
+        dependency = 0;
+    }
 
-/** Read the meta information of a data block (particle or non-particle data).
- * @param tng_data is a trajectory data container.
- * @param block is the block to store the data (should already contain
- * the block headers).
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
- */
-static tng_function_status tng_data_block_meta_information_read
-                (tng_trajectory_t tng_data,
-                 tng_gen_block_t block,
-                 int *offset,
-                 char *datatype,
-                 char *dependency,
-                 char *sparse_data,
-                 int64_t *n_values,
-                 int64_t *codec_id,
-                 int64_t *first_frame_with_data,
-                 int64_t *stride_length,
-                 int64_t *n_frames,
-                 int64_t *num_first_particle,
-                 int64_t *block_n_particles,
-                 double *multiplier)
-{
-    int meta_size;
-    char *contents;
+    if(tng_data_block_len_calculate(tng_data, (tng_particle_data_t)data, TNG_FALSE, n_frames,
+                                    frame_step, stride_length, 0,
+                                    1, dependency, &data_start_pos,
+                                    &block->block_contents_size) != TNG_SUCCESS)
+    {
+        fprintf(stderr, "TNG library: Cannot calculate length of non-particle data block. %s: %d\n",
+                __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
 
     if(block->block_contents)
     {
-        contents = block->block_contents;
+        free(block->block_contents);
     }
-    else
+    block->block_contents = malloc(block->block_contents_size);
+    if(!block->block_contents)
     {
-        meta_size = 3 * sizeof(char) + sizeof(double) + 6 * sizeof(int64_t);
-        contents = malloc(meta_size);
-        if(!contents)
-        {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
-               meta_size, __FILE__, __LINE__);
-        }
-
-        if(fread(contents, meta_size, 1, tng_data->input_file) == 0)
-        {
-            fprintf(stderr, "TNG library: Cannot read data block meta information. %s: %d\n", __FILE__, __LINE__);
-            free(contents);
-            return(TNG_CRITICAL);
-        }
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+               block->block_contents_size, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
     }
 
-    memcpy(datatype, contents+*offset,
-           sizeof(*datatype));
-    *offset += sizeof(*datatype);
 
-    memcpy(dependency, contents+*offset,
-           sizeof(*dependency));
-    *offset += sizeof(*dependency);
+    memcpy(block->block_contents, &data->datatype, sizeof(char));
+    offset += sizeof(char);
 
-    if(*dependency & TNG_FRAME_DEPENDENT)
+    memcpy(block->block_contents+offset, &dependency, sizeof(char));
+    offset += sizeof(char);
+
+    if(dependency & TNG_FRAME_DEPENDENT)
     {
-        memcpy(sparse_data, contents+*offset,
-               sizeof(*sparse_data));
-        *offset += sizeof(*sparse_data);
+        if(stride_length > 1)
+        {
+            temp = 1;
+        }
+        else
+        {
+            temp = 0;
+        }
+        memcpy(block->block_contents+offset, &temp, sizeof(char));
+        offset += sizeof(char);
     }
 
-    memcpy(n_values, contents+*offset,
-        sizeof(*n_values));
-    if(tng_data->input_endianness_swap_func_64)
+    memcpy(block->block_contents+offset, &data->n_values_per_frame,
+           sizeof(data->n_values_per_frame));
+    if(tng_data->output_endianness_swap_func_64)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   n_values)
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+           (int64_t *)block->header_contents+offset)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    *offset += sizeof(*n_values);
+    offset += sizeof(data->n_values_per_frame);
 
-    memcpy(codec_id, contents+*offset,
-        sizeof(*codec_id));
-    if(tng_data->input_endianness_swap_func_64)
+    memcpy(block->block_contents+offset, &data->codec_id,
+           sizeof(data->codec_id));
+    if(tng_data->output_endianness_swap_func_64)
     {
-        if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                   codec_id)
+        if(tng_data->output_endianness_swap_func_64(tng_data,
+           (int64_t *)block->header_contents+offset)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
-    *offset += sizeof(*codec_id);
+    offset += sizeof(data->codec_id);
 
-    if(*codec_id != TNG_UNCOMPRESSED)
+    if(data->codec_id != TNG_UNCOMPRESSED)
     {
-        memcpy(multiplier, contents+*offset,
-            sizeof(*multiplier));
-        if(tng_data->input_endianness_swap_func_64)
+        memcpy(block->block_contents+offset, &data->compression_multiplier,
+               sizeof(data->compression_multiplier));
+        if(tng_data->output_endianness_swap_func_64)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       (int64_t *) multiplier)
+            if(tng_data->output_endianness_swap_func_64(tng_data,
+            (int64_t *)block->header_contents+offset)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
-        *offset += sizeof(*multiplier);
-    }
-    else
-    {
-        *multiplier = 1;
-    }
-
-    if(*dependency & TNG_FRAME_DEPENDENT)
-    {
-        if(*sparse_data)
-        {
-            memcpy(first_frame_with_data, contents+*offset,
-                sizeof(*first_frame_with_data));
-            if(tng_data->input_endianness_swap_func_64)
-            {
-                if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                           first_frame_with_data)
-                    != TNG_SUCCESS)
-                {
-                    fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                            __FILE__, __LINE__);
-                }
-            }
-            *offset += sizeof(*first_frame_with_data);
-
-            memcpy(stride_length, contents+*offset,
-                sizeof(*stride_length));
-            if(tng_data->input_endianness_swap_func_64)
-            {
-                if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                           stride_length)
-                    != TNG_SUCCESS)
-                {
-                    fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                            __FILE__, __LINE__);
-                }
-            }
-            *offset += sizeof(*stride_length);
-            *n_frames = tng_data->current_trajectory_frame_set.n_frames -
-                        (*first_frame_with_data -
-                        tng_data->current_trajectory_frame_set.first_frame);
-        }
-        else
-        {
-            *first_frame_with_data = 0;
-            *stride_length = 1;
-            *n_frames = tng_data->current_trajectory_frame_set.n_frames;
-        }
-    }
-    else
-    {
-        *first_frame_with_data = 0;
-        *stride_length = 1;
-        *n_frames = 1;
+        offset += sizeof(data->compression_multiplier);
     }
 
-    if (*dependency & TNG_PARTICLE_DEPENDENT)
-    {
-        memcpy(num_first_particle, contents+*offset,
-               sizeof(*num_first_particle));
-        if(tng_data->input_endianness_swap_func_64)
+    if(data->n_frames > 0 && stride_length > 1)
+    {
+        /* FIXME: first_frame_with_data is not reliably set */
+        if(data->first_frame_with_data == 0)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       num_first_particle)
+            data->first_frame_with_data = frame_set->first_frame;
+        }
+        memcpy(block->block_contents+offset, &data->first_frame_with_data,
+               sizeof(data->first_frame_with_data));
+        if(tng_data->output_endianness_swap_func_64)
+        {
+            if(tng_data->output_endianness_swap_func_64(tng_data,
+            (int64_t *)block->header_contents+offset)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
-        *offset += sizeof(*num_first_particle);
+        offset += sizeof(data->first_frame_with_data);
 
-        memcpy(block_n_particles, contents+*offset,
-            sizeof(*block_n_particles));
-        if(tng_data->input_endianness_swap_func_64)
+        memcpy(block->block_contents+offset, &stride_length,
+               sizeof(data->stride_length));
+        if(tng_data->output_endianness_swap_func_64)
         {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                       block_n_particles)
+            if(tng_data->output_endianness_swap_func_64(tng_data,
+            (int64_t *)block->header_contents+offset)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
-        *offset += sizeof(*block_n_particles);
-    }
-
-    if(!block->block_contents)
-    {
-        free(contents);
-    }
-    return(TNG_SUCCESS);
-}
-
-/** Read the contents of a data block (particle or non-particle data).
- * @param tng_data is a trajectory data container.
- * @param block is the block to store the data (should already contain
- * the block headers).
- * @param hash_mode is an option to decide whether to use the md5 hash or not.
- * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
- * compared to the md5 hash of the read contents to ensure valid data.
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
- */
-static tng_function_status tng_data_block_contents_read
-                (tng_trajectory_t tng_data,
-                 tng_gen_block_t block,
-                 const char hash_mode)
-{
-    int64_t n_values, codec_id, n_frames, first_frame_with_data;
-    int64_t stride_length, block_n_particles, num_first_particle;
-    double multiplier;
-    char datatype, dependency, sparse_data;
-    int offset = 0;
-    tng_bool same_hash;
-
-    if(tng_input_file_init(tng_data) != TNG_SUCCESS)
-    {
-        return(TNG_CRITICAL);
-    }
-
-    if(block->block_contents)
-    {
-        free(block->block_contents);
-    }
-
-    block->block_contents = malloc(block->block_contents_size);
-    if(!block->block_contents)
-    {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               block->block_contents_size, __FILE__, __LINE__);
-        return(TNG_CRITICAL);
-    }
-
-    /* Read the whole block into block_contents to be able to write it to
-     * disk even if it cannot be interpreted. */
-    if(fread(block->block_contents, block->block_contents_size, 1,
-             tng_data->input_file) == 0)
-    {
-        fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
-        return(TNG_CRITICAL);
+        offset += sizeof(data->stride_length);
     }
 
-    /* FIXME: Does not check if the size of the contents matches the expected
-     * size or if the contents can be read. */
-
-    if(hash_mode == TNG_USE_HASH)
+    if(data->datatype == TNG_CHAR_DATA)
     {
-        tng_md5_hash_match_verify(block, &same_hash);
-        if(same_hash != TNG_TRUE)
+        if(data->strings)
         {
-            fprintf(stderr, "TNG library: '%s' data block contents corrupt. Hashes do not match. %s: %d\n",
-                block->name, __FILE__, __LINE__);
-    /*         return(TNG_FAILURE); */
+            for(i = 0; i < frame_step; i++)
+            {
+                for(j = 0; j < data->n_values_per_frame; j++)
+                {
+                    len = (unsigned int)strlen(data->strings[i][j]) + 1;
+                    strncpy(block->block_contents+offset, data->strings[i][j],
+                            len);
+                    offset += len;
+                }
+            }
         }
     }
-
-    if(tng_data_block_meta_information_read(tng_data, block,
-                                            &offset, &datatype,
-                                            &dependency, &sparse_data,
-                                            &n_values, &codec_id,
-                                            &first_frame_with_data,
-                                            &stride_length, &n_frames,
-                                            &num_first_particle,
-                                            &block_n_particles,
-                                            &multiplier) == TNG_CRITICAL)
-    {
-        fprintf(stderr, "TNG library: Cannot read data block (%s) meta information. %s: %d\n",
-            block->name, __FILE__, __LINE__);
-        return(TNG_CRITICAL);
-    }
-
-    if (dependency & TNG_PARTICLE_DEPENDENT)
+    else if(data->values)
     {
-        return(tng_particle_data_read(tng_data, block,
-                                      &offset, datatype,
-                                      num_first_particle,
-                                      block_n_particles,
-                                      first_frame_with_data,
-                                      stride_length,
-                                      n_frames, n_values,
-                                      codec_id, multiplier));
+        memcpy(block->block_contents + offset, data->values,
+               block->block_contents_size - offset);
+        switch(data->datatype)
+        {
+        case TNG_FLOAT_DATA:
+            if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION ||
+               data->codec_id == TNG_TNG_COMPRESSION)
+            {
+                if(tng_data->input_endianness_swap_func_32)
+                {
+                    for(i = offset; i < block->block_contents_size; i+=size)
+                    {
+                        if(tng_data->input_endianness_swap_func_32(tng_data,
+                           (int32_t *)(block->block_contents + i))
+                           != TNG_SUCCESS)
+                        {
+                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                                    __FILE__, __LINE__);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                multiplier = data->compression_multiplier;
+                if(fabs(multiplier - 1.0) > 0.00001 ||
+                   tng_data->input_endianness_swap_func_32)
+                {
+                    for(i = offset; block->block_contents_size; i+=size)
+                    {
+                        *(float *)(block->block_contents + i) *= (float)multiplier;
+                        if(tng_data->input_endianness_swap_func_32 &&
+                        tng_data->input_endianness_swap_func_32(tng_data,
+                        (int32_t *)(block->block_contents + i))
+                        != TNG_SUCCESS)
+                        {
+                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                                    __FILE__, __LINE__);
+                        }
+                    }
+                }
+            }
+            break;
+        case TNG_INT_DATA:
+            if(tng_data->input_endianness_swap_func_64)
+            {
+                for(i = offset; i < block->block_contents_size; i+=size)
+                {
+                    if(tng_data->input_endianness_swap_func_64(tng_data,
+                       (int64_t *)(block->block_contents + i))
+                       != TNG_SUCCESS)
+                    {
+                        fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                                __FILE__, __LINE__);
+                    }
+                }
+            }
+            break;
+        case TNG_DOUBLE_DATA:
+            if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION ||
+               data->codec_id == TNG_TNG_COMPRESSION)
+            {
+                if(tng_data->input_endianness_swap_func_64)
+                {
+                    for(i = offset; i < block->block_contents_size; i+=size)
+                    {
+                        if(tng_data->input_endianness_swap_func_64(tng_data,
+                           (int64_t *)(block->block_contents + i))
+                           != TNG_SUCCESS)
+                        {
+                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                                    __FILE__, __LINE__);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                multiplier = data->compression_multiplier;
+                if(fabs(multiplier - 1.0) > 0.00001 ||
+                   tng_data->input_endianness_swap_func_64)
+                {
+                    for(i = offset; i < block->block_contents_size; i+=size)
+                    {
+                        *(double *)(block->block_contents + i) *= multiplier;
+                        if(tng_data->input_endianness_swap_func_64 &&
+                        tng_data->input_endianness_swap_func_64(tng_data,
+                        (int64_t *)(block->block_contents + i))
+                        != TNG_SUCCESS)
+                        {
+                            fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                                    __FILE__, __LINE__);
+                        }
+                    }
+                }
+            }
+            break;
+        case TNG_CHAR_DATA:
+            break;
+        }
     }
     else
     {
-        return(tng_data_read(tng_data, block,
-                             &offset, datatype,
-                             first_frame_with_data,
-                             stride_length,
-                             n_frames, n_values,
-                             codec_id, multiplier));
+        memset(block->block_contents+offset, 0, block->block_contents_size - offset);
     }
-}
 
-/** Update the md5 hash of a block already written to the file
- * @param tng_data is a trajectory data container.
- * @param block is the block, of which to update the md5 hash.
- * @param header_start_pos is the file position where the block header starts.
- * @param contents_start_pos is the file position where the block contents
- * start.
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
- */
-static tng_function_status tng_md5_hash_update(tng_trajectory_t tng_data,
-                                               tng_gen_block_t block,
-                                               const int64_t header_start_pos,
-                                               const int64_t contents_start_pos)
-{
-    if(block->block_contents)
+    frame_set->n_written_frames += frame_set->n_unwritten_frames;
+    frame_set->n_unwritten_frames = 0;
+
+    if(block_type_flag == TNG_NON_TRAJECTORY_BLOCK || frame_set->n_written_frames > 0)
     {
-        free(block->block_contents);
+        switch(data->codec_id)
+        {
+#ifdef USE_ZLIB
+        case TNG_GZIP_COMPRESSION:
+    /*         fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */
+            stat = tng_gzip_compress(tng_data, block,
+                                     block->block_contents + data_start_pos,
+                                     block->block_contents_size - data_start_pos);
+            if(stat != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__,
+                    __LINE__);
+                if(stat == TNG_CRITICAL)
+                {
+                    return(TNG_CRITICAL);
+                }
+                data->codec_id = TNG_UNCOMPRESSED;
+            }
+    /*         fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */
+            break;
+#endif
+        }
     }
 
-    block->block_contents = malloc(block->block_contents_size);
-    if(!block->block_contents)
+    if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-               block->block_contents_size, __FILE__, __LINE__);
+        fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n",
+               tng_data->output_file_path, __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
 
-    fseek(tng_data->output_file, (long)contents_start_pos, SEEK_SET);
-    if(fread(block->block_contents, block->block_contents_size, 1,
-            tng_data->output_file) == 0)
+    if(fwrite(block->block_contents, block->block_contents_size, 1,
+              tng_data->output_file) != 1)
     {
-        fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
+        fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n",
+               __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
 
-    tng_block_md5_hash_generate(block);
-
-    fseek(tng_data->output_file, (long)header_start_pos + 3 * sizeof(int64_t),
-          SEEK_SET);
-    fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file);
-
     return(TNG_SUCCESS);
 }
 
-/** Update the frame set pointers in the file header (general info block),
- * already written to disk
+/** Read the meta information of a data block (particle or non-particle data).
  * @param tng_data is a trajectory data container.
- * @param hash_mode specifies whether to update the block md5 hash when
- * updating the pointers.
+ * @param block is the block to store the data (should already contain
+ * the block headers).
  * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
  * error has occured.
  */
-static tng_function_status tng_header_pointers_update
-                (tng_trajectory_t tng_data, const char hash_mode)
+static tng_function_status tng_data_block_meta_information_read
+                (tng_trajectory_t tng_data,
+                 tng_gen_block_t block,
+                 int *offset,
+                 char *datatype,
+                 char *dependency,
+                 char *sparse_data,
+                 int64_t *n_values,
+                 int64_t *codec_id,
+                 int64_t *first_frame_with_data,
+                 int64_t *stride_length,
+                 int64_t *n_frames,
+                 int64_t *num_first_particle,
+                 int64_t *block_n_particles,
+                 double *multiplier)
 {
-    tng_gen_block_t block;
-    FILE *temp = tng_data->input_file;
-    int64_t output_file_pos, pos, contents_start_pos;
+    int meta_size;
+    char *contents;
 
-    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
+    if(block->block_contents)
     {
-        fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
-               __FILE__, __LINE__);
-        return(TNG_CRITICAL);
+        contents = block->block_contents;
     }
+    else
+    {
+        meta_size = 3 * sizeof(char) + sizeof(double) + 6 * sizeof(int64_t);
+        contents = malloc(meta_size);
+        if(!contents)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+               meta_size, __FILE__, __LINE__);
+        }
 
-    tng_data->input_file = tng_data->output_file;
+        if(fread(contents, meta_size, 1, tng_data->input_file) == 0)
+        {
+            fprintf(stderr, "TNG library: Cannot read data block meta information. %s: %d\n", __FILE__, __LINE__);
+            free(contents);
+            return(TNG_CRITICAL);
+        }
+    }
 
-    tng_block_init(&block);
+    memcpy(datatype, contents+*offset,
+           sizeof(*datatype));
+    *offset += sizeof(*datatype);
 
-    output_file_pos = ftell(tng_data->output_file);
-    fseek(tng_data->output_file, 0, SEEK_SET);
+    memcpy(dependency, contents+*offset,
+           sizeof(*dependency));
+    *offset += sizeof(*dependency);
 
-    if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
+    if(*dependency & TNG_FRAME_DEPENDENT)
     {
-        fprintf(stderr, "TNG library: Cannot read general info header. %s: %d\n",
-               __FILE__, __LINE__);
-        tng_data->input_file = temp;
-        tng_block_destroy(&block);
-        return(TNG_CRITICAL);
+        memcpy(sparse_data, contents+*offset,
+               sizeof(*sparse_data));
+        *offset += sizeof(*sparse_data);
     }
 
-    contents_start_pos = ftell(tng_data->output_file);
-
-    fseek(tng_data->output_file, (long)block->block_contents_size - 5 *
-          sizeof(int64_t), SEEK_CUR);
-
-    tng_data->input_file = temp;
-
-    pos = tng_data->first_trajectory_frame_set_output_file_pos;
-
+    memcpy(n_values, contents+*offset,
+        sizeof(*n_values));
     if(tng_data->input_endianness_swap_func_64)
     {
         if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                    &pos)
+                                                   n_values)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
+    *offset += sizeof(*n_values);
 
-    if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
-    {
-        tng_block_destroy(&block);
-        return(TNG_CRITICAL);
-    }
-
-    pos = tng_data->last_trajectory_frame_set_output_file_pos;
-
+    memcpy(codec_id, contents+*offset,
+        sizeof(*codec_id));
     if(tng_data->input_endianness_swap_func_64)
     {
         if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                    &pos)
+                                                   codec_id)
             != TNG_SUCCESS)
         {
             fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                     __FILE__, __LINE__);
         }
     }
+    *offset += sizeof(*codec_id);
 
-    if(fwrite(&pos,
-        sizeof(int64_t), 1, tng_data->output_file) != 1)
-    {
-        tng_block_destroy(&block);
-        return(TNG_CRITICAL);
-    }
-
-    if(hash_mode == TNG_USE_HASH)
-    {
-        tng_md5_hash_update(tng_data, block, 0, contents_start_pos);
-    }
-
-    tng_block_destroy(&block);
-
-    fseek(tng_data->output_file, (long)output_file_pos, SEEK_SET);
-
-    return(TNG_SUCCESS);
-}
-
-/** Update the frame set pointers in the current frame set block, already
- * written to disk. It also updates the pointers of the blocks pointing to
- * the current frame set block.
- * @param tng_data is a trajectory data container.
- * @param hash_mode specifies whether to update the block md5 hash when
- * updating the pointers.
- * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
- * error has occured.
- */
-static tng_function_status tng_frame_set_pointers_update
-                (tng_trajectory_t tng_data, const char hash_mode)
-{
-    tng_gen_block_t block;
-    tng_trajectory_frame_set_t frame_set;
-    FILE *temp = tng_data->input_file;
-    int64_t pos, output_file_pos, header_start_pos, contents_start_pos;
-
-    if(tng_output_file_init(tng_data) != TNG_SUCCESS)
-    {
-        fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n",
-               __FILE__, __LINE__);
-        return(TNG_CRITICAL);
-    }
-
-    tng_block_init(&block);
-    output_file_pos = ftell(tng_data->output_file);
-
-    tng_data->input_file = tng_data->output_file;
-
-    frame_set = &tng_data->current_trajectory_frame_set;
-
-    /* Update previous frame set */
-    if(frame_set->prev_frame_set_file_pos != -1 &&
-       frame_set->prev_frame_set_file_pos != 0)
+    if(*codec_id != TNG_UNCOMPRESSED)
     {
-        fseek(tng_data->output_file, (long)frame_set->prev_frame_set_file_pos,
-              SEEK_SET);
-
-        header_start_pos = frame_set->prev_frame_set_file_pos;
-
-        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot read frame header. %s: %d\n",
-                __FILE__, __LINE__);
-            tng_data->input_file = temp;
-            tng_block_destroy(&block);
-            return(TNG_CRITICAL);
-        }
-
-        contents_start_pos = ftell(tng_data->output_file);
-
-        fseek(tng_data->output_file, (long)block->block_contents_size - (6 *
-            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
-
-        pos = tng_data->current_trajectory_frame_set_output_file_pos;
-
+        memcpy(multiplier, contents+*offset,
+            sizeof(*multiplier));
         if(tng_data->input_endianness_swap_func_64)
         {
             if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                        &pos)
+                                                       (int64_t *) multiplier)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
+        *offset += sizeof(*multiplier);
+    }
+    else
+    {
+        *multiplier = 1;
+    }
 
-        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
+    if(*dependency & TNG_FRAME_DEPENDENT)
+    {
+        if(*sparse_data)
         {
-            tng_data->input_file = temp;
-            tng_block_destroy(&block);
-            return(TNG_CRITICAL);
-        }
+            memcpy(first_frame_with_data, contents+*offset,
+                sizeof(*first_frame_with_data));
+            if(tng_data->input_endianness_swap_func_64)
+            {
+                if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                           first_frame_with_data)
+                    != TNG_SUCCESS)
+                {
+                    fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                            __FILE__, __LINE__);
+                }
+            }
+            *offset += sizeof(*first_frame_with_data);
 
-        if(hash_mode == TNG_USE_HASH)
+            memcpy(stride_length, contents+*offset,
+                sizeof(*stride_length));
+            if(tng_data->input_endianness_swap_func_64)
+            {
+                if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                           stride_length)
+                    != TNG_SUCCESS)
+                {
+                    fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                            __FILE__, __LINE__);
+                }
+            }
+            *offset += sizeof(*stride_length);
+            *n_frames = tng_data->current_trajectory_frame_set.n_frames -
+                        (*first_frame_with_data -
+                        tng_data->current_trajectory_frame_set.first_frame);
+        }
+        else
         {
-            tng_md5_hash_update(tng_data, block, header_start_pos,
-                                contents_start_pos);
+            *first_frame_with_data = 0;
+            *stride_length = 1;
+            *n_frames = tng_data->current_trajectory_frame_set.n_frames;
         }
-        fseek(tng_data->output_file, (long)output_file_pos, SEEK_SET);
     }
-
-    /* Update the frame set one medium stride step before */
-    if(frame_set->medium_stride_prev_frame_set_file_pos != -1 &&
-       frame_set->medium_stride_prev_frame_set_file_pos != 0)
+    else
     {
-        fseek(tng_data->output_file,
-              (long)frame_set->medium_stride_prev_frame_set_file_pos,
-              SEEK_SET);
-
-        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
-                __FILE__, __LINE__);
-            tng_data->input_file = temp;
-            tng_block_destroy(&block);
-            return(TNG_CRITICAL);
-        }
-
-        contents_start_pos = ftell(tng_data->output_file);
-
-        fseek(tng_data->output_file, (long)block->block_contents_size - (4 *
-            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
-
-        pos = tng_data->current_trajectory_frame_set_output_file_pos;
+        *first_frame_with_data = 0;
+        *stride_length = 1;
+        *n_frames = 1;
+    }
 
+    if (*dependency & TNG_PARTICLE_DEPENDENT)
+    {
+        memcpy(num_first_particle, contents+*offset,
+               sizeof(*num_first_particle));
         if(tng_data->input_endianness_swap_func_64)
         {
             if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                        &pos)
+                                                       num_first_particle)
                 != TNG_SUCCESS)
             {
                 fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
                         __FILE__, __LINE__);
             }
         }
+        *offset += sizeof(*num_first_particle);
 
-        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
-        {
-            tng_data->input_file = temp;
-            tng_block_destroy(&block);
-            return(TNG_CRITICAL);
-        }
-
-        if(hash_mode == TNG_USE_HASH)
+        memcpy(block_n_particles, contents+*offset,
+            sizeof(*block_n_particles));
+        if(tng_data->input_endianness_swap_func_64)
         {
-            tng_md5_hash_update(tng_data, block,
-                                frame_set->medium_stride_prev_frame_set_file_pos,
-                                contents_start_pos);
+            if(tng_data->input_endianness_swap_func_64(tng_data,
+                                                       block_n_particles)
+                != TNG_SUCCESS)
+            {
+                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
+                        __FILE__, __LINE__);
+            }
         }
+        *offset += sizeof(*block_n_particles);
     }
 
-    /* Update the frame set one long stride step before */
-    if(frame_set->long_stride_prev_frame_set_file_pos != -1 &&
-       frame_set->long_stride_prev_frame_set_file_pos != 0)
+    if(!block->block_contents)
     {
-        fseek(tng_data->output_file,
-              (long)frame_set->long_stride_prev_frame_set_file_pos,
-              SEEK_SET);
+        free(contents);
+    }
+    return(TNG_SUCCESS);
+}
 
-        if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
-        {
-            fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
-                __FILE__, __LINE__);
-            tng_data->input_file = temp;
-            tng_block_destroy(&block);
-            return(TNG_CRITICAL);
-        }
+/** Read the contents of a data block (particle or non-particle data).
+ * @param tng_data is a trajectory data container.
+ * @param block is the block to store the data (should already contain
+ * the block headers).
+ * @param hash_mode is an option to decide whether to use the md5 hash or not.
+ * If hash_mode == TNG_USE_HASH the written md5 hash in the file will be
+ * compared to the md5 hash of the read contents to ensure valid data.
+ * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major
+ * error has occured.
+ */
+static tng_function_status tng_data_block_contents_read
+                (tng_trajectory_t tng_data,
+                 tng_gen_block_t block,
+                 const char hash_mode)
+{
+    int64_t n_values, codec_id, n_frames, first_frame_with_data;
+    int64_t stride_length, block_n_particles, num_first_particle;
+    double multiplier;
+    char datatype, dependency, sparse_data;
+    int offset = 0;
+    tng_bool same_hash;
 
-        contents_start_pos = ftell(tng_data->output_file);
+    if(tng_input_file_init(tng_data) != TNG_SUCCESS)
+    {
+        return(TNG_CRITICAL);
+    }
 
-        fseek(tng_data->output_file, (long)block->block_contents_size - (2 *
-            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
+    if(block->block_contents)
+    {
+        free(block->block_contents);
+    }
 
-        pos = tng_data->current_trajectory_frame_set_output_file_pos;
+    block->block_contents = malloc(block->block_contents_size);
+    if(!block->block_contents)
+    {
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+               block->block_contents_size, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
 
-        if(tng_data->input_endianness_swap_func_64)
-        {
-            if(tng_data->input_endianness_swap_func_64(tng_data,
-                                                        &pos)
-                != TNG_SUCCESS)
-            {
-                fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n",
-                        __FILE__, __LINE__);
-            }
-        }
+    /* Read the whole block into block_contents to be able to write it to
+     * disk even if it cannot be interpreted. */
+    if(fread(block->block_contents, block->block_contents_size, 1,
+             tng_data->input_file) == 0)
+    {
+        fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
 
-        if(fwrite(&pos, sizeof(int64_t), 1, tng_data->output_file) != 1)
-        {
-            tng_data->input_file = temp;
-            tng_block_destroy(&block);
-            return(TNG_CRITICAL);
-        }
+    /* FIXME: Does not check if the size of the contents matches the expected
+     * size or if the contents can be read. */
 
-        if(hash_mode == TNG_USE_HASH)
+    if(hash_mode == TNG_USE_HASH)
+    {
+        tng_md5_hash_match_verify(block, &same_hash);
+        if(same_hash != TNG_TRUE)
         {
-            tng_md5_hash_update(tng_data, block,
-                                frame_set->long_stride_prev_frame_set_file_pos,
-                                contents_start_pos);
+            fprintf(stderr, "TNG library: '%s' data block contents corrupt. Hashes do not match. %s: %d\n",
+                block->name, __FILE__, __LINE__);
+    /*         return(TNG_FAILURE); */
         }
     }
 
-    fseek(tng_data->output_file, (long)output_file_pos, SEEK_SET);
-
-    tng_data->input_file = temp;
-
-    tng_block_destroy(&block);
+    if(tng_data_block_meta_information_read(tng_data, block,
+                                            &offset, &datatype,
+                                            &dependency, &sparse_data,
+                                            &n_values, &codec_id,
+                                            &first_frame_with_data,
+                                            &stride_length, &n_frames,
+                                            &num_first_particle,
+                                            &block_n_particles,
+                                            &multiplier) == TNG_CRITICAL)
+    {
+        fprintf(stderr, "TNG library: Cannot read data block (%s) meta information. %s: %d\n",
+            block->name, __FILE__, __LINE__);
+        return(TNG_CRITICAL);
+    }
 
-    return(TNG_SUCCESS);
+    if (dependency & TNG_PARTICLE_DEPENDENT)
+    {
+        return(tng_particle_data_read(tng_data, block,
+                                      &offset, datatype,
+                                      num_first_particle,
+                                      block_n_particles,
+                                      first_frame_with_data,
+                                      stride_length,
+                                      n_frames, n_values,
+                                      codec_id, multiplier));
+    }
+    else
+    {
+        return(tng_data_read(tng_data, block,
+                             &offset, datatype,
+                             first_frame_with_data,
+                             stride_length,
+                             n_frames, n_values,
+                             codec_id, multiplier));
+    }
 }
+
 /*
 // ** Move the blocks in a frame set so that there is no unused space between
 //  * them. This can only be done on the last frame set in the file and should
@@ -6891,13 +7590,13 @@ static tng_function_status tng_frame_set_pointers_update
 //     }
 //
 //     tng_block_init(&block);
-// //     output_file_pos = ftell(tng_data->output_file);
+// //     output_file_pos = ftello(tng_data->output_file);
 //
 //     tng_data->input_file = tng_data->output_file;
 //
 //     pos = tng_data->current_trajectory_frame_set_output_file_pos;
 //
-//     fseek(tng_data->output_file, pos, SEEK_SET);
+//     fseeko(tng_data->output_file, pos, SEEK_SET);
 //     if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
 //     {
 //         fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n",
@@ -6907,12 +7606,12 @@ static tng_function_status tng_frame_set_pointers_update
 //         return(TNG_CRITICAL);
 //     }
 //
-//     contents_start_pos = ftell(tng_data->output_file);
+//     contents_start_pos = ftello(tng_data->output_file);
 //
-//     fseek(tng_data->output_file, 0, SEEK_END);
-//     output_file_len = ftell(tng_data->output_file);
+//     fseeko(tng_data->output_file, 0, SEEK_END);
+//     output_file_len = ftello(tng_data->output_file);
 //     pos = contents_start_pos + block->block_contents_size;
-//     fseek(tng_data->output_file, pos,
+//     fseeko(tng_data->output_file, pos,
 //           SEEK_SET);
 //
 //     while(pos < output_file_len)
@@ -6926,7 +7625,7 @@ static tng_function_status tng_frame_set_pointers_update
 //             return(TNG_CRITICAL);
 //         }
 //         pos += block->header_contents_size + block->block_contents_size;
-//         fseek(tng_data->output_file, pos, SEEK_SET);
+//         fseeko(tng_data->output_file, pos, SEEK_SET);
 //     }
 //
 //     return(TNG_SUCCESS);
@@ -6964,13 +7663,13 @@ static tng_function_status tng_frame_set_finalize
     }
 
     tng_block_init(&block);
-/*     output_file_pos = ftell(tng_data->output_file); */
+/*     output_file_pos = ftello(tng_data->output_file); */
 
     tng_data->input_file = tng_data->output_file;
 
     pos = tng_data->current_trajectory_frame_set_output_file_pos;
 
-    fseek(tng_data->output_file, (long)pos, SEEK_SET);
+    fseeko(tng_data->output_file, pos, SEEK_SET);
 
     if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
     {
@@ -6981,9 +7680,9 @@ static tng_function_status tng_frame_set_finalize
         return(TNG_CRITICAL);
     }
 
-    contents_start_pos = ftell(tng_data->output_file);
+    contents_start_pos = ftello(tng_data->output_file);
 
-    fseek(tng_data->output_file, sizeof(frame_set->first_frame), SEEK_CUR);
+    fseeko(tng_data->output_file, sizeof(frame_set->first_frame), SEEK_CUR);
     if(fwrite(&frame_set->n_written_frames, sizeof(frame_set->n_frames),
               1, tng_data->output_file) != 1)
     {
@@ -6999,10 +7698,10 @@ static tng_function_status tng_frame_set_finalize
                             pos + block->header_contents_size);
     }
 
-    fseek(tng_data->output_file, 0, SEEK_END);
-    output_file_len = ftell(tng_data->output_file);
+    fseeko(tng_data->output_file, 0, SEEK_END);
+    output_file_len = ftello(tng_data->output_file);
     pos = contents_start_pos + block->block_contents_size;
-    fseek(tng_data->output_file, (long)pos, SEEK_SET);
+    fseeko(tng_data->output_file, pos, SEEK_SET);
 
     while(pos < output_file_len)
     {
@@ -7021,7 +7720,7 @@ static tng_function_status tng_frame_set_finalize
                                 pos + block->header_contents_size);
         }
         pos += block->header_contents_size + block->block_contents_size;
-        fseek(tng_data->output_file, (long)pos, SEEK_SET);
+        fseeko(tng_data->output_file, pos, SEEK_SET);
     }
 
     tng_data->input_file = temp;
@@ -7222,34 +7921,70 @@ static tng_function_status tng_atom_destroy(tng_atom_t atom)
     return(TNG_SUCCESS);
 }
 
+tng_function_status DECLSPECDLLEXPORT tng_version_major
+                (const tng_trajectory_t tng_data,
+                 int *version)
+{
+    (void)tng_data;
+
+    *version = TNG_VERSION_MAJOR;
+
+    return(TNG_SUCCESS);
+}
+
+tng_function_status DECLSPECDLLEXPORT tng_version_minor
+                (const tng_trajectory_t tng_data,
+                 int *version)
+{
+    (void)tng_data;
+
+    *version = TNG_VERSION_MINOR;
+
+    return(TNG_SUCCESS);
+}
+
+tng_function_status DECLSPECDLLEXPORT tng_version_patchlevel
+                (const tng_trajectory_t tng_data,
+                 int *patch_level)
+{
+    (void)tng_data;
+
+    *patch_level = TNG_VERSION_PATCHLEVEL;
+
+    return(TNG_SUCCESS);
+}
+
+tng_function_status DECLSPECDLLEXPORT tng_version
+                (const tng_trajectory_t tng_data,
+                 char *version,
+                 const int max_len)
+{
+    (void)tng_data;
+    TNG_ASSERT(version, "TNG library: version must not be a NULL pointer");
+
+    TNG_SNPRINTF(version, max_len, "%s", TNG_VERSION);
+
+    return(TNG_SUCCESS);
+}
+
 tng_function_status DECLSPECDLLEXPORT tng_molecule_add
                 (tng_trajectory_t tng_data,
                  const char *name,
                  tng_molecule_t *molecule)
 {
-    int64_t id, i;
-    tng_bool found_id = TNG_TRUE;
+    int64_t id;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(name, "TNG library: name must not be a NULL pointer.");
 
-    /* Find an unused ID */
-    id = 0;
-    while(found_id)
+    /* Set ID to the ID of the last molecule + 1 */
+    if(tng_data->n_molecules)
     {
-        found_id = TNG_FALSE;
-        for(i = tng_data->n_molecules; i--;)
-        {
-            if(tng_data->molecules[i].id == id)
-            {
-                found_id = TNG_TRUE;
-                i = 0;
-            }
-        }
-        if(found_id)
-        {
-            id++;
-        }
+        id = tng_data->molecules[tng_data->n_molecules-1].id + 1;
+    }
+    else
+    {
+        id = 1;
     }
 
     return(tng_molecule_w_id_add(tng_data, name, id, molecule));
@@ -7262,7 +7997,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add
                  tng_molecule_t *molecule)
 {
     tng_molecule_t new_molecules;
-    int64_t *new_molecule_cnt_list, i;
+    int64_t *new_molecule_cnt_list;
     tng_function_status stat = TNG_SUCCESS;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
@@ -7274,7 +8009,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add
 
     if(!new_molecules)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_molecule) * (tng_data->n_molecules + 1),
                __FILE__, __LINE__);
         free(tng_data->molecules);
@@ -7288,7 +8023,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add
 
     if(!new_molecule_cnt_list)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(int64_t) * (tng_data->n_molecules + 1),
                __FILE__, __LINE__);
         free(tng_data->molecule_cnt_list);
@@ -7308,17 +8043,6 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add
     /* FIXME: Should this be a function argument instead? */
     tng_data->molecule_cnt_list[tng_data->n_molecules] = 0;
 
-    for(i = tng_data->n_molecules; i--;)
-    {
-        if(tng_data->molecules[i].id == id)
-        {
-            stat = TNG_FAILURE;
-            fprintf(stderr, "TNG library: Molecule ID %"PRId64" already in use. %s: %d\n", id,
-                   __FILE__, __LINE__);
-            break;
-        }
-    }
-
     (*molecule)->id = id;
 
     tng_data->n_molecules++;
@@ -7330,29 +8054,19 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add
                 (tng_trajectory_t tng_data,
                  tng_molecule_t *molecule_p)
 {
-    tng_bool found_id = TNG_TRUE;
+    int64_t *new_molecule_cnt_list, id;
     tng_molecule_t new_molecules, molecule;
-    int64_t *new_molecule_cnt_list, i, id;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
 
-    /* Find an unused ID */
-    id = 0;
-    while(found_id)
+    /* Set ID to the ID of the last molecule + 1 */
+    if(tng_data->n_molecules)
     {
-        found_id = TNG_FALSE;
-        for(i = tng_data->n_molecules; i--;)
-        {
-            if(tng_data->molecules[i].id == id)
-            {
-                found_id = TNG_TRUE;
-                i = 0;
-            }
-        }
-        if(found_id)
-        {
-            id++;
-        }
+        id = tng_data->molecules[tng_data->n_molecules-1].id + 1;
+    }
+    else
+    {
+        id = 1;
     }
 
     new_molecules = realloc(tng_data->molecules,
@@ -7361,7 +8075,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add
 
     if(!new_molecules)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_molecule) * (tng_data->n_molecules + 1),
                __FILE__, __LINE__);
         free(tng_data->molecules);
@@ -7375,7 +8089,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add
 
     if(!new_molecule_cnt_list)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(int64_t) * (tng_data->n_molecules + 1),
                __FILE__, __LINE__);
         free(tng_data->molecule_cnt_list);
@@ -7471,12 +8185,12 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(cnt, "TNG library: cnt must not be a NULL pointer.");
 
-    for(i = tng_data->n_molecules; i--;)
+    for(i = 0; i < tng_data->n_molecules; i++)
     {
         if(&tng_data->molecules[i] == molecule)
         {
             index = i;
-            i = 0;
+            break;
         }
     }
     if(index == -1)
@@ -7497,12 +8211,12 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
 
-    for(i = tng_data->n_molecules; i--;)
+    for(i = 0; i < tng_data->n_molecules; i++)
     {
         if(&tng_data->molecules[i] == molecule)
         {
             index = i;
-            i = 0;
+            break;
         }
     }
     if(index == -1)
@@ -7545,7 +8259,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_find
 
     n_molecules = tng_data->n_molecules;
 
-    for(i = 0; i < n_molecules; i++)
+    for(i = n_molecules - 1; i >= 0; i--)
     {
         *molecule = &tng_data->molecules[i];
         if(name[0] == 0 || strcmp(name, (*molecule)->name) == 0)
@@ -7606,7 +8320,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(tng_trajectory_t
                     sizeof(struct tng_molecule) * tng_data_src->n_molecules);
     if(!molecule_temp)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_molecule) * tng_data_src->n_molecules,
                __FILE__, __LINE__);
         free(tng_data_dest->molecules);
@@ -7617,7 +8331,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(tng_trajectory_t
                                      sizeof(int64_t) * tng_data_src->n_molecules);
     if(!list_temp)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(int64_t) * tng_data_src->n_molecules,
                __FILE__, __LINE__);
         free(tng_data_dest->molecule_cnt_list);
@@ -7681,21 +8395,24 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(tng_trajectory_t
             }
         }
         molecule_temp->n_bonds = molecule->n_bonds;
-        bond_temp = realloc(molecule_temp->bonds, sizeof(struct tng_bond) *
-                            molecule->n_bonds);
-        if(!bond_temp)
-        {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
-                   sizeof(struct tng_bond) * molecule->n_bonds,
-                   __FILE__, __LINE__);
-            free(molecule_temp->bonds);
-            molecule_temp->n_bonds = 0;
-            return(TNG_CRITICAL);
-        }
-        molecule_temp->bonds = bond_temp;
-        for(j = 0; j < molecule->n_bonds; j++)
+        if(molecule->n_bonds > 0)
         {
-            molecule_temp->bonds[j] = molecule->bonds[j];
+            bond_temp = realloc(molecule_temp->bonds, sizeof(struct tng_bond) *
+                                molecule->n_bonds);
+            if(!bond_temp)
+            {
+                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
+                       sizeof(struct tng_bond) * molecule->n_bonds,
+                       __FILE__, __LINE__);
+                free(molecule_temp->bonds);
+                molecule_temp->n_bonds = 0;
+                return(TNG_CRITICAL);
+            }
+            molecule_temp->bonds = bond_temp;
+            for(j = 0; j < molecule->n_bonds; j++)
+            {
+                molecule_temp->bonds[j] = molecule->bonds[j];
+            }
         }
         stat = tng_molecule_cnt_set(tng_data_dest, molecule_temp,
                                     tng_data_src->molecule_cnt_list[i]);
@@ -7823,7 +8540,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find
 
     n_chains = molecule->n_chains;
 
-    for(i = 0; i < n_chains; i++)
+    for(i = n_chains - 1; i >= 0; i--)
     {
         *chain = &molecule->chains[i];
         if(name[0] == 0 || strcmp(name, (*chain)->name) == 0)
@@ -7846,11 +8563,23 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add
                  const char *name,
                  tng_chain_t *chain)
 {
+    int64_t id;
+
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(name, "TNG library: name must not be a NULL pointer.");
 
+    /* Set ID to the ID of the last chain + 1 */
+    if(molecule->n_chains)
+    {
+        id = molecule->chains[molecule->n_chains-1].id + 1;
+    }
+    else
+    {
+        id = 1;
+    }
+
     return(tng_molecule_chain_w_id_add(tng_data, molecule, name,
-                                       molecule->n_chains + 1, chain));
+                                       id, chain));
 }
 
 tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add
@@ -7860,7 +8589,6 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add
                  const int64_t id,
                  tng_chain_t *chain)
 {
-    int64_t i;
     tng_chain_t new_chains;
     tng_function_status stat = TNG_SUCCESS;
 
@@ -7873,7 +8601,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add
 
     if(!new_chains)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_chain) * (molecule->n_chains + 1),
                __FILE__, __LINE__);
         free(molecule->chains);
@@ -7891,16 +8619,6 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add
     (*chain)->molecule = molecule;
     (*chain)->n_residues = 0;
 
-    for(i = molecule->n_chains; i--;)
-    {
-        if(molecule->chains[i].id == id)
-        {
-            stat = TNG_FAILURE;
-            fprintf(stderr, "TNG library: Chain ID already in use. %s: %d\n", __FILE__, __LINE__);
-            break;
-        }
-    }
-
     molecule->n_chains++;
 
     (*chain)->id = id;
@@ -7915,28 +8633,16 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add
                  const int64_t to_atom_id,
                  tng_bond_t *bond)
 {
-    int64_t i;
     tng_bond_t new_bonds;
     (void)tng_data;
 
-    for(i = 0; i < molecule->n_bonds; i++)
-    {
-        *bond = &molecule->bonds[i];
-        /* Check if the bond already exists */
-        if(((*bond)->from_atom_id == from_atom_id && (*bond)->to_atom_id == to_atom_id) ||
-           ((*bond)->to_atom_id == from_atom_id && (*bond)->from_atom_id == to_atom_id))
-        {
-            return(TNG_SUCCESS);
-        }
-    }
-
     new_bonds = realloc(molecule->bonds,
                         sizeof(struct tng_bond) *
                         (molecule->n_bonds + 1));
 
     if(!new_bonds)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_bond) * (molecule->n_bonds + 1),
                __FILE__, __LINE__);
         *bond = 0;
@@ -7971,7 +8677,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_find
 
     n_atoms = molecule->n_atoms;
 
-    for(i = 0; i < n_atoms; i++)
+    for(i = n_atoms - 1; i >= 0; i--)
     {
         *atom = &molecule->atoms[i];
         if(name[0] == 0 || strcmp(name, (*atom)->name) == 0)
@@ -8089,7 +8795,7 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find
 
     n_residues = chain->n_residues;
 
-    for(i = 0; i < n_residues; i++)
+    for(i = n_residues - 1; i >= 0; i--)
     {
         *residue = &chain->residues[i];
         if(name[0] == 0 || strcmp(name, (*residue)->name) == 0)
@@ -8112,11 +8818,23 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add
                  const char *name,
                  tng_residue_t *residue)
 {
+    int64_t id;
+
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(name, "TNG library: name must not be a NULL pointer.");
 
+    /* Set ID to the ID of the last residue + 1 */
+    if(chain->n_residues)
+    {
+        id = chain->residues[chain->n_residues-1].id + 1;
+    }
+    else
+    {
+        id = 0;
+    }
+
     return(tng_chain_residue_w_id_add(tng_data, chain, name,
-                                      chain->n_residues + 1, residue));
+                                      id, residue));
 }
 
 tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
@@ -8126,7 +8844,7 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
                  const int64_t id,
                  tng_residue_t *residue)
 {
-    int64_t i, curr_index;
+    int64_t curr_index;
     tng_residue_t new_residues, temp_residue, last_residue;
     tng_molecule_t molecule = chain->molecule;
     tng_function_status stat = TNG_SUCCESS;
@@ -8149,7 +8867,7 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
 
     if(!new_residues)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_residue) * (molecule->n_residues + 1),
                __FILE__, __LINE__);
         free(molecule->residues);
@@ -8188,6 +8906,10 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
     {
         chain->residues = *residue;
     }
+    else
+    {
+        chain->residues = &molecule->residues[curr_index];
+    }
 
     (*residue)->name = 0;
     tng_residue_name_set(tng_data, *residue, name);
@@ -8196,16 +8918,6 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add
     (*residue)->n_atoms = 0;
     (*residue)->atoms_offset = 0;
 
-    for(i = chain->n_residues; i--;)
-    {
-        if(chain->residues[i].id == id)
-        {
-            stat = TNG_FAILURE;
-            fprintf(stderr, "TNG library: Residue ID already in use. %s: %d\n", __FILE__, __LINE__);
-            break;
-        }
-    }
-
     chain->n_residues++;
     molecule->n_residues++;
 
@@ -8320,13 +9032,24 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add
                  const char *atom_type,
                  tng_atom_t *atom)
 {
+    int64_t id;
+
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(atom_name, "TNG library: atom_name must not be a NULL pointer.");
     TNG_ASSERT(atom_type, "TNG library: atom_type must not be a NULL pointer.");
 
+    /* Set ID to the ID of the last atom + 1 */
+    if(residue->chain->molecule->n_atoms)
+    {
+        id = residue->chain->molecule->atoms[residue->chain->molecule->n_atoms-1].id + 1;
+    }
+    else
+    {
+        id = 0;
+    }
+
     return(tng_residue_atom_w_id_add(tng_data, residue, atom_name, atom_type,
-                                     residue->chain->molecule->n_atoms + 1,
-                                     atom));
+                                     id, atom));
 }
 
 tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add
@@ -8337,7 +9060,6 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add
                  const int64_t id,
                  tng_atom_t *atom)
 {
-    int64_t i;
     tng_atom_t new_atoms;
     tng_molecule_t molecule = residue->chain->molecule;
     tng_function_status stat = TNG_SUCCESS;
@@ -8357,7 +9079,7 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add
 
     if(!new_atoms)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_atom) * (molecule->n_atoms + 1),
                __FILE__, __LINE__);
         free(molecule->atoms);
@@ -8375,16 +9097,6 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add
 
     (*atom)->residue = residue;
 
-    for(i = molecule->n_atoms; i--;)
-    {
-        if(molecule->atoms[i].id == id)
-        {
-            stat = TNG_FAILURE;
-            fprintf(stderr, "TNG library: Atom ID %"PRId64" already in use. %s: %d\n", id, __FILE__, __LINE__);
-            break;
-        }
-    }
-
     residue->n_atoms++;
     molecule->n_atoms++;
 
@@ -8399,7 +9111,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_alloc(const tng_trajectory_t
     *molecule_p = malloc(sizeof(struct tng_molecule));
     if(!*molecule_p)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                sizeof(struct tng_molecule), __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -8457,7 +9169,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy(const tng_trajectory_
 
     if(molecule->chains)
     {
-        for(i = molecule->n_chains; i--;)
+        for(i = 0; i < molecule->n_chains; i++)
         {
             if(molecule->chains[i].name)
             {
@@ -8472,7 +9184,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy(const tng_trajectory_
 
     if(molecule->residues)
     {
-        for(i = molecule->n_residues; i--;)
+        for(i = 0; i < molecule->n_residues; i++)
         {
             if(molecule->residues[i].name)
             {
@@ -8487,7 +9199,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy(const tng_trajectory_
 
     if(molecule->atoms)
     {
-        for(i = molecule->n_atoms; i--;)
+        for(i = 0; i < molecule->n_atoms; i++)
         {
             tng_atom_destroy(&molecule->atoms[i]);
         }
@@ -8631,14 +9343,14 @@ tng_function_status DECLSPECDLLEXPORT tng_molsystem_bonds_get
     *from_atoms = malloc(sizeof(int64_t) * (*n_bonds));
     if(!*from_atoms)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(int64_t) * (*n_bonds), __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
     *to_atoms = malloc(sizeof(int64_t) * (*n_bonds));
     if(!*to_atoms)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(int64_t) * (*n_bonds), __FILE__, __LINE__);
         free(*from_atoms);
         *from_atoms = 0;
@@ -9020,7 +9732,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add
 
     if(!mapping)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(struct tng_particle_mapping)*frame_set->n_mapping_blocks,
                __FILE__, __LINE__);
         free(frame_set->mappings);
@@ -9035,7 +9747,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add
     frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers = malloc(sizeof(int64_t) * n_particles);
     if(!frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(int64_t) * n_particles, __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -9060,7 +9772,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_particle_mapping_free(tng_tr
 
     if(frame_set->n_mapping_blocks && frame_set->mappings)
     {
-        for(i = frame_set->n_mapping_blocks; i--;)
+        for(i = 0; i < frame_set->n_mapping_blocks; i++)
         {
             mapping = &frame_set->mappings[i];
             if(mapping->real_particle_numbers)
@@ -9086,7 +9798,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_init(tng_trajectory_t *tng_
     *tng_data_p = malloc(sizeof(struct tng_trajectory));
     if(!*tng_data_p)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                sizeof(struct tng_trajectory), __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -9130,7 +9842,6 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_init(tng_trajectory_t *tng_
     tng_data->current_trajectory_frame_set_output_file_pos = -1;
     tng_data->frame_set_n_frames = 100;
     tng_data->n_trajectory_frame_sets = 0;
-    tng_data->n_trajectory_blocks = 0;
     tng_data->medium_stride_length = 100;
     tng_data->long_stride_length = 10000;
 
@@ -9268,6 +9979,11 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
 
     if(tng_data->input_file)
     {
+        if(tng_data->output_file == tng_data->input_file)
+        {
+            tng_frame_set_finalize(tng_data, TNG_USE_HASH);
+            tng_data->output_file = 0;
+        }
         fclose(tng_data->input_file);
         tng_data->input_file = 0;
     }
@@ -9359,7 +10075,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
 
     if(tng_data->non_tr_particle_data)
     {
-        for(i = tng_data->n_particle_data_blocks; i--; )
+        for(i = 0; i < tng_data->n_particle_data_blocks; i++)
         {
             if(tng_data->non_tr_particle_data[i].values)
             {
@@ -9373,11 +10089,11 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
                                      n_values_per_frame;
                 if(tng_data->non_tr_particle_data[i].strings[0])
                 {
-                    for(j = n_particles; j--;)
+                    for(j = 0; j < n_particles; j++)
                     {
                         if(tng_data->non_tr_particle_data[i].strings[0][j])
                         {
-                            for(k = n_values_per_frame; k--;)
+                            for(k = 0; k < n_values_per_frame; k++)
                             {
                                 if(tng_data->non_tr_particle_data[i].
                                    strings[0][j][k])
@@ -9412,7 +10128,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
 
     if(tng_data->non_tr_data)
     {
-        for(i = tng_data->n_data_blocks; i--;)
+        for(i = 0; i < tng_data->n_data_blocks; i++)
         {
             if(tng_data->non_tr_data[i].values)
             {
@@ -9426,7 +10142,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
                                      n_values_per_frame;
                 if(tng_data->non_tr_data[i].strings[0])
                 {
-                    for(j = n_values_per_frame; j--;)
+                    for(j = 0; j < n_values_per_frame; j++)
                     {
                         if(tng_data->non_tr_data[i].strings[0][j])
                         {
@@ -9467,7 +10183,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
 
     if(frame_set->tr_particle_data)
     {
-        for(i = frame_set->n_particle_data_blocks; i--; )
+        for(i = 0; i < frame_set->n_particle_data_blocks; i++)
         {
             if(frame_set->tr_particle_data[i].values)
             {
@@ -9479,16 +10195,16 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
             {
                 n_values_per_frame = frame_set->tr_particle_data[i].
                                      n_values_per_frame;
-                for(j = frame_set->tr_particle_data[i].n_frames; j--;)
+                for(j = 0; j < frame_set->tr_particle_data[i].n_frames; j++)
                 {
                     if(frame_set->tr_particle_data[i].strings[j])
                     {
-                        for(k = n_particles; k--;)
+                        for(k = 0; k < n_particles; k++)
                         {
                             if(frame_set->tr_particle_data[i].
                                 strings[j][k])
                             {
-                                for(l = n_values_per_frame; l--;)
+                                for(l = 0; l < n_values_per_frame; l++)
                                 {
                                     if(frame_set->tr_particle_data[i].
                                         strings[j][k][l])
@@ -9525,7 +10241,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
 
     if(frame_set->tr_data)
     {
-        for(i = frame_set->n_data_blocks; i--;)
+        for(i = 0; i < frame_set->n_data_blocks; i++)
         {
             if(frame_set->tr_data[i].values)
             {
@@ -9537,11 +10253,11 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
             {
                 n_values_per_frame = frame_set->tr_data[i].
                                      n_values_per_frame;
-                for(j = frame_set->tr_data[i].n_frames; j--;)
+                for(j = 0; j < frame_set->tr_data[i].n_frames; j++)
                 {
                     if(frame_set->tr_data[i].strings[j])
                     {
-                        for(k = n_values_per_frame; k--;)
+                        for(k = 0; k < n_values_per_frame; k++)
                         {
                             if(frame_set->tr_data[i].strings[j][k])
                             {
@@ -9572,7 +10288,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *t
 
     if(tng_data->molecules)
     {
-        for(i=tng_data->n_molecules; i--;)
+        for(i = 0; i < tng_data->n_molecules; i++)
         {
             tng_molecule_destroy(tng_data, &tng_data->molecules[i]);
         }
@@ -9603,7 +10319,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_init_from_src(tng_trajector
     *dest_p = malloc(sizeof(struct tng_trajectory));
     if(!*dest_p)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n",
                sizeof(struct tng_trajectory), __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -9657,7 +10373,6 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_init_from_src(tng_trajector
     src->current_trajectory_frame_set_output_file_pos;
     dest->frame_set_n_frames = src->frame_set_n_frames;
     dest->n_trajectory_frame_sets = src->n_trajectory_frame_sets;
-    dest->n_trajectory_blocks = src->n_trajectory_blocks;
     dest->medium_stride_length = src->medium_stride_length;
     dest->long_stride_length = src->long_stride_length;
 
@@ -9861,6 +10576,7 @@ tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set
                 tng_data->output_file_path, __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
+    tng_data->input_file = tng_data->output_file;
 
     return(TNG_SUCCESS);
 }
@@ -9950,7 +10666,7 @@ tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_set
 
     /* Tne endianness cannot be changed if the data has already been written
      * to the output file. */
-    if(ftell(tng_data->output_file) > 0)
+    if(ftello(tng_data->output_file) > 0)
     {
         return(TNG_FAILURE);
     }
@@ -10574,14 +11290,13 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frames_get
 {
     tng_gen_block_t block;
     tng_function_status stat;
-    long file_pos;
-    int64_t last_file_pos, first_frame, n_frames;
+    int64_t file_pos, last_file_pos, first_frame, n_frames;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(tng_data->input_file, "TNG library: An input file must be open to find the next frame set");
     TNG_ASSERT(n, "TNG library: n must not be a NULL pointer");
 
-    file_pos = ftell(tng_data->input_file);
+    file_pos = ftello(tng_data->input_file);
     last_file_pos = tng_data->last_trajectory_frame_set_input_file_pos;
 
     if(last_file_pos <= 0)
@@ -10590,9 +11305,9 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frames_get
     }
 
     tng_block_init(&block);
-    fseek(tng_data->input_file,
-          (long)last_file_pos,
-          SEEK_SET);
+    fseeko(tng_data->input_file,
+           last_file_pos,
+           SEEK_SET);
     /* Read block headers first to see that a frame set block is found. */
     stat = tng_block_header_read(tng_data, block);
     if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -10616,7 +11331,7 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frames_get
                __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
-    fseek(tng_data->input_file, file_pos, SEEK_SET);
+    fseeko(tng_data->input_file, file_pos, SEEK_SET);
 
     *n = first_frame + n_frames;
 
@@ -10796,7 +11511,7 @@ tng_function_status DECLSPECDLLEXPORT tng_num_molecules_get
         return(TNG_FAILURE);
     }
 
-    for(i = tng_data->n_molecules; i --;)
+    for(i = 0; i < tng_data->n_molecules; i++)
     {
         cnt += cnt_list[i];
     }
@@ -10879,9 +11594,9 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
                  int64_t *n)
 {
     int64_t long_stride_length, medium_stride_length;
-    long file_pos, orig_frame_set_file_pos;
+    int64_t file_pos, orig_frame_set_file_pos;
     tng_trajectory_frame_set_t frame_set;
-    struct tng_trajectory_frame_set   orig_frame_set;
+    struct tng_trajectory_frame_set orig_frame_set;
     tng_gen_block_t block;
     tng_function_status stat;
     int64_t cnt = 0;
@@ -10894,10 +11609,16 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
     frame_set = &tng_data->current_trajectory_frame_set;
 
     orig_frame_set_file_pos = tng_data->current_trajectory_frame_set_input_file_pos;
-    file_pos = (long)tng_data->first_trajectory_frame_set_input_file_pos;
+    file_pos = tng_data->first_trajectory_frame_set_input_file_pos;
+
+    if(file_pos < 0)
+    {
+        *n = tng_data->n_trajectory_frame_sets = cnt;
+        return(TNG_SUCCESS);
+    }
 
     tng_block_init(&block);
-    fseek(tng_data->input_file,
+    fseeko(tng_data->input_file,
           file_pos,
           SEEK_SET);
     tng_data->current_trajectory_frame_set_input_file_pos = file_pos;
@@ -10905,7 +11626,7 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
     stat = tng_block_header_read(tng_data, block);
     if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n", file_pos,
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", file_pos,
                 __FILE__, __LINE__);
         tng_block_destroy(&block);
         return(TNG_CRITICAL);
@@ -10925,18 +11646,18 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
 
     /* Take long steps forward until a long step forward would be too long or
      * the last frame set is found */
-    file_pos = (long)frame_set->long_stride_next_frame_set_file_pos;
+    file_pos = frame_set->long_stride_next_frame_set_file_pos;
     while(file_pos > 0)
     {
         if(file_pos > 0)
         {
             cnt += long_stride_length;
-            fseek(tng_data->input_file, file_pos, SEEK_SET);
+            fseeko(tng_data->input_file, file_pos, SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
             {
-                fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+                fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                        file_pos, __FILE__, __LINE__);
                 tng_block_destroy(&block);
                 return(TNG_CRITICAL);
@@ -10949,25 +11670,25 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
                 return(TNG_CRITICAL);
             }
         }
-        file_pos = (long)frame_set->long_stride_next_frame_set_file_pos;
+        file_pos = frame_set->long_stride_next_frame_set_file_pos;
     }
 
     /* Take medium steps forward until a medium step forward would be too long
      * or the last frame set is found */
-    file_pos = (long)frame_set->medium_stride_next_frame_set_file_pos;
+    file_pos = frame_set->medium_stride_next_frame_set_file_pos;
     while(file_pos > 0)
     {
         if(file_pos > 0)
         {
             cnt += medium_stride_length;
-            fseek(tng_data->input_file,
+            fseeko(tng_data->input_file,
                   file_pos,
                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
             {
-                fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+                fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                        file_pos, __FILE__, __LINE__);
                 tng_block_destroy(&block);
                 return(TNG_CRITICAL);
@@ -10980,24 +11701,24 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
                 return(TNG_CRITICAL);
             }
         }
-        file_pos = (long)frame_set->medium_stride_next_frame_set_file_pos;
+        file_pos = frame_set->medium_stride_next_frame_set_file_pos;
     }
 
     /* Take one step forward until the last frame set is found */
-    file_pos = (long)frame_set->next_frame_set_file_pos;
+    file_pos = frame_set->next_frame_set_file_pos;
     while(file_pos > 0)
     {
         if(file_pos > 0)
         {
             ++cnt;
-            fseek(tng_data->input_file,
+            fseeko(tng_data->input_file,
                   file_pos,
                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
             {
-                fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+                fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                        file_pos, __FILE__, __LINE__);
                 tng_block_destroy(&block);
                 return(TNG_CRITICAL);
@@ -11010,7 +11731,7 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
                 return(TNG_CRITICAL);
             }
         }
-        file_pos = (long)frame_set->next_frame_set_file_pos;
+        file_pos = frame_set->next_frame_set_file_pos;
     }
 
     tng_block_destroy(&block);
@@ -11018,10 +11739,14 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get
     *n = tng_data->n_trajectory_frame_sets = cnt;
 
     *frame_set = orig_frame_set;
+    /* The mapping block in the original frame set has been freed when reading
+     * other frame sets. */
+    frame_set->mappings = 0;
+    frame_set->n_mapping_blocks = 0;
 
-    fseek(tng_data->input_file,
-          (long)tng_data->first_trajectory_frame_set_input_file_pos,
-          SEEK_SET);
+    fseeko(tng_data->input_file,
+           tng_data->first_trajectory_frame_set_input_file_pos,
+           SEEK_SET);
 
     tng_data->current_trajectory_frame_set_input_file_pos = orig_frame_set_file_pos;
 
@@ -11088,10 +11813,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
     }
 
     tng_block_init(&block);
-    fseek(tng_data->input_file,
-          (long)file_pos,
-          SEEK_SET);
-    tng_data->current_trajectory_frame_set_input_file_pos = (long)file_pos;
+    fseeko(tng_data->input_file,
+           file_pos,
+           SEEK_SET);
+    tng_data->current_trajectory_frame_set_input_file_pos = file_pos;
     /* Read block headers first to see what block is found. */
     stat = tng_block_header_read(tng_data, block);
     if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11125,7 +11850,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             curr_nr += long_stride_length;
-            fseek(tng_data->input_file, (long)file_pos, SEEK_SET);
+            fseeko(tng_data->input_file, file_pos, SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11137,7 +11862,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
             }
 
             if(tng_block_read_next(tng_data, block,
-                                TNG_SKIP_HASH) != TNG_SUCCESS)
+                                   TNG_SKIP_HASH) != TNG_SUCCESS)
             {
                 tng_block_destroy(&block);
                 return(TNG_CRITICAL);
@@ -11158,9 +11883,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             curr_nr += medium_stride_length;
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11193,9 +11918,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             ++curr_nr;
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11228,9 +11953,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             curr_nr -= long_stride_length;
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11263,9 +11988,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             curr_nr -= medium_stride_length;
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11297,9 +12022,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             --curr_nr;
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11332,9 +12057,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find
         if(file_pos > 0)
         {
             ++curr_nr;
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11384,10 +12109,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
     if(tng_data->current_trajectory_frame_set_input_file_pos < 0)
     {
         file_pos = tng_data->first_trajectory_frame_set_input_file_pos;
-        fseek(tng_data->input_file,
-                (long)file_pos,
-                SEEK_SET);
-        tng_data->current_trajectory_frame_set_input_file_pos = (long)file_pos;
+        fseeko(tng_data->input_file,
+               file_pos,
+               SEEK_SET);
+        tng_data->current_trajectory_frame_set_input_file_pos = file_pos;
         /* Read block headers first to see what block is found. */
         stat = tng_block_header_read(tng_data, block);
         if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11467,10 +12192,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
 
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
-            tng_data->current_trajectory_frame_set_input_file_pos = (long)file_pos;
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
+            tng_data->current_trajectory_frame_set_input_file_pos = file_pos;
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11509,7 +12234,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->long_stride_next_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file, (long)file_pos, SEEK_SET);
+            fseeko(tng_data->input_file, file_pos, SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11544,9 +12269,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->medium_stride_next_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11579,9 +12304,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->next_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11616,9 +12341,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->long_stride_prev_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11653,9 +12378,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->medium_stride_prev_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11688,9 +12413,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->prev_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11724,9 +12449,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find
         file_pos = frame_set->next_frame_set_file_pos;
         if(file_pos > 0)
         {
-            fseek(tng_data->input_file,
-                  (long)file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   file_pos,
+                   SEEK_SET);
             /* Read block headers first to see what block is found. */
             stat = tng_block_header_read(tng_data, block);
             if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
@@ -11877,11 +12602,55 @@ static TNG_INLINE tng_function_status tng_particle_mapping_get_real_particle
 }
 */
 
+static tng_function_status tng_file_headers_len_get
+                (tng_trajectory_t tng_data,
+                 int64_t *len)
+{
+    int64_t orig_pos;
+    tng_gen_block_t block;
+
+    TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
+
+    if(tng_input_file_init(tng_data) != TNG_SUCCESS)
+    {
+        return(TNG_CRITICAL);
+    }
+
+    *len = 0;
+
+    orig_pos = ftello(tng_data->input_file);
+
+    if(!tng_data->input_file_len)
+    {
+        fseeko(tng_data->input_file, 0, SEEK_END);
+        tng_data->input_file_len = ftello(tng_data->input_file);
+    }
+    fseeko(tng_data->input_file, 0, SEEK_SET);
+
+    tng_block_init(&block);
+    /* Read through the headers of non-trajectory blocks (they come before the
+     * trajectory blocks in the file) */
+    while (*len < tng_data->input_file_len &&
+           tng_block_header_read(tng_data, block) != TNG_CRITICAL &&
+           block->id != -1 &&
+           block->id != TNG_TRAJECTORY_FRAME_SET)
+    {
+        *len += block->header_contents_size + block->block_contents_size;
+        fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
+    }
+
+    fseeko(tng_data->input_file, orig_pos, SEEK_SET);
+
+    tng_block_destroy(&block);
+
+    return(TNG_SUCCESS);
+}
+
 tng_function_status DECLSPECDLLEXPORT tng_file_headers_read
                 (tng_trajectory_t tng_data,
                  const char hash_mode)
 {
-    int cnt = 0, prev_pos = 0;
+    int64_t prev_pos = 0;
     tng_gen_block_t block;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
@@ -11895,10 +12664,10 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_read
 
     if(!tng_data->input_file_len)
     {
-        fseek(tng_data->input_file, 0, SEEK_END);
-        tng_data->input_file_len = ftell(tng_data->input_file);
-        fseek(tng_data->input_file, 0, SEEK_SET);
+        fseeko(tng_data->input_file, 0, SEEK_END);
+        tng_data->input_file_len = ftello(tng_data->input_file);
     }
+    fseeko(tng_data->input_file, 0, SEEK_SET);
 
     tng_block_init(&block);
     /* Non trajectory blocks (they come before the trajectory
@@ -11908,18 +12677,14 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_read
            block->id != -1 &&
            block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        if(tng_block_read_next(tng_data, block,
-                               hash_mode) == TNG_SUCCESS)
-        {
-            cnt++;
-        }
-        prev_pos = ftell(tng_data->input_file);
+        tng_block_read_next(tng_data, block, hash_mode);
+        prev_pos = ftello(tng_data->input_file);
     }
 
     /* Go back if a trajectory block was encountered */
     if(block->id == TNG_TRAJECTORY_FRAME_SET)
     {
-        fseek(tng_data->input_file, prev_pos, SEEK_SET);
+        fseeko(tng_data->input_file, prev_pos, SEEK_SET);
     }
 
     tng_block_destroy(&block);
@@ -11932,7 +12697,9 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_write
                  const char hash_mode)
 {
     int i;
-    tng_gen_block_t data_block;
+    int64_t len, orig_len, tot_len = 0, data_start_pos;
+    tng_function_status stat;
+    tng_gen_block_t block;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
 
@@ -11941,6 +12708,69 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_write
         return(TNG_CRITICAL);
     }
 
+    if(tng_data->n_trajectory_frame_sets > 0)
+    {
+        stat = tng_file_headers_len_get(tng_data, &orig_len);
+        if(stat != TNG_SUCCESS)
+        {
+            return(stat);
+        }
+
+        tng_block_init(&block);
+        block->name = malloc(TNG_MAX_STR_LEN);
+        if(!block->name)
+        {
+            fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n",
+                    TNG_MAX_STR_LEN, __FILE__, __LINE__);
+            tng_block_destroy(&block);
+            return(TNG_CRITICAL);
+        }
+        strcpy(block->name, "GENERAL INFO");
+        tng_block_header_len_calculate(tng_data, block, &len);
+        tot_len += len;
+        tng_general_info_block_len_calculate(tng_data, &len);
+        tot_len += len;
+        strcpy(block->name, "MOLECULES");
+        tng_block_header_len_calculate(tng_data, block, &len);
+        tot_len += len;
+        tng_molecules_block_len_calculate(tng_data, &len);
+        tot_len += len;
+
+        for(i = 0; i < tng_data->n_data_blocks; i++)
+        {
+            strcpy(block->name, tng_data->non_tr_data[i].block_name);
+            tng_block_header_len_calculate(tng_data, block, &len);
+            tot_len += len;
+            tng_data_block_len_calculate(tng_data,
+                                        (tng_particle_data_t)&tng_data->non_tr_data[i],
+                                        TNG_FALSE, 1, 1, 1, 0,
+                                        1, 0, &data_start_pos,
+                                        &len);
+            tot_len += len;
+        }
+        for(i = 0; i < tng_data->n_particle_data_blocks; i++)
+        {
+            strcpy(block->name, tng_data->non_tr_particle_data[i].block_name);
+            tng_block_header_len_calculate(tng_data, block, &len);
+            tot_len += len;
+            tng_data_block_len_calculate(tng_data,
+                                        &tng_data->non_tr_particle_data[i],
+                                        TNG_TRUE, 1, 1, 1, 0,
+                                        tng_data->n_particles, TNG_PARTICLE_DEPENDENT,
+                                        &data_start_pos,
+                                        &len);
+            tot_len += len;
+        }
+        tng_block_destroy(&block);
+
+        if(tot_len > orig_len)
+        {
+            tng_migrate_data_in_file(tng_data, orig_len+1, tot_len - orig_len);
+        }
+
+        tng_data->current_trajectory_frame_set_output_file_pos = -1;
+    }
+
     /* TODO: If there is already frame set data written to this file (e.g. when
      * appending to an already existing file we might need to move frame sets to
      * the end of the file. */
@@ -11963,22 +12793,22 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_write
 
     /* FIXME: Currently writing non-trajectory data blocks here.
      * Should perhaps be moved. */
-    tng_block_init(&data_block);
+    tng_block_init(&block);
     for(i = 0; i < tng_data->n_data_blocks; i++)
     {
-        data_block->id = tng_data->non_tr_data[i].block_id;
-        tng_data_block_write(tng_data, data_block,
+        block->id = tng_data->non_tr_data[i].block_id;
+        tng_data_block_write(tng_data, block,
                              i, hash_mode);
     }
 
     for(i = 0; i < tng_data->n_particle_data_blocks; i++)
     {
-        data_block->id = tng_data->non_tr_particle_data[i].block_id;
-        tng_particle_data_block_write(tng_data, data_block,
+        block->id = tng_data->non_tr_particle_data[i].block_id;
+        tng_particle_data_block_write(tng_data, block,
                                       i, 0, hash_mode);
     }
 
-    tng_block_destroy(&data_block);
+    tng_block_destroy(&block);
 
     return(TNG_SUCCESS);
 }
@@ -12008,7 +12838,7 @@ tng_function_status DECLSPECDLLEXPORT tng_block_read_next(tng_trajectory_t tng_d
         else
         {
             /* Skip to the next block */
-            fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+            fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
             return(TNG_FAILURE);
         }
     }
@@ -12018,7 +12848,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
                 (tng_trajectory_t tng_data,
                  const char hash_mode)
 {
-    long file_pos;
+    int64_t file_pos;
     tng_gen_block_t block;
     tng_function_status stat;
 
@@ -12029,22 +12859,23 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
         return(TNG_CRITICAL);
     }
 
-    file_pos = ftell(tng_data->input_file);
+    file_pos = ftello(tng_data->input_file);
 
     tng_block_init(&block);
 
     if(!tng_data->input_file_len)
     {
-        fseek(tng_data->input_file, 0, SEEK_END);
-        tng_data->input_file_len = ftell(tng_data->input_file);
-        fseek(tng_data->input_file, file_pos, SEEK_SET);
+        fseeko(tng_data->input_file, 0, SEEK_END);
+        tng_data->input_file_len = ftello(tng_data->input_file);
+        fseeko(tng_data->input_file, file_pos, SEEK_SET);
     }
 
     /* Read block headers first to see what block is found. */
     stat = tng_block_header_read(tng_data, block);
-    if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
+    if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET ||
+       block->id == -1)
     {
-        fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                file_pos, __FILE__, __LINE__);
         tng_block_destroy(&block);
         return(TNG_CRITICAL);
@@ -12056,18 +12887,19 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
                            hash_mode) == TNG_SUCCESS)
     {
         tng_data->n_trajectory_frame_sets++;
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
               stat != TNG_CRITICAL &&
-              block->id != TNG_TRAJECTORY_FRAME_SET)
+              block->id != TNG_TRAJECTORY_FRAME_SET &&
+              block->id != -1)
         {
             stat = tng_block_read_next(tng_data, block,
                                        hash_mode);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -12076,7 +12908,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
         }
         if(stat == TNG_CRITICAL)
         {
-            fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                    file_pos, __FILE__, __LINE__);
             tng_block_destroy(&block);
             return(stat);
@@ -12084,7 +12916,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read
 
         if(block->id == TNG_TRAJECTORY_FRAME_SET)
         {
-            fseek(tng_data->input_file, file_pos, SEEK_SET);
+            fseeko(tng_data->input_file, file_pos, SEEK_SET);
         }
     }
 
@@ -12099,7 +12931,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
                  const char hash_mode,
                  const int64_t block_id)
 {
-    long file_pos;
+    int64_t file_pos;
     tng_gen_block_t block;
     tng_function_status stat;
     int found_flag = 1;
@@ -12111,19 +12943,19 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
         return(TNG_CRITICAL);
     }
 
-    file_pos = (long)tng_data->current_trajectory_frame_set_input_file_pos;
+    file_pos = tng_data->current_trajectory_frame_set_input_file_pos;
 
     if(file_pos < 0)
     {
         /* No current frame set. This means that the first frame set must be
          * read */
         found_flag = 0;
-        file_pos = (long)tng_data->first_trajectory_frame_set_input_file_pos;
+        file_pos = tng_data->first_trajectory_frame_set_input_file_pos;
     }
 
     if(file_pos > 0)
     {
-        fseek(tng_data->input_file,
+        fseeko(tng_data->input_file,
               file_pos,
               SEEK_SET);
     }
@@ -12136,16 +12968,16 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
 
     if(!tng_data->input_file_len)
     {
-        fseek(tng_data->input_file, 0, SEEK_END);
-        tng_data->input_file_len = ftell(tng_data->input_file);
-        fseek(tng_data->input_file, file_pos, SEEK_SET);
+        fseeko(tng_data->input_file, 0, SEEK_END);
+        tng_data->input_file_len = ftello(tng_data->input_file);
+        fseeko(tng_data->input_file, file_pos, SEEK_SET);
     }
 
     /* Read block headers first to see what block is found. */
     stat = tng_block_header_read(tng_data, block);
     if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                file_pos, __FILE__, __LINE__);
         tng_block_destroy(&block);
         return(TNG_CRITICAL);
@@ -12153,7 +12985,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
     /* If the current frame set had already been read skip its block contents */
     if(found_flag)
     {
-        fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+        fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
     }
     /* Otherwiese read the frame set block */
     else
@@ -12167,7 +12999,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
             return(stat);
         }
     }
-    file_pos = ftell(tng_data->input_file);
+    file_pos = ftello(tng_data->input_file);
 
     found_flag = 0;
 
@@ -12176,7 +13008,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
     stat = tng_block_header_read(tng_data, block);
     while(file_pos < tng_data->input_file_len &&
             stat != TNG_CRITICAL &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+            block->id != TNG_TRAJECTORY_FRAME_SET &&
+            block->id != -1)
     {
         if(block->id == block_id)
         {
@@ -12184,7 +13017,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
                                        hash_mode);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 found_flag = 1;
                 if(file_pos < tng_data->input_file_len)
                 {
@@ -12194,8 +13027,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
         }
         else
         {
-            file_pos += (long)(block->block_contents_size + block->header_contents_size);
-            fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+            file_pos += (block->block_contents_size + block->header_contents_size);
+            fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
             if(file_pos < tng_data->input_file_len)
             {
                 stat = tng_block_header_read(tng_data, block);
@@ -12204,7 +13037,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
     }
     if(stat == TNG_CRITICAL)
     {
-        fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                 file_pos, __FILE__, __LINE__);
         tng_block_destroy(&block);
         return(stat);
@@ -12212,7 +13045,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_
 
     if(block->id == TNG_TRAJECTORY_FRAME_SET)
     {
-        fseek(tng_data->input_file, file_pos, SEEK_SET);
+        fseeko(tng_data->input_file, file_pos, SEEK_SET);
     }
 
     tng_block_destroy(&block);
@@ -12231,7 +13064,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next
                 (tng_trajectory_t tng_data,
                  const char hash_mode)
 {
-    long file_pos;
+    int64_t file_pos;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
 
@@ -12240,16 +13073,16 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next
         return(TNG_CRITICAL);
     }
 
-    file_pos = (long)tng_data->current_trajectory_frame_set.next_frame_set_file_pos;
+    file_pos = tng_data->current_trajectory_frame_set.next_frame_set_file_pos;
 
     if(file_pos < 0 && tng_data->current_trajectory_frame_set_input_file_pos <= 0)
     {
-        file_pos = (long)tng_data->first_trajectory_frame_set_input_file_pos;
+        file_pos = tng_data->first_trajectory_frame_set_input_file_pos;
     }
 
     if(file_pos > 0)
     {
-        fseek(tng_data->input_file,
+        fseeko(tng_data->input_file,
               file_pos,
               SEEK_SET);
     }
@@ -12266,7 +13099,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_blo
                  const char hash_mode,
                  const int64_t block_id)
 {
-    long file_pos;
+    int64_t file_pos;
     tng_gen_block_t block;
     tng_function_status stat;
 
@@ -12277,16 +13110,16 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_blo
         return(TNG_CRITICAL);
     }
 
-    file_pos = (long)tng_data->current_trajectory_frame_set.next_frame_set_file_pos;
+    file_pos = tng_data->current_trajectory_frame_set.next_frame_set_file_pos;
 
     if(file_pos < 0 && tng_data->current_trajectory_frame_set_input_file_pos <= 0)
     {
-        file_pos = (long)tng_data->first_trajectory_frame_set_input_file_pos;
+        file_pos = tng_data->first_trajectory_frame_set_input_file_pos;
     }
 
     if(file_pos > 0)
     {
-        fseek(tng_data->input_file,
+        fseeko(tng_data->input_file,
               file_pos,
               SEEK_SET);
     }
@@ -12299,16 +13132,16 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_blo
 
     if(!tng_data->input_file_len)
     {
-        fseek(tng_data->input_file, 0, SEEK_END);
-        tng_data->input_file_len = ftell(tng_data->input_file);
-        fseek(tng_data->input_file, file_pos, SEEK_SET);
+        fseeko(tng_data->input_file, 0, SEEK_END);
+        tng_data->input_file_len = ftello(tng_data->input_file);
+        fseeko(tng_data->input_file, file_pos, SEEK_SET);
     }
 
     /* Read block headers first to see what block is found. */
     stat = tng_block_header_read(tng_data, block);
     if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                file_pos, __FILE__, __LINE__);
         tng_block_destroy(&block);
         return(TNG_CRITICAL);
@@ -12345,7 +13178,7 @@ tng_function_status tng_frame_set_write(tng_trajectory_t tng_data,
     }
 
     tng_data->current_trajectory_frame_set_output_file_pos =
-    ftell(tng_data->output_file);
+    ftello(tng_data->output_file);
     tng_data->last_trajectory_frame_set_output_file_pos =
     tng_data->current_trajectory_frame_set_output_file_pos;
 
@@ -12456,7 +13289,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
 
     frame_set = &tng_data->current_trajectory_frame_set;
 
-    curr_pos = ftell(tng_data->output_file);
+    curr_pos = ftello(tng_data->output_file);
 
     if(curr_pos <= 10)
     {
@@ -12474,7 +13307,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
     }
 
     tng_data->current_trajectory_frame_set_output_file_pos =
-    ftell(tng_data->output_file);
+    ftello(tng_data->output_file);
 
     tng_data->n_trajectory_frame_sets++;
 
@@ -12494,10 +13327,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
             tng_block_init(&block);
             tng_data->input_file = tng_data->output_file;
 
-            curr_pos = ftell(tng_data->output_file);
-            fseek(tng_data->output_file,
-                  (long)frame_set->medium_stride_prev_frame_set_file_pos,
-                  SEEK_SET);
+            curr_pos = ftello(tng_data->output_file);
+            fseeko(tng_data->output_file,
+                   frame_set->medium_stride_prev_frame_set_file_pos,
+                   SEEK_SET);
 
             if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
             {
@@ -12510,8 +13343,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
 
             /* Read the next frame set from the previous frame set and one
              * medium stride step back */
-            fseek(tng_data->output_file, (long)block->block_contents_size - 6 *
-                sizeof(int64_t), SEEK_CUR);
+            fseeko(tng_data->output_file, block->block_contents_size - (6 *
+            sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
             if(fread(&frame_set->medium_stride_prev_frame_set_file_pos,
                sizeof(frame_set->medium_stride_prev_frame_set_file_pos),
                1, tng_data->output_file) == 0)
@@ -12551,9 +13384,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
                     tng_block_init(&block);
                     tng_data->input_file = tng_data->output_file;
 
-                    fseek(tng_data->output_file,
-                          (long)frame_set->long_stride_prev_frame_set_file_pos,
-                          SEEK_SET);
+                    fseeko(tng_data->output_file,
+                           frame_set->long_stride_prev_frame_set_file_pos,
+                           SEEK_SET);
 
                     if(tng_block_header_read(tng_data, block) != TNG_SUCCESS)
                     {
@@ -12566,8 +13399,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
 
                     /* Read the next frame set from the previous frame set and one
                     * long stride step back */
-                    fseek(tng_data->output_file, (long)block->block_contents_size - 6 *
-                          sizeof(int64_t), SEEK_CUR);
+                    fseeko(tng_data->output_file, block->block_contents_size - (6 *
+                          sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR);
 
                     tng_block_destroy(&block);
 
@@ -12595,7 +13428,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new
             }
 
             tng_data->input_file = temp;
-            fseek(tng_data->output_file, (long)curr_pos, SEEK_SET);
+            fseeko(tng_data->output_file, curr_pos, SEEK_SET);
         }
     }
 
@@ -12665,7 +13498,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get
                 (const tng_trajectory_t tng_data,
                  int64_t *frame)
 {
-    long file_pos, next_frame_set_file_pos;
+    int64_t file_pos, next_frame_set_file_pos;
     tng_gen_block_t block;
     tng_function_status stat;
 
@@ -12675,16 +13508,16 @@ tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get
     TNG_ASSERT(tng_data->input_file, "TNG library: An input file must be open to find the next frame set");
     TNG_ASSERT(frame, "TNG library: frame must not be a NULL pointer");
 
-    file_pos = ftell(tng_data->input_file);
+    file_pos = ftello(tng_data->input_file);
 
     if(tng_data->current_trajectory_frame_set_input_file_pos <= 0)
     {
-        next_frame_set_file_pos = (long)tng_data->first_trajectory_frame_set_input_file_pos;
+        next_frame_set_file_pos = tng_data->first_trajectory_frame_set_input_file_pos;
     }
     else
     {
         frame_set = &tng_data->current_trajectory_frame_set;
-        next_frame_set_file_pos = (long)frame_set->next_frame_set_file_pos;
+        next_frame_set_file_pos = frame_set->next_frame_set_file_pos;
     }
 
     if(next_frame_set_file_pos <= 0)
@@ -12692,13 +13525,13 @@ tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get
         return(TNG_FAILURE);
     }
 
-    fseek(tng_data->input_file, (long)next_frame_set_file_pos, SEEK_SET);
+    fseeko(tng_data->input_file, next_frame_set_file_pos, SEEK_SET);
     /* Read block headers first to see that a frame set block is found. */
     tng_block_init(&block);
     stat = tng_block_header_read(tng_data, block);
     if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET)
     {
-        fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
                file_pos, __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
@@ -12714,7 +13547,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get
                __FILE__, __LINE__);
         return(TNG_CRITICAL);
     }
-    fseek(tng_data->input_file, file_pos, SEEK_SET);
+    fseeko(tng_data->input_file, file_pos, SEEK_SET);
 
     return(TNG_SUCCESS);
 }
@@ -13294,8 +14127,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
     int64_t header_pos, file_pos;
     int64_t output_file_len, n_values_per_frame, size, contents_size;
     int64_t header_size, temp_first, temp_last;
-    int64_t i, last_frame;
-    long temp_current;
+    int64_t i, last_frame, temp_current;
     tng_gen_block_t block;
     tng_trajectory_frame_set_t frame_set;
     FILE *temp = tng_data->input_file;
@@ -13350,10 +14182,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
             tng_frame_set_new(tng_data,
                               last_frame+1,
                               tng_data->frame_set_n_frames);
-            file_pos = ftell(tng_data->output_file);
-            fseek(tng_data->output_file, 0, SEEK_END);
-            output_file_len = ftell(tng_data->output_file);
-            fseek(tng_data->output_file, (long)file_pos, SEEK_SET);
+            file_pos = ftello(tng_data->output_file);
+            fseeko(tng_data->output_file, 0, SEEK_END);
+            output_file_len = ftello(tng_data->output_file);
+            fseeko(tng_data->output_file, file_pos, SEEK_SET);
 
             /* Read mapping blocks from the last frame set */
             tng_block_init(&block);
@@ -13361,7 +14193,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
             stat = tng_block_header_read(tng_data, block);
             while(file_pos < output_file_len &&
                   stat != TNG_CRITICAL &&
-                  block->id != TNG_TRAJECTORY_FRAME_SET)
+                  block->id != TNG_TRAJECTORY_FRAME_SET &&
+                  block->id != -1)
             {
                 if(block->id == TNG_PARTICLE_MAPPING)
                 {
@@ -13370,10 +14203,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
                 }
                 else
                 {
-                    fseek(tng_data->output_file, (long)block->block_contents_size,
-                        SEEK_CUR);
+                    fseeko(tng_data->output_file, block->block_contents_size,
+                           SEEK_CUR);
                 }
-                file_pos = ftell(tng_data->output_file);
+                file_pos = ftello(tng_data->output_file);
                 if(file_pos < output_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -13402,9 +14235,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
 
     file_pos = tng_data->current_trajectory_frame_set_output_file_pos;
 
-    fseek(tng_data->output_file, 0, SEEK_END);
-    output_file_len = ftell(tng_data->output_file);
-    fseek(tng_data->output_file, (long)file_pos, SEEK_SET);
+    fseeko(tng_data->output_file, 0, SEEK_END);
+    output_file_len = ftello(tng_data->output_file);
+    fseeko(tng_data->output_file, file_pos, SEEK_SET);
 
     /* Read past the frame set block first */
     stat = tng_block_header_read(tng_data, block);
@@ -13420,8 +14253,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
         tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
         return(stat);
     }
-    fseek(tng_data->output_file, (long)block->block_contents_size,
-            SEEK_CUR);
+    fseeko(tng_data->output_file, block->block_contents_size,
+           SEEK_CUR);
 
     /* Read all block headers until next frame set block or
      * until the wanted block id is found */
@@ -13429,10 +14262,11 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
     while(file_pos < output_file_len &&
             stat != TNG_CRITICAL &&
             block->id != block_id &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+            block->id != TNG_TRAJECTORY_FRAME_SET &&
+            block->id != -1)
     {
-        fseek(tng_data->output_file, (long)block->block_contents_size, SEEK_CUR);
-        file_pos = ftell(tng_data->output_file);
+        fseeko(tng_data->output_file, block->block_contents_size, SEEK_CUR);
+        file_pos = ftello(tng_data->output_file);
         if(file_pos < output_file_len)
         {
             stat = tng_block_header_read(tng_data, block);
@@ -13453,7 +14287,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
     contents_size = block->block_contents_size;
     header_size = block->header_contents_size;
 
-    header_pos = ftell(tng_data->output_file) - header_size;
+    header_pos = ftello(tng_data->output_file) - header_size;
     frame_set = &tng_data->current_trajectory_frame_set;
 
     if(fread(&datatype, sizeof(datatype), 1, tng_data->input_file) == 0)
@@ -13635,7 +14469,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write
         return(TNG_FAILURE);
     }
 
-    fseek(tng_data->output_file, (long)file_pos, SEEK_CUR);
+    fseeko(tng_data->output_file, file_pos, SEEK_CUR);
 
     /* If the endianness is not big endian the data needs to be swapped */
     if((data.datatype == TNG_INT_DATA ||
@@ -13718,8 +14552,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
     int64_t output_file_len, n_values_per_frame, size, contents_size;
     int64_t header_size, temp_first, temp_last;
     int64_t mapping_block_end_pos, num_first_particle, block_n_particles;
-    int64_t i, last_frame;
-    long temp_current;
+    int64_t i, last_frame, temp_current;
     tng_gen_block_t block;
     tng_trajectory_frame_set_t frame_set;
     FILE *temp = tng_data->input_file;
@@ -13778,10 +14611,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
                               last_frame+1,
                               tng_data->frame_set_n_frames);
 
-            file_pos = ftell(tng_data->output_file);
-            fseek(tng_data->output_file, 0, SEEK_END);
-            output_file_len = ftell(tng_data->output_file);
-            fseek(tng_data->output_file, (long)file_pos, SEEK_SET);
+            file_pos = ftello(tng_data->output_file);
+            fseeko(tng_data->output_file, 0, SEEK_END);
+            output_file_len = ftello(tng_data->output_file);
+            fseeko(tng_data->output_file, file_pos, SEEK_SET);
 
             /* Read mapping blocks from the last frame set */
             tng_block_init(&block);
@@ -13789,7 +14622,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
             stat = tng_block_header_read(tng_data, block);
             while(file_pos < output_file_len &&
                   stat != TNG_CRITICAL &&
-                  block->id != TNG_TRAJECTORY_FRAME_SET)
+                  block->id != TNG_TRAJECTORY_FRAME_SET &&
+                  block->id != -1)
             {
                 if(block->id == TNG_PARTICLE_MAPPING)
                 {
@@ -13798,10 +14632,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
                 }
                 else
                 {
-                    fseek(tng_data->output_file, (long)block->block_contents_size,
+                    fseeko(tng_data->output_file, block->block_contents_size,
                         SEEK_CUR);
                 }
-                file_pos = ftell(tng_data->output_file);
+                file_pos = ftello(tng_data->output_file);
                 if(file_pos < output_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -13831,9 +14665,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
 
     file_pos = tng_data->current_trajectory_frame_set_output_file_pos;
 
-    fseek(tng_data->output_file, 0, SEEK_END);
-    output_file_len = ftell(tng_data->output_file);
-    fseek(tng_data->output_file, (long)file_pos, SEEK_SET);
+    fseeko(tng_data->output_file, 0, SEEK_END);
+    output_file_len = ftello(tng_data->output_file);
+    fseeko(tng_data->output_file, file_pos, SEEK_SET);
 
     /* Read past the frame set block first */
     stat = tng_block_header_read(tng_data, block);
@@ -13849,7 +14683,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
         tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
         return(stat);
     }
-    fseek(tng_data->output_file, (long)block->block_contents_size,
+    fseeko(tng_data->output_file, block->block_contents_size,
             SEEK_CUR);
 
     if(tng_data->var_num_atoms_flag)
@@ -13868,7 +14702,8 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < output_file_len &&
                 stat != TNG_CRITICAL &&
-                block->id != TNG_TRAJECTORY_FRAME_SET)
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
         {
             if(block->id == TNG_PARTICLE_MAPPING)
             {
@@ -13876,10 +14711,10 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
             }
             else
             {
-                fseek(tng_data->output_file, (long)block->block_contents_size,
+                fseeko(tng_data->output_file, block->block_contents_size,
                       SEEK_CUR);
             }
-            file_pos = ftell(tng_data->output_file);
+            file_pos = ftello(tng_data->output_file);
             if(block->id == TNG_PARTICLE_MAPPING)
             {
                 mapping = &frame_set->mappings[frame_set->n_mapping_blocks - 1];
@@ -13919,7 +14754,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
             tng_data->current_trajectory_frame_set_input_file_pos = temp_current;
             return(TNG_FAILURE);
         }
-        fseek(tng_data->output_file, (long)mapping_block_end_pos, SEEK_SET);
+        fseeko(tng_data->output_file, mapping_block_end_pos, SEEK_SET);
     }
 
     /* Read all block headers until next frame set block or
@@ -13929,10 +14764,11 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
             stat != TNG_CRITICAL &&
             block->id != block_id &&
             block->id != TNG_PARTICLE_MAPPING &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+            block->id != TNG_TRAJECTORY_FRAME_SET &&
+            block->id != -1)
     {
-        fseek(tng_data->output_file, (long)block->block_contents_size, SEEK_CUR);
-        file_pos = ftell(tng_data->output_file);
+        fseeko(tng_data->output_file, block->block_contents_size, SEEK_CUR);
+        file_pos = ftello(tng_data->output_file);
         if(file_pos < output_file_len)
         {
             stat = tng_block_header_read(tng_data, block);
@@ -13954,7 +14790,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
     contents_size = block->block_contents_size;
     header_size = block->header_contents_size;
 
-    header_pos = ftell(tng_data->output_file) - header_size;
+    header_pos = ftello(tng_data->output_file) - header_size;
     frame_set = &tng_data->current_trajectory_frame_set;
 
     if(fread(&datatype, sizeof(datatype), 1, tng_data->input_file) == 0)
@@ -14178,7 +15014,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write
         return(TNG_FAILURE);
     }
 
-    fseek(tng_data->output_file, (long)file_pos, SEEK_CUR);
+    fseeko(tng_data->output_file, file_pos, SEEK_CUR);
 
     /* If the endianness is not big endian the data needs to be swapped */
     if((data.datatype == TNG_INT_DATA ||
@@ -14277,20 +15113,20 @@ static tng_function_status tng_data_values_alloc
     *values = malloc(sizeof(union data_values *) * n_frames);
     if(!*values)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(union data_values **) * n_frames,
                __FILE__, __LINE__);
         return(TNG_CRITICAL);
 
     }
 
-    for(i = n_frames; i--;)
+    for(i = 0; i < n_frames; i++)
     {
         (*values)[i] = malloc(sizeof(union data_values) *
                            n_values_per_frame);
         if(!(*values)[i])
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                    sizeof(union data_values) * n_values_per_frame,
                    __FILE__, __LINE__);
             free(values);
@@ -14320,7 +15156,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_values_free
             {
                 if(type == TNG_CHAR_DATA)
                 {
-                    for(j = n_values_per_frame; j--;)
+                    for(j = 0; j < n_values_per_frame; j++)
                     {
                         if(values[i][j].c)
                         {
@@ -14371,33 +15207,33 @@ static tng_function_status tng_particle_data_values_alloc
     *values = malloc(sizeof(union data_values **) * n_frames);
     if(!*values)
     {
-        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+        fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                sizeof(union data_values **) * n_frames,
                __FILE__, __LINE__);
         return(TNG_CRITICAL);
 
     }
 
-    for(i = n_frames; i--;)
+    for(i = 0; i < n_frames; i++)
     {
         (*values)[i] = malloc(sizeof(union data_values *) *
                            n_particles);
         if(!(*values)[i])
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                    sizeof(union data_values *) * n_particles,
                    __FILE__, __LINE__);
             free(*values);
             *values = 0;
             return(TNG_CRITICAL);
         }
-        for(j = n_particles; j--;)
+        for(j = 0; j < n_particles; j++)
         {
             (*values)[i][j] = malloc(sizeof(union data_values) *
                                   n_values_per_frame);
             if(!(*values)[i][j])
             {
-                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                     sizeof(union data_values *) * n_particles,
                     __FILE__, __LINE__);
                 tng_particle_data_values_free(tng_data, *values, n_frames,
@@ -14433,7 +15269,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free
                 {
                     if(type == TNG_CHAR_DATA)
                     {
-                        for(k = n_values_per_frame; k--;)
+                        for(k = 0; k < n_values_per_frame; k++)
                         {
                             if(values[i][j][k].c)
                             {
@@ -14486,19 +15322,20 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get
     if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS)
     {
         tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
                 stat != TNG_CRITICAL &&
-                block->id != TNG_TRAJECTORY_FRAME_SET)
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
         {
             /* Use hash by default */
             stat = tng_block_read_next(tng_data, block,
                                     TNG_USE_HASH);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -14513,7 +15350,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get
             return(stat);
         }
 
-        for(i = frame_set->n_data_blocks; i-- ;)
+        for(i = 0; i < frame_set->n_data_blocks; i++)
         {
             data = &frame_set->tr_data[i];
             if(data->block_id == block_id)
@@ -14546,9 +15383,9 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get
     switch(*type)
     {
     case TNG_CHAR_DATA:
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 len = strlen(data->strings[i][j]) + 1;
                 (*values)[i][j].c = malloc(len);
@@ -14558,9 +15395,9 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get
         break;
     case TNG_INT_DATA:
         size = sizeof(int);
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 (*values)[i][j].i = *(int *)((char *)data->values + size *
                                              (i*(*n_values_per_frame) + j));
@@ -14569,9 +15406,9 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get
         break;
     case TNG_FLOAT_DATA:
         size = sizeof(float);
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 (*values)[i][j].f = *(float *)((char *)data->values + size *
                                                (i*(*n_values_per_frame) + j));
@@ -14581,9 +15418,9 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get
     case TNG_DOUBLE_DATA:
     default:
         size = sizeof(double);
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 (*values)[i][j].d = *(double *)((char *)data->values + size *
                                                 (i*(*n_values_per_frame) + j));
@@ -14626,19 +15463,20 @@ tng_function_status tng_data_vector_get(tng_trajectory_t tng_data,
     if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS)
     {
         tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
                 stat != TNG_CRITICAL &&
-                block->id != TNG_TRAJECTORY_FRAME_SET)
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
         {
             /* Use hash by default */
             stat = tng_block_read_next(tng_data, block,
                                     TNG_USE_HASH);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -14653,7 +15491,7 @@ tng_function_status tng_data_vector_get(tng_trajectory_t tng_data,
             return(stat);
         }
 
-        for(i = frame_set->n_data_blocks; i-- ;)
+        for(i = 0; i < frame_set->n_data_blocks; i++)
         {
             data = &frame_set->tr_data[i];
             if(data->block_id == block_id)
@@ -14754,18 +15592,19 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
        frame_set->n_data_blocks <= 0)
     {
         tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
             stat != TNG_CRITICAL &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+            block->id != TNG_TRAJECTORY_FRAME_SET &&
+            block->id != -1)
         {
             stat = tng_block_read_next(tng_data, block,
                                     hash_mode);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -14784,7 +15623,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
 
     /* See if there is a data block of this ID.
      * Start checking the last read frame set */
-    for(i = frame_set->n_data_blocks; i-- ;)
+    for(i = 0; i < frame_set->n_data_blocks; i++)
     {
         data = &frame_set->tr_data[i];
         if(data->block_id == block_id)
@@ -14833,7 +15672,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 len = strlen(data->strings[current_frame_pos][j]) + 1;
                 (*values)[i][j].c = malloc(len);
@@ -14855,7 +15694,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 (*values)[i][j].i = *(int *)((char *)data->values + size *
                                             (current_frame_pos *
@@ -14877,7 +15716,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 (*values)[i][j].f = *(float *)((char *)data->values + size *
                                                (current_frame_pos *
@@ -14900,7 +15739,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_values_per_frame; j--;)
+            for(j = 0; j < *n_values_per_frame; j++)
             {
                 (*values)[i][j].d = *(double *)((char *)data->values + size *
                                                 (current_frame_pos *
@@ -14960,9 +15799,9 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get
         tng_block_init(&block);
         if(stat != TNG_SUCCESS)
         {
-            fseek(tng_data->input_file,
-                  (long)tng_data->current_trajectory_frame_set_input_file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   tng_data->current_trajectory_frame_set_input_file_pos,
+                   SEEK_SET);
             stat = tng_block_header_read(tng_data, block);
             if(stat != TNG_SUCCESS)
             {
@@ -14971,14 +15810,15 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get
                 return(stat);
             }
 
-            fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+            fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
         }
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
             stat != TNG_CRITICAL &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+            block->id != TNG_TRAJECTORY_FRAME_SET &&
+            block->id != -1)
         {
             if(block->id == block_id)
             {
@@ -14986,7 +15826,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get
                                         hash_mode);
                 if(stat != TNG_CRITICAL)
                 {
-                    file_pos = ftell(tng_data->input_file);
+                    file_pos = ftello(tng_data->input_file);
                     if(file_pos < tng_data->input_file_len)
                     {
                         stat = tng_block_header_read(tng_data, block);
@@ -14996,7 +15836,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get
             else
             {
                 file_pos += block->block_contents_size + block->header_contents_size;
-                fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+                fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -15196,19 +16036,20 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
         }
 
         tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
                 stat != TNG_CRITICAL &&
-                block->id != TNG_TRAJECTORY_FRAME_SET)
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
         {
             /* Use hash by default */
             stat = tng_block_read_next(tng_data, block,
                                     TNG_USE_HASH);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -15223,7 +16064,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
             return(stat);
         }
 
-        for(i = frame_set->n_particle_data_blocks; i-- ;)
+        for(i = 0; i < frame_set->n_particle_data_blocks; i++)
         {
             data = &frame_set->tr_particle_data[i];
             if(data->block_id == block_id)
@@ -15281,12 +16122,12 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
     switch(*type)
     {
     case TNG_CHAR_DATA:
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k = 0; k < *n_values_per_frame; k++)
                 {
                     len = strlen(data->strings[i][j][k]) + 1;
                     (*values)[i][mapping][k].c = malloc(len);
@@ -15299,12 +16140,12 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
     case TNG_INT_DATA:
         size = sizeof(int);
         i_step = (*n_particles) * (*n_values_per_frame);
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k = 0; k < *n_values_per_frame; k++)
                 {
                     (*values)[i][mapping][k].i = *(int *)
                                                  ((char *)data->values + size *
@@ -15317,12 +16158,12 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
     case TNG_FLOAT_DATA:
         size = sizeof(float);
         i_step = (*n_particles) * (*n_values_per_frame);
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k = 0; k < *n_values_per_frame; k++)
                 {
                     (*values)[i][mapping][k].f = *(float *)
                                                  ((char *)data->values + size *
@@ -15336,12 +16177,12 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get
     default:
         size = sizeof(double);
         i_step = (*n_particles) * (*n_values_per_frame);
-        for(i=*n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j=*n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k = 0; k < *n_values_per_frame; k++)
                 {
                     (*values)[i][mapping][k].d = *(double *)
                                                  ((char *)data->values + size *
@@ -15391,19 +16232,20 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get
     if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS)
     {
         tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
                 stat != TNG_CRITICAL &&
-                block->id != TNG_TRAJECTORY_FRAME_SET)
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
         {
             /* Use hash by default */
             stat = tng_block_read_next(tng_data, block,
                                     TNG_USE_HASH);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -15418,7 +16260,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get
             return(stat);
         }
 
-        for(i = frame_set->n_particle_data_blocks; i-- ;)
+        for(i = 0; i < frame_set->n_particle_data_blocks; i++)
         {
             data = &frame_set->tr_particle_data[i];
             if(data->block_id == block_id)
@@ -15499,9 +16341,9 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get
     else
     {
         i_step = (*n_particles) * (*n_values_per_frame);
-        for(i = *n_frames; i--;)
+        for(i = 0; i < *n_frames; i++)
         {
-            for(j = *n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
                 memcpy(((char *)*values) + size * (i * i_step + mapping *
@@ -15561,18 +16403,19 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
        frame_set->n_particle_data_blocks <= 0)
     {
         tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read all blocks until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
                 stat != TNG_CRITICAL &&
-                block->id != TNG_TRAJECTORY_FRAME_SET)
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
         {
             stat = tng_block_read_next(tng_data, block,
                                     hash_mode);
             if(stat != TNG_CRITICAL)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -15651,10 +16494,10 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k = 0; k < *n_values_per_frame; k++)
                 {
                     len = strlen(data->strings[current_frame_pos][j][k]) + 1;
                     (*values)[i][mapping][k].c = malloc(len);
@@ -15678,10 +16521,10 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_particles; j--;)
+            for(j = 0; j < *n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k = 0; k < *n_values_per_frame; k++)
                 {
                     (*values)[i][mapping][k].i = *(int *)
                                                  ((char *)data->values + size *
@@ -15707,10 +16550,10 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_particles; j--;)
+            for(j=0; j<*n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k=0; k<*n_values_per_frame; k++)
                 {
                     (*values)[i][mapping][k].f = *(float *)
                                                  ((char *)data->values + size *
@@ -15737,10 +16580,10 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get
                 }
                 current_frame_pos = 0;
             }
-            for(j=*n_particles; j--;)
+            for(j=0; j<*n_particles; j++)
             {
                 tng_particle_mapping_get_real_particle(frame_set, j, &mapping);
-                for(k=*n_values_per_frame; k--;)
+                for(k=0; k<*n_values_per_frame; k++)
                 {
                     (*values)[i][mapping][k].d = *(double *)
                                                  ((char *)data->values + size *
@@ -15804,9 +16647,9 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get
         tng_block_init(&block);
         if(stat != TNG_SUCCESS)
         {
-            fseek(tng_data->input_file,
-                  (long)tng_data->current_trajectory_frame_set_input_file_pos,
-                  SEEK_SET);
+            fseeko(tng_data->input_file,
+                   tng_data->current_trajectory_frame_set_input_file_pos,
+                   SEEK_SET);
             stat = tng_block_header_read(tng_data, block);
             if(stat != TNG_SUCCESS)
             {
@@ -15815,14 +16658,15 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get
                 return(stat);
             }
 
-            fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+            fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
         }
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         /* Read until next frame set block */
         stat = tng_block_header_read(tng_data, block);
         while(file_pos < tng_data->input_file_len &&
             stat != TNG_CRITICAL &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+            block->id != TNG_TRAJECTORY_FRAME_SET &&
+            block->id != -1)
         {
             if(block->id == block_id || block->id == TNG_PARTICLE_MAPPING)
             {
@@ -15830,7 +16674,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get
                                         hash_mode);
                 if(stat != TNG_CRITICAL)
                 {
-                    file_pos = ftell(tng_data->input_file);
+                    file_pos = ftello(tng_data->input_file);
                     if(file_pos < tng_data->input_file_len)
                     {
                         stat = tng_block_header_read(tng_data, block);
@@ -15840,7 +16684,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get
             else
             {
                 file_pos += block->block_contents_size + block->header_contents_size;
-                fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+                fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
                 if(file_pos < tng_data->input_file_len)
                 {
                     stat = tng_block_header_read(tng_data, block);
@@ -16007,7 +16851,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
     tng_function_status stat;
     tng_non_particle_data_t np_data;
     tng_particle_data_t p_data;
-    long file_pos;
+    int64_t orig_file_pos, file_pos;
     int is_particle_data;
 
     if(tng_data->current_trajectory_frame_set_input_file_pos <= 0)
@@ -16023,6 +16867,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
             return(stat);
         }
     }
+    orig_file_pos = tng_data->current_trajectory_frame_set_input_file_pos;
     stat = tng_data_find(tng_data, block_id, &np_data);
     if(stat != TNG_SUCCESS)
     {
@@ -16033,15 +16878,17 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
             /* If no specific frame was required read until this data block is found */
             if(frame < 0)
             {
-                file_pos = ftell(tng_data->input_file);
+                file_pos = ftello(tng_data->input_file);
                 while(stat != TNG_SUCCESS && file_pos < tng_data->input_file_len)
                 {
                     stat = tng_frame_set_read_next_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id);
-                    file_pos = ftell(tng_data->input_file);
+                    file_pos = ftello(tng_data->input_file);
                 }
             }
             if(stat != TNG_SUCCESS)
             {
+                tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos);
+
                 return(stat);
             }
             stat = tng_data_find(tng_data, block_id, &np_data);
@@ -16050,6 +16897,8 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
                 stat = tng_particle_data_find(tng_data, block_id, &p_data);
                 if(stat != TNG_SUCCESS)
                 {
+                    tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos);
+
                     return(stat);
                 }
                 else
@@ -16079,6 +16928,8 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length
     {
         *stride_length = np_data->stride_length;
     }
+    tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos);
+
     return(TNG_SUCCESS);
 }
 
@@ -16131,7 +16982,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
         /* Read the file headers */
         tng_file_headers_read(*tng_data_p, TNG_USE_HASH);
 
-        tng_num_frame_sets_get(*tng_data_p, &(*tng_data_p)->n_trajectory_frame_sets);
+        stat = tng_num_frame_sets_get(*tng_data_p, &(*tng_data_p)->n_trajectory_frame_sets);
+
+        if(stat != TNG_SUCCESS)
+        {
+            return(stat);
+        }
     }
 
     if(mode == 'w')
@@ -16140,9 +16996,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
     }
     else if(mode == 'a')
     {
-        fseek((*tng_data_p)->input_file,
-                (long)(*tng_data_p)->last_trajectory_frame_set_input_file_pos,
-                SEEK_SET);
+        if((*tng_data_p)->output_file)
+        {
+            fclose((*tng_data_p)->output_file);
+        }
+        (*tng_data_p)->output_file = (*tng_data_p)->input_file;
+        fseeko((*tng_data_p)->input_file,
+               (*tng_data_p)->last_trajectory_frame_set_input_file_pos,
+               SEEK_SET);
 
         stat = tng_frame_set_read(*tng_data_p, TNG_USE_HASH);
         if(stat != TNG_SUCCESS)
@@ -16150,6 +17011,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
             fprintf(stderr, "TNG library: Cannot read frame set and related blocks. %s: %d\n",
                    __FILE__, __LINE__);
         }
+        (*tng_data_p)->output_file = 0;
 
         (*tng_data_p)->first_trajectory_frame_set_output_file_pos =
         (*tng_data_p)->first_trajectory_frame_set_input_file_pos;
@@ -16157,9 +17019,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
         (*tng_data_p)->last_trajectory_frame_set_input_file_pos;
         (*tng_data_p)->current_trajectory_frame_set_output_file_pos =
         (*tng_data_p)->current_trajectory_frame_set_input_file_pos;
-        (*tng_data_p)->first_trajectory_frame_set_input_file_pos = -1;
-        (*tng_data_p)->last_trajectory_frame_set_input_file_pos = -1;
-        (*tng_data_p)->current_trajectory_frame_set_input_file_pos = -1;
         if((*tng_data_p)->input_file)
         {
             fclose((*tng_data_p)->input_file);
@@ -16172,7 +17031,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open
         }
         tng_output_append_file_set(*tng_data_p, filename);
 
-        fseek((*tng_data_p)->output_file, 0, SEEK_END);
+        fseeko((*tng_data_p)->output_file, 0, SEEK_END);
     }
 
     return(TNG_SUCCESS);
@@ -16517,12 +17376,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
                  double *retrieved_time)
 {
     tng_trajectory_frame_set_t frame_set;
-    tng_particle_data_t data;
+    tng_particle_data_t data = 0;
     tng_function_status stat;
     int size;
-    int64_t i, data_size, n_particles;
+    int64_t i, data_size, n_particles, file_pos;
     void *temp;
-    long file_pos;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(values, "TNG library: The pointer to the values array must not be a NULL pointer");
@@ -16536,11 +17394,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
     if(stat != TNG_SUCCESS)
     {
         stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         while(stat != TNG_SUCCESS && file_pos < tng_data->input_file_len)
         {
             stat = tng_frame_set_read_next_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id);
-            file_pos = ftell(tng_data->input_file);
+            file_pos = ftello(tng_data->input_file);
         }
         if(stat != TNG_SUCCESS)
         {
@@ -16554,9 +17412,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
     }
     if(data->last_retrieved_frame < 0)
     {
-        fseek(tng_data->input_file,
-              (long)tng_data->first_trajectory_frame_set_input_file_pos,
-              SEEK_SET);
+        fseeko(tng_data->input_file,
+               tng_data->first_trajectory_frame_set_input_file_pos,
+               SEEK_SET);
         stat = tng_frame_set_read(tng_data, TNG_USE_HASH);
         if(stat != TNG_SUCCESS)
         {
@@ -16572,7 +17430,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
     }
     else
     {
-        i = data->last_retrieved_frame + data->stride_length;
+        if(data->n_frames == 1)
+        {
+            i = data->last_retrieved_frame + 1;
+        }
+        else
+        {
+            i = data->last_retrieved_frame + data->stride_length;
+        }
         if(i < frame_set->first_frame || i >= frame_set->first_frame + frame_set->n_frames)
         {
             stat = tng_frame_set_of_frame_find(tng_data, i);
@@ -16586,6 +17451,10 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read
                 {
                     return(stat);
                 }
+                if(frame_set->first_frame + frame_set->n_frames - 1 < i)
+                {
+                    return(TNG_FAILURE);
+                }
                 i = frame_set->first_frame;
             }
         }
@@ -16670,12 +17539,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
                  double *retrieved_time)
 {
     tng_trajectory_frame_set_t frame_set;
-    tng_non_particle_data_t data;
+    tng_non_particle_data_t data = 0;
     tng_function_status stat;
     int size;
-    int64_t i, data_size;
+    int64_t i, data_size, file_pos;
     void *temp;
-    long file_pos;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(values, "TNG library: The pointer to the values array must not be a NULL pointer");
@@ -16689,11 +17557,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
     if(stat != TNG_SUCCESS)
     {
         stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id);
-        file_pos = ftell(tng_data->input_file);
+        file_pos = ftello(tng_data->input_file);
         while(stat != TNG_SUCCESS && file_pos < tng_data->input_file_len)
         {
             stat = tng_frame_set_read_next_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id);
-            file_pos = ftell(tng_data->input_file);
+            file_pos = ftello(tng_data->input_file);
         }
         if(stat != TNG_SUCCESS)
         {
@@ -16707,9 +17575,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
     }
     if(data->last_retrieved_frame < 0)
     {
-        fseek(tng_data->input_file,
-                (long)tng_data->first_trajectory_frame_set_input_file_pos,
-                SEEK_SET);
+        fseeko(tng_data->input_file,
+               tng_data->first_trajectory_frame_set_input_file_pos,
+               SEEK_SET);
         stat = tng_frame_set_read(tng_data, TNG_USE_HASH);
         if(stat != TNG_SUCCESS)
         {
@@ -16725,7 +17593,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
     }
     else
     {
-        i = data->last_retrieved_frame + data->stride_length;
+        if(data->n_frames == 1)
+        {
+            i = data->last_retrieved_frame + 1;
+        }
+        else
+        {
+            i = data->last_retrieved_frame + data->stride_length;
+        }
         if(i < frame_set->first_frame || i >= frame_set->first_frame + frame_set->n_frames)
         {
             stat = tng_frame_set_of_frame_find(tng_data, i);
@@ -16739,6 +17614,10 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read
                 {
                     return(stat);
                 }
+                if(frame_set->first_frame + frame_set->n_frames - 1 < i)
+                {
+                    return(TNG_FAILURE);
+                }
                 i = frame_set->first_frame;
             }
         }
@@ -17359,7 +18238,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write
     tng_trajectory_frame_set_t frame_set;
     tng_particle_data_t p_data;
     tng_non_particle_data_t np_data;
-    int64_t n_particles, n_frames, stride_length = 100, frame_pos;
+    int64_t n_particles = 0, n_frames, stride_length = 100, frame_pos;
     int64_t last_frame;
     int is_first_frame_flag = 0;
     char block_type_flag;
@@ -17573,7 +18452,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write
     tng_trajectory_frame_set_t frame_set;
     tng_particle_data_t p_data;
     tng_non_particle_data_t np_data;
-    int64_t n_particles, n_frames, stride_length = 100, frame_pos;
+    int64_t n_particles = 0, n_frames, stride_length = 100, frame_pos;
     int64_t last_frame;
     int is_first_frame_flag = 0;
     char block_type_flag;
@@ -18146,11 +19025,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get
                 (tng_trajectory_t tng_data,
                  const int64_t block_id,
                  int64_t *codec_id,
-                 float *factor)
+                 double *factor)
 {
     tng_trajectory_frame_set_t frame_set;
-    tng_particle_data_t p_data;
-    tng_non_particle_data_t np_data;
+    tng_particle_data_t p_data = 0;
+    tng_non_particle_data_t np_data = 0;
     tng_function_status stat;
     int64_t i;
     int block_type = -1;
@@ -18243,12 +19122,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get
     if(block_type == TNG_PARTICLE_BLOCK_DATA)
     {
         *codec_id = p_data->codec_id;
-        *factor   = (float)p_data->compression_multiplier;
+        *factor   = p_data->compression_multiplier;
     }
     else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA)
     {
         *codec_id = np_data->codec_id;
-        *factor   = (float)np_data->compression_multiplier;
+        *factor   = np_data->compression_multiplier;
     }
     return(TNG_SUCCESS);
 }
@@ -18269,9 +19148,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat
     tng_gen_block_t block;
     int64_t i, j, block_id, *temp;
     int64_t data_frame, frame_diff, min_diff;
-    int64_t size, frame_set_file_pos;
+    int64_t size, frame_set_file_pos, file_pos;
     int found, read_all = 0;
-    long file_pos;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(next_frame, "TNG library: The pointer to the next frame must not be NULL.");
@@ -18285,7 +19163,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat
         temp = realloc(*data_block_ids_in_next_frame, size);
         if(!temp)
         {
-            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+            fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                     sizeof(int64_t) * (*n_data_blocks_in_next_frame),
                     __FILE__, __LINE__);
             free(*data_block_ids_in_next_frame);
@@ -18319,33 +19197,37 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat
         }
     }
 
-    if(frame_set->n_particle_data_blocks <= 0 || frame_set->n_data_blocks <= 0)
+    /* Check for data blocks only if they have not already been found. */
+    if(frame_set->n_particle_data_blocks <= 0 && frame_set->n_data_blocks <= 0)
     {
-        tng_block_init(&block);
-        file_pos = ftell(tng_data->input_file);
-        /* Read all blocks until next frame set block */
-        stat = tng_block_header_read(tng_data, block);
-        while(file_pos < tng_data->input_file_len &&
-            stat != TNG_CRITICAL &&
-            block->id != TNG_TRAJECTORY_FRAME_SET)
+        file_pos = ftello(tng_data->input_file);
+        if(file_pos < tng_data->input_file_len)
         {
-            stat = tng_block_read_next(tng_data, block,
-                                       TNG_USE_HASH);
-            if(stat != TNG_CRITICAL)
+            tng_block_init(&block);
+            stat = tng_block_header_read(tng_data, block);
+            while(file_pos < tng_data->input_file_len &&
+                stat != TNG_CRITICAL &&
+                block->id != TNG_TRAJECTORY_FRAME_SET &&
+                block->id != -1)
             {
-                file_pos = ftell(tng_data->input_file);
-                if(file_pos < tng_data->input_file_len)
+                stat = tng_block_read_next(tng_data, block,
+                                        TNG_USE_HASH);
+                if(stat != TNG_CRITICAL)
                 {
-                    stat = tng_block_header_read(tng_data, block);
+                    file_pos = ftello(tng_data->input_file);
+                    if(file_pos < tng_data->input_file_len)
+                    {
+                        stat = tng_block_header_read(tng_data, block);
+                    }
                 }
             }
-        }
-        tng_block_destroy(&block);
-        if(stat == TNG_CRITICAL)
-        {
-            fprintf(stderr, "TNG library: Cannot read block header at pos %ld. %s: %d\n",
-                    file_pos, __FILE__, __LINE__);
-            return(stat);
+            tng_block_destroy(&block);
+            if(stat == TNG_CRITICAL)
+            {
+                fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n",
+                        file_pos, __FILE__, __LINE__);
+                return(stat);
+            }
         }
         read_all = 1;
     }
@@ -18423,7 +19305,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat
                 temp = realloc(*data_block_ids_in_next_frame, size);
                 if(!temp)
                 {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                            sizeof(int64_t) * (*n_data_blocks_in_next_frame),
                            __FILE__, __LINE__);
                     free(*data_block_ids_in_next_frame);
@@ -18510,7 +19392,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat
                 temp = realloc(*data_block_ids_in_next_frame, size);
                 if(!temp)
                 {
-                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n",
+                    fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n",
                            sizeof(int64_t) * (*n_data_blocks_in_next_frame),
                            __FILE__, __LINE__);
                     free(*data_block_ids_in_next_frame);
@@ -18550,7 +19432,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_g
                  char **compressions)
 {
     tng_gen_block_t block;
-    long orig_file_pos, file_pos;
+    int64_t orig_file_pos, file_pos;
 
     TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup.");
     TNG_ASSERT(n_data_blocks, "TNG library: The pointer to n_data_blocks must not be NULL.");
@@ -18558,15 +19440,15 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_g
     TNG_ASSERT(data_block_names, "TNG library: The pointer to the list of data block names must not be NULL.");
     TNG_ASSERT(stride_lengths, "TNG library: The pointer to the list of stride lengths must not be NULL.");
 
-    orig_file_pos = ftell(tng_data->input_file);
+    orig_file_pos = ftello(tng_data->input_file);
 
     if(!tng_data->input_file_len)
     {
-        fseek(tng_data->input_file, 0, SEEK_END);
-        tng_data->input_file_len = ftell(tng_data->input_file);
+        fseeko(tng_data->input_file, 0, SEEK_END);
+        tng_data->input_file_len = ftello(tng_data->input_file);
     }
 
-    fseek(tng_data->input_file, 0, SEEK_SET);
+    fseeko(tng_data->input_file, 0, SEEK_SET);
     file_pos = 0;
 
     *n_data_blocks = 0;
@@ -18580,11 +19462,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_g
         {
 
         }
-        file_pos += (long)(block->block_contents_size + block->header_contents_size);
-        fseek(tng_data->input_file, (long)block->block_contents_size, SEEK_CUR);
+        file_pos += (block->block_contents_size + block->header_contents_size);
+        fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR);
     }
 
-    fseek(tng_data->input_file, orig_file_pos, SEEK_SET);
+    fseeko(tng_data->input_file, orig_file_pos, SEEK_SET);
 
     return(TNG_SUCCESS);
 }