Index: src/Parser/TremoloParser.cpp
===================================================================
--- src/Parser/TremoloParser.cpp	(revision 531f27764dc2eabbcb727eb49be1867ac1257e30)
+++ src/Parser/TremoloParser.cpp	(revision 23fd4308ecfb01cade133b122c6e3e4b440e3141)
@@ -81,13 +81,7 @@
   knownKeys["GrpTypeNo"] = TremoloKey::GrpTypeNo;
   knownKeys["torsion"] = TremoloKey::torsion;
+  knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys
 
   createKnownTypesByIdentity();
-
-  // default behavior: use all possible keys on output
-  for (std::map<std::string, TremoloKey::atomDataKey>::iterator iter = knownKeys.begin(); iter != knownKeys.end(); ++iter)
-    usedFields.push_back(iter->first);
-
-  // and noKey afterwards(!) such that it is not used in usedFields
-  knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys
 
   // invert knownKeys for debug output
@@ -103,6 +97,5 @@
 FormatParser< tremolo >::~FormatParser() 
 {
-  LOG(1, "INFO: Clearing usedFields.");
-  usedFields.clear();
+  usedFields_save.clear();
   additionalAtomData.clear();
   knownKeys.clear();
@@ -120,7 +113,4 @@
   // reset the id maps
   resetIdAssociations();
-
-  LOG(1, "INFO: Clearing usedFields.");
-  usedFields.clear();
 
   molecule *newmol = World::getInstance().createMolecule();
@@ -130,8 +120,9 @@
   while (file->good()) {
     std::getline(*file, line, '\n');
-    if (usedFields.empty()) {
+    // we only parse in the first ATOMDATA line
+    if (usedFields_load.empty()) {
       location = line.find("ATOMDATA", 0);
       if (location != string::npos) {
-       parseAtomDataKeysLine(line, location + 8);
+       parseAtomDataKeysLine(line, location + 8, usedFields_load);
       }
     }
@@ -140,5 +131,5 @@
     }
   }
-  LOG(3, "usedFields after load contains: " << usedFields);
+  LOG(3, "DEBUG: Local usedFields is: " << usedFields_load);
 
   // refresh atom::nr and atom::name
@@ -149,4 +140,8 @@
   adaptImprData();
   adaptTorsion();
+
+  // append usedFields to global usedFields, is made unique on save, clear after use
+  usedFields_save.insert(usedFields_save.end(), usedFields_load.begin(), usedFields_load.end());
+  usedFields_load.clear();
 }
 
@@ -157,29 +152,102 @@
  * \param atoms atoms to store
  */
-void FormatParser< tremolo >::save(ostream* file, const std::vector<atom *> &AtomList) {
+void FormatParser< tremolo >::save(std::ostream* file, const std::vector<atom *> &AtomList) {
   LOG(0, "Saving changes to tremolo.");
 
-  std::vector<atom*>::const_iterator atomIt;
-  /*vector<string>::iterator it;*/
-  std::vector<std::string>::iterator it = unique(usedFields.begin(), usedFields.end()); // skips all duplicates in the vector
-
-  LOG(3, "INFO: usedFields before save contains: " << usedFields);
-  //LOG(3, "INFO: additionalAtomData contains: " << additionalAtomData);
-
-  // distribute continuous indices
+  // install default usedFields if empty so far
+  if (usedFields_save.empty()) {
+    // default behavior: use all possible keys on output
+    for (std::map<std::string, TremoloKey::atomDataKey>::iterator iter = knownKeys.begin();
+        iter != knownKeys.end(); ++iter)
+      if (iter->second != TremoloKey::noKey) // don't add noKey
+        usedFields_save.push_back(iter->first);
+  }
+  // make present usedFields_save unique
+  makeUsedFieldsUnique(usedFields_save);
+  LOG(1, "DEBUG: Global (with unique entries) usedFields_save is: " << usedFields_save);
+
+  // distribute ids continuously
+  distributeContinuousIds(AtomList);
+
+  // store atomdata
+  save_AtomDataLine(file);
+
+  // store box
+  save_BoxLine(file);
+
+  // store particles
+  for (std::vector<atom*>::const_iterator  atomIt = AtomList.begin();
+      atomIt != AtomList.end(); ++atomIt)
+    saveLine(file, *atomIt);
+}
+
+/** Helper function to make \given fields unique while preserving the order of first appearance.
+ *
+ * As std::unique only removes element if equal to predecessor, a vector is only
+ * made unique if sorted beforehand. But sorting would destroy order of first
+ * appearance, hence we do the sorting on a temporary field and add the unique
+ * elements in the order as in \a fields.
+ *
+ * @param fields usedFields to make unique while preserving order of appearance
+ */
+void FormatParser< tremolo >::makeUsedFieldsUnique(usedFields_t &fields)
+{
+  // std::unique only removes if predecessor is equal, not over whole range, hence do it manually
+  usedFields_t temp_fields(usedFields_save);
+  std::sort(temp_fields.begin(), temp_fields.end());
+  usedFields_t::iterator it =
+      std::unique(temp_fields.begin(), temp_fields.end()); // skips all duplicates in the vector
+  temp_fields.erase(it, temp_fields.end());
+  usedFields_t usedfields(usedFields_save);
+  usedFields_save.clear();
+  usedFields_save.reserve(temp_fields.size());
+  // now go through each usedFields entry, check if in temp_fields and remove there on first occurence
+  for (usedFields_t::const_iterator iter = usedfields.begin();
+      iter != usedfields.end(); ++iter) {
+    usedFields_t::iterator uniqueiter =
+        std::find(temp_fields.begin(), temp_fields.end(), *iter);
+    if (uniqueiter != temp_fields.end()) {
+      usedFields_save.push_back(*iter);
+      // add only once to ATOMDATA
+      temp_fields.erase(uniqueiter);
+    }
+  }
+  ASSERT( temp_fields.empty(),
+      "FormatParser< tremolo >::save() - still unique entries left in temp_fields after unique?");
+}
+
+
+/** Resets and distributes the indices continuously.
+ *
+ * \param atoms atoms to store
+ */
+void FormatParser< tremolo >::distributeContinuousIds(const std::vector<atom *> &AtomList)
+{
   resetIdAssociations();
   atomId_t lastid = 0;
-  for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
+  for (std::vector<atom*>::const_iterator atomIt = AtomList.begin();
+      atomIt != AtomList.end(); ++atomIt)
     associateLocaltoGlobalId(++lastid, (*atomIt)->getId());
-  }
-
-  // store Atomdata line
+}
+
+/** Store Atomdata line to \a file.
+ *
+ * @param file output stream
+ */
+void FormatParser< tremolo >::save_AtomDataLine(std::ostream* file) const
+{
   *file << "# ATOMDATA";
-  for (it=usedFields.begin(); it < usedFields.end(); it++) {
+  for (usedFields_t::const_iterator it=usedFields_save.begin();
+      it != usedFields_save.end(); ++it)
     *file << "\t" << *it;
-  }
-  *file << endl;
-
-  // store Box info
+  *file << std::endl;
+}
+
+/** Store Box info to \a file
+ *
+ * @param file output stream
+ */
+void FormatParser< tremolo >::save_BoxLine(std::ostream* file) const
+{
   *file << "# Box";
   const RealSpaceMatrix &M = World::getInstance().getDomain().getM();
@@ -188,9 +256,4 @@
       *file << "\t" << M.at(i,j);
   *file << std::endl;
-
-  // store particles
-  for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
-    saveLine(file, *atomIt);
-  }
 }
 
@@ -225,16 +288,4 @@
 
 /**
- * Sets the keys for which data should be written to the stream when save is
- * called.
- *
- * \param string of field names with the same syntax as for an ATOMDATA line
- *        but without the prexix "ATOMDATA"
- */
-void FormatParser< tremolo >::setFieldsForSave(std::string atomDataLine) {
-  parseAtomDataKeysLine(atomDataLine, 0);
-}
-
-
-/**
  * Writes one line of tremolo-formatted data to the provided stream.
  *
@@ -242,12 +293,11 @@
  * \param reference to the atom of which information should be written
  */
-void FormatParser< tremolo >::saveLine(ostream* file, atom* currentAtom) {
-  std::vector<string>::iterator it;
-
+void FormatParser< tremolo >::saveLine(std::ostream* file, const atom* currentAtom)
+{
   TremoloKey::atomDataKey currentField;
 
   LOG(4, "INFO: Saving atom " << *currentAtom << ", its father id is " << currentAtom->GetTrueFather()->getId());
 
-  for (it = usedFields.begin(); it != usedFields.end(); it++) {
+  for (usedFields_t::iterator it = usedFields_save.begin(); it != usedFields_save.end(); it++) {
     currentField = knownKeys[it->substr(0, it->find("="))];
     switch (currentField) {
@@ -343,5 +393,5 @@
   }
 
-  *file << endl;
+  *file << std::endl;
 }
 
@@ -355,5 +405,5 @@
  * \param reference to the atom of which to take the neighbor information
  */
-void FormatParser< tremolo >::writeNeighbors(ostream* file, int numberOfNeighbors, atom* currentAtom) {
+void FormatParser< tremolo >::writeNeighbors(std::ostream* file, const int numberOfNeighbors, const atom* currentAtom) {
   const BondList& ListOfBonds = currentAtom->getListOfBonds();
   // sort bonded indices
@@ -373,16 +423,18 @@
 
 /**
- * Stores keys from the ATOMDATA line.
+ * Stores keys from the ATOMDATA line in \a fields.
  *
  * \param line to parse the keys from
- * \param with which offset the keys begin within the line
- */
-void FormatParser< tremolo >::parseAtomDataKeysLine(std::string line, int offset) {
+ * \param offset with which offset the keys begin within the line
+ * \param fields which usedFields to use
+ */
+void FormatParser< tremolo >::parseAtomDataKeysLine(
+    const std::string &line,
+    const int offset,
+    usedFields_t &fields) {
   std::string keyword;
   std::stringstream lineStream;
 
   lineStream << line.substr(offset);
-  LOG(1, "INFO: Clearing usedFields in parseAtomDataKeysLine.");
-  usedFields.clear();
   while (lineStream.good()) {
     lineStream >> keyword;
@@ -392,7 +444,7 @@
       break;
     }
-    usedFields.push_back(keyword);
-  }
-  //LOG(1, "INFO: " << usedFields);
+    fields.push_back(keyword);
+  }
+  //LOG(1, "INFO: " << fields);
 }
 
@@ -400,6 +452,6 @@
  *  \a atomdata_string.
  *
- *  We just call \sa  FormatParser< tremolo >::parseAtomDataKeysLine() which is left
- *  private.,
+ *  We just call \sa  FormatParser< tremolo >::parseAtomDataKeysLine(), however
+ *  we clear FormatParser< tremolo >::usedFields_save.
  *
  * @param atomdata_string line to parse with space-separated values
@@ -407,5 +459,6 @@
 void FormatParser< tremolo >::setAtomData(const std::string &atomdata_string)
 {
-  parseAtomDataKeysLine(atomdata_string, 0);
+  usedFields_save.clear();
+  parseAtomDataKeysLine(atomdata_string, 0, usedFields_save);
 }
 
@@ -418,6 +471,5 @@
  * \param *newmol molecule to add atom to
  */
-void FormatParser< tremolo >::readAtomDataLine(std::string line, molecule *newmol = NULL) {
-  std::vector<string>::iterator it;
+void FormatParser< tremolo >::readAtomDataLine(const std::string &line, molecule *newmol = NULL) {
   std::stringstream lineStream;
   atom* newAtom = World::getInstance().createAtom();
@@ -439,5 +491,5 @@
   tokenizer::iterator tok_iter = tokens.begin();
   // then associate each token to each file
-  for (it = usedFields.begin(); it < usedFields.end(); it++) {
+  for (usedFields_t::const_iterator it = usedFields_load.begin(); it < usedFields_load.end(); it++) {
     const std::string keyName = it->substr(0, it->find("="));
     currentField = knownKeys[keyName];
@@ -543,5 +595,5 @@
  * \param atomid world id of the atom the information belongs to
  */
-void FormatParser< tremolo >::readNeighbors(std::stringstream* line, int numberOfNeighbors, int atomId) {
+void FormatParser< tremolo >::readNeighbors(std::stringstream* line, const int numberOfNeighbors, const int atomId) {
   int neighborId = 0;
   for (int i = 0; i < numberOfNeighbors; i++) {
@@ -557,13 +609,15 @@
 
 /**
- * Checks whether the provided name is within the list of used fields.
- *
- * \param field name to check
- *
+ * Checks whether the provided name is within \a fields.
+ *
+ * \param fields which usedFields to use
+ * \param fieldName name to check
  * \return true if the field name is used
  */
-bool FormatParser< tremolo >::isUsedField(std::string fieldName) {
+bool FormatParser< tremolo >::isUsedField(const usedFields_t &fields, const std::string &fieldName) const
+{
   bool fieldNameExists = false;
-  for (std::vector<std::string>::iterator usedField = usedFields.begin(); usedField != usedFields.end(); usedField++) {
+  for (usedFields_t::const_iterator usedField = fields.begin();
+      usedField != fields.end(); usedField++) {
     if (usedField->substr(0, usedField->find("=")) == fieldName)
       fieldNameExists = true;
@@ -582,5 +636,5 @@
  */
 void FormatParser< tremolo >::processNeighborInformation(const std::vector<atomId_t> &atoms) {
-  if (!isUsedField("neighbors")) {
+  if (!isUsedField(usedFields_load, "neighbors")) {
     return;
   }
@@ -646,5 +700,5 @@
  */
 void FormatParser< tremolo >::adaptImprData() {
-  if (!isUsedField("imprData")) {
+  if (!isUsedField(usedFields_load, "imprData")) {
     return;
   }
@@ -662,5 +716,5 @@
  */
 void FormatParser< tremolo >::adaptTorsion() {
-  if (!isUsedField("torsion")) {
+  if (!isUsedField(usedFields_load, "torsion")) {
     return;
   }
