Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/Makefile.am	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -50,4 +50,7 @@
  			    
 
+PARSERSOURCE = Parser/ChangeTracker.cpp Parser/FormatParser.cpp Parser/TremoloParser.cpp Parser/XyzParser.cpp
+PARSERHEADER = Parser/ChangeTracker.hpp Parser/FormatParser.hpp Parser/TremoloParser.hpp Parser/XyzParser.hpp
+
 PATTERNSOURCE = Patterns/Observer.cpp
 PATTERNHEADER = Patterns/Cacheable.hpp \
@@ -98,4 +101,5 @@
 		 ${ATOMSOURCE} \
 		 ${PATTERNSOURCE} \
+		 ${PARSERSOURCE} \
 		 ${UISOURCE} \
 		 ${DESCRIPTORSOURCE} \
@@ -140,4 +144,5 @@
 	  ${ANALYSISHEADER} \
 	  ${ATOMHEADER} \
+	  ${PARSERHEADER} \
 	  ${PATTERNHEADER} \
 	  ${UIHEADER} \
Index: src/Parser/ChangeTracker.cpp
===================================================================
--- src/Parser/ChangeTracker.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/ChangeTracker.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,73 @@
+/*
+ * ChangeTracker.cpp
+ *
+ *  Created on: Mar 1, 2010
+ *      Author: metzler
+ */
+
+#include "ChangeTracker.hpp"
+
+ChangeTracker* ChangeTracker::instance = NULL;
+
+/**
+ * Constructor. Signs on as an observer for the World.
+ */
+ChangeTracker::ChangeTracker() {
+  isConsistent = true;
+  World::getInstance().signOn(this);
+}
+
+/**
+ * Destructor. Signs off from the World.
+ */
+ChangeTracker::~ChangeTracker() {
+  World::getInstance().signOff(this);
+}
+
+/**
+ * Returns the change tracker instance.
+ *
+ * \return this
+ */
+ChangeTracker* ChangeTracker::get() {
+  if (instance == NULL) {
+    instance = new ChangeTracker();
+  }
+
+  return instance;
+}
+
+/**
+ * Destroys the change tracker instance. Be careful, the change tracker is a
+ * singleton and destruction might lead to a loss of consistency.
+ */
+void ChangeTracker::destroy() {
+  delete instance;
+  instance = NULL;
+}
+
+/**
+ * With this, the World can update the change tracker's state.
+ */
+void ChangeTracker::update(Observable *publisher) {
+  isConsistent = false;
+}
+
+/**
+ * Gets whether there are non-saved changes.
+ *
+ * \param true if there are any changes, false otherwise
+ */
+bool ChangeTracker::hasChanged() {
+  return !isConsistent;
+}
+
+/**
+ * Tells all observers (which are the different parsers) that they are supposed
+ * to save the current state.
+ */
+void ChangeTracker::saveStatus() {
+  if (hasChanged()) {
+    notifyAll();
+  }
+}
Index: src/Parser/ChangeTracker.hpp
===================================================================
--- src/Parser/ChangeTracker.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/ChangeTracker.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,37 @@
+/*
+ * ChangeTracker.hpp
+ *
+ *  Created on: Mar 1, 2010
+ *      Author: metzler
+ */
+
+#ifndef CHANGETRACKER_HPP_
+#define CHANGETRACKER_HPP_
+
+#include "Patterns/Observer.hpp"
+#include "World.hpp"
+
+using namespace std;
+
+/**
+ * Observes the world and notifies subscribers via saveStatus if there are
+ * changes to it.
+ */
+class ChangeTracker : public Observable {
+public:
+  void saveStatus();
+  static ChangeTracker* get();
+  static void destroy();
+
+protected:
+  void update(Observable *publisher);
+  bool hasChanged();
+
+private:
+  bool isConsistent;
+  static ChangeTracker* instance;
+  ChangeTracker();
+  ~ChangeTracker();
+};
+
+#endif /* CHANGETRACKER_HPP_ */
Index: src/Parser/FormatParser.cpp
===================================================================
--- src/Parser/FormatParser.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/FormatParser.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,55 @@
+/*
+ * FormatParser.cpp
+ *
+ *  Created on: Mar 1, 2010
+ *      Author: metzler
+ */
+
+#include "FormatParser.hpp"
+#include <iostream>
+
+using namespace std;
+
+/**
+ * Constructor.
+ */
+FormatParser::FormatParser() {
+  ChangeTracker::get()->signOn(this);
+  saveStream = NULL;
+}
+
+/**
+ * Destructor.
+ */
+FormatParser::~FormatParser() {
+  ChangeTracker::get()->signOff(this);
+}
+
+/**
+ * Update operation which can be invoked by the observable (which should be the
+ * change tracker here).
+ */
+void FormatParser::update(Observable *publisher) {
+  if (!saveStream) {
+    cerr << "Please invoke setOstream() so the parser knows where to save the World's data." << endl;
+    return;
+  }
+
+  save(saveStream);
+}
+
+/**
+ * The observable can tell when it dies.
+ */
+void FormatParser::subjectKilled(Observable *publisher) {}
+
+
+/**
+ * Sets the output stream for save, so the save() method can be invoked on update
+ * automatically.
+ *
+ * \param ostream where to save the World's state
+ */
+void FormatParser::setOstream(ostream* output) {
+  saveStream = output;
+}
Index: src/Parser/FormatParser.hpp
===================================================================
--- src/Parser/FormatParser.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/FormatParser.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,32 @@
+/*
+ * FormatParser.hpp
+ *
+ *  Created on: Mar 1, 2010
+ *      Author: metzler
+ */
+
+#ifndef FORMATPARSER_HPP_
+#define FORMATPARSER_HPP_
+
+#include "Patterns/Observer.hpp"
+#include "ChangeTracker.hpp"
+#include "parser.hpp"
+
+/**
+ * General parser which observes the change tracker.
+ */
+class FormatParser : public Observer {
+public:
+  FormatParser();
+  virtual ~FormatParser();
+  virtual void save(std::ostream* file)=0;
+  virtual void load(std::istream* file)=0;
+  void setOstream(std::ostream* file);
+  void update(Observable *publisher);
+  void subjectKilled(Observable *publisher);
+
+private:
+  std::ostream* saveStream;
+};
+
+#endif /* FORMATPARSER_HPP_ */
Index: src/Parser/TremoloParser.cpp
===================================================================
--- src/Parser/TremoloParser.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/TremoloParser.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,495 @@
+/*
+ * TremoloParser.cpp
+ *
+ *  Created on: Mar 2, 2010
+ *      Author: metzler
+ */
+
+#include "Helpers/Assert.hpp"
+#include "TremoloParser.hpp"
+#include "World.hpp"
+#include "atom.hpp"
+#include "element.hpp"
+#include "bond.hpp"
+#include "periodentafel.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include <map>
+#include <vector>
+
+
+using namespace std;
+using namespace boost;
+
+/**
+ * Constructor.
+ */
+TremoloParser::TremoloParser() {
+  knownKeys[" "] = TremoloKey::noKey; // with this we can detect invalid keys
+  knownKeys["x"] = TremoloKey::x;
+  knownKeys["u"] = TremoloKey::u;
+  knownKeys["F"] = TremoloKey::F;
+  knownKeys["stress"] = TremoloKey::stress;
+  knownKeys["Id"] = TremoloKey::Id;
+  knownKeys["neighbors"] = TremoloKey::neighbors;
+  knownKeys["imprData"] = TremoloKey::imprData;
+  knownKeys["GroupMeasureTypeNo"] = TremoloKey::GroupMeasureTypeNo;
+  knownKeys["Type"] = TremoloKey::Type;
+  knownKeys["extType"] = TremoloKey::extType;
+  knownKeys["name"] = TremoloKey::name;
+  knownKeys["resName"] = TremoloKey::resName;
+  knownKeys["chainID"] = TremoloKey::chainID;
+  knownKeys["resSeq"] = TremoloKey::resSeq;
+  knownKeys["occupancy"] = TremoloKey::occupancy;
+  knownKeys["tempFactor"] = TremoloKey::tempFactor;
+  knownKeys["segID"] = TremoloKey::segID;
+  knownKeys["Charge"] = TremoloKey::Charge;
+  knownKeys["charge"] = TremoloKey::charge;
+  knownKeys["GrpTypeNo"] = TremoloKey::GrpTypeNo;
+  knownKeys["torsion"] = TremoloKey::torsion;
+}
+
+/**
+ * Destructor.
+ */
+TremoloParser::~TremoloParser() {
+  usedFields.clear();
+  additionalAtomData.clear();
+  atomIdMap.clear();
+  knownKeys.clear();
+}
+
+/**
+ * Loads atoms from a tremolo-formatted file.
+ *
+ * \param tremolo file
+ */
+void TremoloParser::load(istream* file) {
+  string line;
+  string::size_type location;
+
+  usedFields.clear();
+  while (file->good()) {
+    std::getline(*file, line, '\n');
+    if (usedFields.empty()) {
+      location = line.find("ATOMDATA", 0);
+      if (location != string::npos) {
+       parseAtomDataKeysLine(line, location + 8);
+      }
+    }
+    if (line.length() > 0 && line.at(0) != '#') {
+      readAtomDataLine(line);
+    }
+  }
+
+  processNeighborInformation();
+  adaptImprData();
+  adaptTorsion();
+}
+
+/**
+ * Saves the World's current state into as a tremolo file.
+ *
+ * \param file where to save the state
+ */
+void TremoloParser::save(ostream* file) {
+  vector<atom*>::iterator atomIt;
+  vector<string>::iterator it;
+
+  *file << "# ATOMDATA";
+  for (it=usedFields.begin(); it < usedFields.end(); it++) {
+    *file << "\t" << *it;
+  }
+  *file << endl;
+  vector<atom *> AtomList = World::getInstance().getAllAtoms();
+  for (atomIt = AtomList.begin(); atomIt != AtomList.end(); atomIt++) {
+    saveLine(file, *atomIt);
+  }
+}
+
+/**
+ * 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 TremoloParser::setFieldsForSave(std::string atomDataLine) {
+  parseAtomDataKeysLine(atomDataLine, 0);
+}
+
+
+/**
+ * Writes one line of tremolo-formatted data to the provided stream.
+ *
+ * \param stream where to write the line to
+ * \param reference to the atom of which information should be written
+ */
+void TremoloParser::saveLine(ostream* file, atom* currentAtom) {
+  vector<string>::iterator it;
+  TremoloKey::atomDataKey currentField;
+
+  for (it = usedFields.begin(); it != usedFields.end(); it++) {
+    currentField = knownKeys[it->substr(0, it->find("="))];
+    switch (currentField) {
+      case TremoloKey::x :
+        // for the moment, assume there are always three dimensions
+        *file << currentAtom->x[0] << "\t";
+        *file << currentAtom->x[1] << "\t";
+        *file << currentAtom->x[2] << "\t";
+        break;
+      case TremoloKey::u :
+        // for the moment, assume there are always three dimensions
+        *file << currentAtom->v[0] << "\t";
+        *file << currentAtom->v[1] << "\t";
+        *file << currentAtom->v[2] << "\t";
+        break;
+      case TremoloKey::Type :
+        *file << currentAtom->getType()->getSymbol() << "\t";
+        break;
+      case TremoloKey::Id :
+        *file << currentAtom->getId() << "\t";
+        break;
+      case TremoloKey::neighbors :
+        writeNeighbors(file, atoi(it->substr(it->find("=") + 1, 1).c_str()), currentAtom);
+        break;
+      default :
+        *file << (additionalAtomData.find(currentAtom->getId()) != additionalAtomData.end()
+          ? additionalAtomData[currentAtom->getId()].get(currentField)
+          : defaultAdditionalData.get(currentField));
+        *file << "\t";
+        break;
+    }
+  }
+
+  *file << endl;
+}
+
+/**
+ * Writes the neighbor information of one atom to the provided stream.
+ *
+ * \param stream where to write neighbor information to
+ * \param number of neighbors
+ * \param reference to the atom of which to take the neighbor information
+ */
+void TremoloParser::writeNeighbors(ostream* file, int numberOfNeighbors, atom* currentAtom) {
+  BondList::iterator currentBond = currentAtom->ListOfBonds.begin();
+  for (int i = 0; i < numberOfNeighbors; i++) {
+    *file << (currentBond != currentAtom->ListOfBonds.end()
+        ? (*currentBond)->GetOtherAtom(currentAtom)->getId() : 0) << "\t";
+  }
+}
+
+/**
+ * Stores keys from the ATOMDATA line.
+ *
+ * \param line to parse the keys from
+ * \param with which offset the keys begin within the line
+ */
+void TremoloParser::parseAtomDataKeysLine(string line, int offset) {
+  string keyword;
+  stringstream lineStream;
+
+  lineStream << line.substr(offset);
+  while (lineStream.good()) {
+    lineStream >> keyword;
+    if (knownKeys[keyword.substr(0, keyword.find("="))] == TremoloKey::noKey) {
+      // throw exception about unknown key
+      cout << "Unknown key: " << keyword << " is not part of the tremolo format specification." << endl;
+      break;
+    }
+    usedFields.push_back(keyword);
+  }
+}
+
+/**
+ * Reads one data line of a tremolo file and interprets it according to the keys
+ * obtained from the ATOMDATA line.
+ *
+ * \param line to parse as an atom
+ */
+void TremoloParser::readAtomDataLine(string line) {
+  vector<string>::iterator it;
+  stringstream lineStream;
+  atom* newAtom = World::getInstance().createAtom();
+  TremoloAtomInfoContainer *atomInfo = NULL;
+  additionalAtomData[newAtom->getId()] = *(new TremoloAtomInfoContainer);
+  atomInfo = &additionalAtomData[newAtom->getId()];
+  TremoloKey::atomDataKey currentField;
+  string word;
+  int oldId;
+
+  lineStream << line;
+  for (it = usedFields.begin(); it < usedFields.end(); it++) {
+    currentField = knownKeys[it->substr(0, it->find("="))];
+    switch (currentField) {
+      case TremoloKey::x :
+        // for the moment, assume there are always three dimensions
+        lineStream >> newAtom->x[0];
+        lineStream >> newAtom->x[1];
+        lineStream >> newAtom->x[2];
+        break;
+      case TremoloKey::u :
+        // for the moment, assume there are always three dimensions
+        lineStream >> newAtom->v[0];
+        lineStream >> newAtom->v[1];
+        lineStream >> newAtom->v[2];
+        break;
+      case TremoloKey::Type :
+        char type[3];
+        lineStream >> type;
+        newAtom->setType(World::getInstance().getPeriode()->FindElement(type));
+        ASSERT(newAtom->getType(), "Type was not set for this atom");
+        break;
+      case TremoloKey::Id :
+        lineStream >> oldId;
+        atomIdMap[oldId] = newAtom->getId();
+        break;
+      case TremoloKey::neighbors :
+        readNeighbors(&lineStream,
+            atoi(it->substr(it->find("=") + 1, 1).c_str()), newAtom->getId());
+        break;
+      default :
+        lineStream >> word;
+        atomInfo->set(currentField, word);
+        break;
+    }
+  }
+}
+
+/**
+ * Reads neighbor information for one atom from the input.
+ *
+ * \param stream where to read the information from
+ * \param number of neighbors to read
+ * \param world id of the atom the information belongs to
+ */
+void TremoloParser::readNeighbors(stringstream* line, int numberOfNeighbors, int atomId) {
+  int neighborId = 0;
+  for (int i = 0; i < numberOfNeighbors; i++) {
+    *line >> neighborId;
+    // 0 is used to fill empty neighbor positions in the tremolo file.
+    if (neighborId > 0) {
+      additionalAtomData[atomId].neighbors.push_back(neighborId);
+    }
+  }
+}
+
+/**
+ * Checks whether the provided name is within the list of used fields.
+ *
+ * \param field name to check
+ *
+ * \return true if the field name is used
+ */
+bool TremoloParser::isUsedField(string fieldName) {
+  bool fieldNameExists = false;
+  for (vector<string>::iterator usedField = usedFields.begin(); usedField != usedFields.end(); usedField++) {
+    if (usedField->substr(0, usedField->find("=")) == fieldName)
+      fieldNameExists = true;
+  }
+
+  return fieldNameExists;
+}
+
+
+/**
+ * Adds the collected neighbor information to the atoms in the world. The atoms
+ * are found by their current ID and mapped to the corresponding atoms with the
+ * Id found in the parsed file.
+ */
+void TremoloParser::processNeighborInformation() {
+  if (!isUsedField("neighbors")) {
+    return;
+  }
+
+  for(map<int, TremoloAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
+    currentInfo != additionalAtomData.end(); currentInfo++
+  ) {
+    for(vector<int>::iterator neighbor = currentInfo->second.neighbors.begin();
+      neighbor != currentInfo->second.neighbors.end(); neighbor++
+    ) {
+      World::getInstance().getAtom(AtomById(currentInfo->first))
+          ->addBond(World::getInstance().getAtom(AtomById(atomIdMap[*neighbor])));
+    }
+  }
+}
+
+/**
+ * Replaces atom IDs read from the file by the corresponding world IDs. All IDs
+ * IDs of the input string will be replaced; expected separating characters are
+ * "-" and ",".
+ *
+ * \param string in which atom IDs should be adapted
+ *
+ * \return input string with modified atom IDs
+ */
+string TremoloParser::adaptIdDependentDataString(string data) {
+  // there might be no IDs
+  if (data == "-") {
+    return "-";
+  }
+
+  char separator;
+  int id;
+  stringstream line, result;
+  line << data;
+
+  line >> id;
+  result << atomIdMap[id];
+  while (line.good()) {
+    line >> separator >> id;
+    result << separator << atomIdMap[id];
+  }
+
+  return result.str();
+}
+
+/**
+ * Corrects the atom IDs in each imprData entry to the corresponding world IDs
+ * as they might differ from the originally read IDs.
+ */
+void TremoloParser::adaptImprData() {
+  if (!isUsedField("imprData")) {
+    return;
+  }
+
+  for(map<int, TremoloAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
+    currentInfo != additionalAtomData.end(); currentInfo++
+  ) {
+    currentInfo->second.imprData = adaptIdDependentDataString(currentInfo->second.imprData);
+  }
+}
+
+/**
+ * Corrects the atom IDs in each torsion entry to the corresponding world IDs
+ * as they might differ from the originally read IDs.
+ */
+void TremoloParser::adaptTorsion() {
+  if (!isUsedField("torsion")) {
+    return;
+  }
+
+  for(map<int, TremoloAtomInfoContainer>::iterator currentInfo = additionalAtomData.begin();
+    currentInfo != additionalAtomData.end(); currentInfo++
+  ) {
+    currentInfo->second.torsion = adaptIdDependentDataString(currentInfo->second.torsion);
+  }
+}
+
+
+TremoloAtomInfoContainer::TremoloAtomInfoContainer() {
+  F = "0";
+  stress = "0";
+  imprData = "-";
+  GroupMeasureTypeNo = "0";
+  extType = "-";
+  name = "-";
+  resName = "-";
+  chainID = "0";
+  resSeq = "0";
+  occupancy = "0";
+  tempFactor = "0";
+  segID = "0";
+  Charge = "0";
+  charge = "0";
+  GrpTypeNo = "0";
+  torsion = "-";
+  neighbors = vector<int>(0, 5);
+}
+
+void TremoloAtomInfoContainer::set(TremoloKey::atomDataKey key, string value) {
+  switch (key) {
+    case TremoloKey::F :
+      F = value;
+      break;
+    case TremoloKey::stress :
+      stress = value;
+     break;
+    case TremoloKey::imprData :
+      imprData = value;
+      break;
+    case TremoloKey::GroupMeasureTypeNo :
+      GroupMeasureTypeNo = value;
+      break;
+    case TremoloKey::extType :
+      extType = value;
+      break;
+    case TremoloKey::name :
+      name = value;
+      break;
+    case TremoloKey::resName :
+      resName = value;
+      break;
+    case TremoloKey::chainID :
+      chainID = value;
+      break;
+    case TremoloKey::resSeq :
+      resSeq = value;
+      break;
+    case TremoloKey::occupancy :
+      occupancy = value;
+      break;
+    case TremoloKey::tempFactor :
+      tempFactor = value;
+      break;
+    case TremoloKey::segID :
+      segID = value;
+      break;
+    case TremoloKey::Charge :
+      Charge = value;
+      break;
+    case TremoloKey::charge :
+      charge = value;
+      break;
+    case TremoloKey::GrpTypeNo :
+      GrpTypeNo = value;
+      break;
+    case TremoloKey::torsion :
+      torsion = value;
+      break;
+    default :
+      cout << "Unknown key: " << key << ", value: " << value << endl;
+      break;
+  }
+}
+
+string TremoloAtomInfoContainer::get(TremoloKey::atomDataKey key) {
+  switch (key) {
+    case TremoloKey::F :
+      return F;
+    case TremoloKey::stress :
+      return stress;
+    case TremoloKey::imprData :
+      return imprData;
+    case TremoloKey::GroupMeasureTypeNo :
+      return GroupMeasureTypeNo;
+    case TremoloKey::extType :
+      return extType;
+    case TremoloKey::name :
+      return name;
+    case TremoloKey::resName :
+      return resName;
+    case TremoloKey::chainID :
+      return chainID;
+    case TremoloKey::resSeq :
+      return resSeq;
+    case TremoloKey::occupancy :
+      return occupancy;
+    case TremoloKey::tempFactor :
+      return tempFactor;
+    case TremoloKey::segID :
+      return segID;
+    case TremoloKey::Charge :
+      return Charge;
+    case TremoloKey::charge :
+      return charge;
+    case TremoloKey::GrpTypeNo :
+      return GrpTypeNo;
+    case TremoloKey::torsion :
+      return torsion;
+    default :
+      cout << "Unknown key: " << key << endl;
+      return "";
+  }
+}
+
Index: src/Parser/TremoloParser.hpp
===================================================================
--- src/Parser/TremoloParser.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/TremoloParser.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,125 @@
+/*
+ * TremoloParser.hpp
+ *
+ *  Created on: Mar 2, 2010
+ *      Author: metzler
+ */
+
+#ifndef TREMOLOPARSER_HPP_
+#define TREMOLOPARSER_HPP_
+
+#include <string>
+#include "FormatParser.hpp"
+
+/**
+ * Known keys for the ATOMDATA line.
+ */
+class TremoloKey {
+public:
+  enum atomDataKey {
+    noKey,
+    x,
+    u,
+    F,
+    stress,
+    Id,
+    neighbors,
+    imprData,
+    GroupMeasureTypeNo,
+    Type,
+    extType,
+    name,
+    resName,
+    chainID,
+    resSeq,
+    occupancy,
+    tempFactor,
+    segID,
+    Charge,
+    charge,
+    GrpTypeNo,
+    torsion
+  };
+};
+
+/**
+ * Holds tremolo-specific information which is not store in the atom class.
+ */
+class TremoloAtomInfoContainer {
+public:
+  TremoloAtomInfoContainer();
+  void set(TremoloKey::atomDataKey key, std::string value);
+  std::string get(TremoloKey::atomDataKey key);
+  std::string F;
+  std::string stress;
+  std::string imprData;
+  std::string GroupMeasureTypeNo;
+  std::string extType;
+  std::string name;
+  std::string resName;
+  std::string chainID;
+  std::string resSeq;
+  std::string occupancy;
+  std::string tempFactor;
+  std::string segID;
+  std::string Charge;
+  std::string charge;
+  std::string GrpTypeNo;
+  std::string torsion;
+  std::vector<int> neighbors;
+};
+
+/**
+ * Loads a tremolo file into the World and saves the World as a tremolo file.
+ */
+class TremoloParser : public FormatParser
+{
+public:
+  TremoloParser();
+  ~TremoloParser();
+  void load(std::istream* file);
+  void save(std::ostream* file);
+  void setFieldsForSave(std::string atomDataLine);
+
+
+private:
+  void readAtomDataLine(string line);
+  void parseAtomDataKeysLine(string line, int offset);
+  void readNeighbors(std::stringstream* line, int numberOfNeighbors, int atomId);
+  void processNeighborInformation();
+  void adaptImprData();
+  void adaptTorsion();
+  std::string adaptIdDependentDataString(std::string data);
+  bool isUsedField(std::string fieldName);
+  void writeNeighbors(std::ostream* file, int numberOfNeighbors, atom* currentAtom);
+  void saveLine(std::ostream* file, atom* currentAtom);
+
+  /**
+   * Map to associate the known keys with numbers.
+   */
+  std::map<std::string, TremoloKey::atomDataKey> knownKeys;
+
+  /**
+   * Fields used in the tremolo file.
+   */
+  std::vector<std::string> usedFields;
+
+  /**
+   * Data which is currently not stored in atoms but was provided by the input
+   * file.
+   */
+  std::map<int, TremoloAtomInfoContainer> additionalAtomData;
+
+  /**
+   * Default additional atom data.
+   */
+  TremoloAtomInfoContainer defaultAdditionalData;
+
+  /**
+   * Maps original atom IDs received from the parsed file to atom IDs in the
+   * world.
+   */
+  std::map<int, int> atomIdMap;
+};
+
+#endif /* TREMOLOPARSER_HPP_ */
Index: src/Parser/XyzParser.cpp
===================================================================
--- src/Parser/XyzParser.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/XyzParser.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,64 @@
+/*
+ * XyzParser.cpp
+ *
+ *  Created on: Mar 2, 2010
+ *      Author: metzler
+ */
+
+#include "XyzParser.hpp"
+#include "World.hpp"
+#include "atom.hpp"
+#include "element.hpp"
+#include "periodentafel.hpp"
+
+using namespace std;
+
+/**
+ * Constructor.
+ */
+XyzParser::XyzParser() {
+  comment = "";
+}
+
+/**
+ * Destructor.
+ */
+XyzParser::~XyzParser() {
+  delete(&comment);
+}
+
+/**
+ * Loads an XYZ file into the World.
+ *
+ * \param XYZ file
+ */
+void XyzParser::load(istream* file) {
+  atom* newAtom;
+  int numberOfAtoms;
+  char commentBuffer[512], type[3];
+
+  // the first line tells number of atoms, the second line is always a comment
+  *file >> numberOfAtoms >> ws;
+  file->getline(commentBuffer, 512);
+  comment = commentBuffer;
+
+  for (int i = 0; i < numberOfAtoms; i++) {
+    newAtom = World::getInstance().createAtom();
+    *file >> type >> ws >> newAtom->x[0] >> ws >> newAtom->x[1] >> ws >> newAtom->x[2];
+    newAtom->setType(World::getInstance().getPeriode()->FindElement(type));
+  }
+}
+
+/**
+ * Saves the current state of the World into the given XYZ file.
+ *
+ * \param XYZ file
+ */
+void XyzParser::save(ostream* file) {
+  *file << World::getInstance().numAtoms() << endl << comment << endl;
+
+  vector<atom*> atoms = World::getInstance().getAllAtoms();
+  for(vector<atom*>::iterator it = atoms.begin(); it < atoms.end(); it++) {
+    *file << fixed << (*it)->getType()->symbol << "\t" << (*it)->x[0] << "\t" << (*it)->x[1] << "\t" << (*it)->x[2] << endl;
+  }
+}
Index: src/Parser/XyzParser.hpp
===================================================================
--- src/Parser/XyzParser.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/Parser/XyzParser.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,28 @@
+/*
+ * XyzParser.hpp
+ *
+ *  Created on: Mar 2, 2010
+ *      Author: metzler
+ */
+
+#ifndef XYZPARSER_HPP_
+#define XYZPARSER_HPP_
+
+#include <string>
+#include "FormatParser.hpp"
+
+/**
+ * Parser for XYZ files.
+ */
+class XyzParser : public FormatParser {
+public:
+  XyzParser();
+  ~XyzParser();
+  void load(std::istream* file);
+  void save(std::ostream* file);
+
+private:
+  std::string comment;
+};
+
+#endif /* XYZPARSER_HPP_ */
Index: src/atom_bondedparticle.cpp
===================================================================
--- src/atom_bondedparticle.cpp	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/atom_bondedparticle.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -74,4 +74,20 @@
       *BondFile << nr << "\t" << (*Runner)->GetOtherAtom(this)->nr << "\n";
 };
+
+/**
+ * Adds a bond between this bonded particle and another. Does nothing if this
+ * bond already exists.
+ *
+ * \param bonding partner
+ */
+void BondedParticle::addBond(BondedParticle* Partner) {
+  if (IsBondedTo(Partner)) {
+    return;
+  }
+
+  bond* newBond = new bond((atom*) this, (atom*) Partner, 1, 0);
+  RegisterBond(newBond);
+  Partner->RegisterBond(newBond);
+}
 
 /** Puts a given bond into atom::ListOfBonds.
Index: src/atom_bondedparticle.hpp
===================================================================
--- src/atom_bondedparticle.hpp	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/atom_bondedparticle.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -37,4 +37,5 @@
   virtual ~BondedParticle();
 
+  void addBond(BondedParticle* Partner);
   bool RegisterBond(bond *Binder);
   bool UnregisterBond(bond *Binder);
Index: src/atom_particleinfo.cpp
===================================================================
--- src/atom_particleinfo.cpp	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/atom_particleinfo.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -16,5 +16,8 @@
     nr(pointer->nr),
     Name(pointer->Name)
-    {}
+    {
+      if (Name == NULL)
+        Name = " ";
+    }
 
 
Index: src/bond.cpp
===================================================================
--- src/bond.cpp	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/bond.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -15,5 +15,7 @@
 /** Empty Constructor for class bond.
  */
-bond::bond() : leftatom(NULL), rightatom(NULL), previous(NULL), next(NULL), HydrogenBond(0), BondDegree(0), nr(-1), Cyclic(false), Type(Undetermined), Used(white)
+bond::bond()
+  : leftatom(NULL), rightatom(NULL), previous(NULL), next(NULL), HydrogenBond(0),
+    BondDegree(0), nr(-1), Cyclic(false), Type(Undetermined), Used(white)
 {
 };
@@ -25,5 +27,7 @@
  * \param number increasing index
  */
-bond::bond(atom *left, atom *right, const int degree, const int number) : leftatom(left), rightatom(right), previous(NULL), next(NULL), HydrogenBond(0), BondDegree(degree), nr(number), Cyclic(false), Type(Undetermined), Used(white)
+bond::bond(atom *left, atom *right, const int degree, const int number)
+  : leftatom(left), rightatom(right), previous(NULL), next(NULL), HydrogenBond(0),
+    BondDegree(degree), nr(number), Cyclic(false), Type(Undetermined), Used(white)
 {
   if ((left != NULL) && (right != NULL)) {
Index: src/unittests/Makefile.am
===================================================================
--- src/unittests/Makefile.am	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/unittests/Makefile.am	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -32,4 +32,5 @@
   PlaneUnittest \
   ObserverTest \
+  ParserUnitTest \
   SingletonTest \
   StackClassUnitTest \
@@ -73,4 +74,5 @@
   PlaneUnittest.cpp \
   ObserverTest.cpp \
+  ParserUnitTest.cpp \
   SingletonTest.cpp \
   stackclassunittest.cpp \
@@ -204,4 +206,7 @@
 AtomDescriptorTest_LDADD = ${ALLLIBS}
 
+ParserUnitTest_SOURCES = UnitTestMain.cpp ParserUnitTest.cpp ParserUnitTest.hpp
+ParserUnitTest_LDADD = ${ALLLIBS}
+
 manipulateAtomsTest_SOURCES = UnitTestMain.cpp manipulateAtomsTest.cpp manipulateAtomsTest.hpp
 manipulateAtomsTest_LDADD = ${ALLLIBS}
Index: src/unittests/ParserUnitTest.cpp
===================================================================
--- src/unittests/ParserUnitTest.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/unittests/ParserUnitTest.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,186 @@
+/*
+ * ParserUnitTest.cpp
+ *
+ *  Created on: Mar 3, 2010
+ *      Author: metzler
+ */
+
+#include "ParserUnitTest.hpp"
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "Parser/XyzParser.hpp"
+#include "Parser/TremoloParser.hpp"
+#include "World.hpp"
+#include "atom.hpp"
+#include "element.hpp"
+#include "periodentafel.hpp"
+#include "Descriptors/AtomTypeDescriptor.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+using namespace std;
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( ParserUnitTest );
+
+
+void ParserUnitTest::setUp() {
+  element* oxygen = new element();
+  oxygen->symbol[0] = 'O';
+  oxygen->Z = 8;
+  World::getInstance().getPeriode()->AddElement(oxygen);
+
+  element* hydrogen = new element();
+  hydrogen->symbol[0] = 'H';
+  hydrogen->Z = 1;
+  World::getInstance().getPeriode()->AddElement(hydrogen);
+}
+
+void ParserUnitTest::tearDown() {
+  World::purgeInstance();
+}
+
+/************************************ tests ***********************************/
+
+void ParserUnitTest::rewriteAnXyzTest() {
+  cout << "Testing the XYZ parser." << endl;
+  XyzParser* testParser = new XyzParser();
+  string waterXyz = "3\nH2O: water molecule\nO\t0.000000\t0.000000\t0.000000\nH\t0.758602\t0.000000\t0.504284\nH\t0.758602\t0.000000\t-0.504284\n";
+  stringstream input;
+  input << waterXyz;
+  testParser->load(&input);
+
+  CPPUNIT_ASSERT_EQUAL(3, World::getInstance().numAtoms());
+
+  string newWaterXyz = "";
+  stringstream output;
+  testParser->save(&output);
+  newWaterXyz = output.str();
+
+  CPPUNIT_ASSERT(waterXyz == newWaterXyz);
+}
+
+void ParserUnitTest::readTremoloPreliminaryCommentsTest() {
+  cout << "Testing the tremolo parser." << endl;
+  TremoloParser* testParser = new TremoloParser();
+  stringstream input, output;
+  string waterTremolo;
+
+  // Atomdata beginning with "# ATOMDATA"
+  waterTremolo = "# ATOMDATA\tId\tname\tType\tx=3\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  testParser->save(&output);
+  CPPUNIT_ASSERT(waterTremolo == output.str());
+  input.clear();
+  output.clear();
+
+  // Atomdata beginning with "#ATOMDATA"
+  waterTremolo = "#\n#ATOMDATA Id name Type x=3\n1 hydrogen H 3.0 4.5 0.1\n\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  testParser->save(&output);
+  CPPUNIT_ASSERT(output.str().find("hydrogen") != string::npos);
+  input.clear();
+  output.clear();
+
+  // Invalid key in Atomdata line
+  waterTremolo = "#\n#ATOMDATA Id name foo Type x=3\n\n\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  //TODO: proove invalidity
+  input.clear();
+}
+
+void ParserUnitTest::readTremoloCoordinatesTest() {
+  TremoloParser* testParser = new TremoloParser();
+  stringstream input;
+  string waterTremolo;
+
+  // One simple data line
+  waterTremolo = "#\n#ATOMDATA Id name Type x=3\n1 hydrogen H 3.0 4.5 0.1\n\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  CPPUNIT_ASSERT(World::getInstance().getAtom(AtomByType(1))->x[0] == 3.0);
+  input.clear();
+}
+
+void ParserUnitTest::readTremoloVelocityTest() {
+  TremoloParser* testParser = new TremoloParser();
+  stringstream input;
+  string waterTremolo;
+
+  // One simple data line
+  waterTremolo = "#\n#ATOMDATA Id name Type u=3\n1 hydrogen H 3.0 4.5 0.1\n\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  CPPUNIT_ASSERT(World::getInstance().getAtom(AtomByType(1))->v[0] == 3.0);
+  input.clear();
+}
+
+void ParserUnitTest::readTremoloNeighborInformationTest() {
+  TremoloParser* testParser = new TremoloParser();
+  stringstream input;
+  string waterTremolo;
+
+  // Neighbor data
+  waterTremolo = "#\n#ATOMDATA Id Type neighbors=2\n1 H 3 0\n2 H 3 0\n3 O 1 2\n";
+  input << waterTremolo;
+  testParser->load(&input);
+
+  CPPUNIT_ASSERT_EQUAL(3, World::getInstance().numAtoms());
+  CPPUNIT_ASSERT(World::getInstance().getAtom(AtomByType(8))->
+      IsBondedTo(World::getInstance().getAtom(AtomByType(1))));
+  input.clear();
+}
+
+void ParserUnitTest::readAndWriteTremoloImprDataInformationTest() {
+  TremoloParser* testParser = new TremoloParser();
+  stringstream input, output;
+  string waterTremolo;
+
+  // Neighbor data
+  waterTremolo = "#\n#ATOMDATA Id Type imprData\n8 H 9-10\n9 H 10-8,8-10\n10 O -\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  testParser->save(&output);
+  CPPUNIT_ASSERT_EQUAL(3, World::getInstance().numAtoms());
+  CPPUNIT_ASSERT(output.str().find("2-0,0-2") != string::npos);
+  input.clear();
+  output.clear();
+}
+
+void ParserUnitTest::readAndWriteTremoloTorsionInformationTest() {
+  TremoloParser* testParser = new TremoloParser();
+  stringstream input, output;
+  string waterTremolo;
+
+  // Neighbor data
+  waterTremolo = "#\n#ATOMDATA Id Type torsion\n8 H 9-10\n9 H 10-8,8-10\n10 O -\n";
+  input << waterTremolo;
+  testParser->load(&input);
+  testParser->save(&output);
+  CPPUNIT_ASSERT_EQUAL(3, World::getInstance().numAtoms());
+  CPPUNIT_ASSERT(output.str().find("2-0,0-2") != string::npos);
+  input.clear();
+  output.clear();
+}
+
+void ParserUnitTest::writeTremoloTest() {
+  TremoloParser* testParser = new TremoloParser();
+  stringstream output;
+
+  // with the maximum number of fields and minimal information, default values are printed
+  atom* newAtom = World::getInstance().createAtom();
+  newAtom->type = World::getInstance().getPeriode()->FindElement(1);
+  testParser->setFieldsForSave("x=3 u=3 F stress Id neighbors=5 imprData GroupMeasureTypeNo Type extType name resName chainID resSeq occupancy tempFactor segID Charge charge GrpTypeNo torsion");
+  testParser->save(&output);
+  CPPUNIT_ASSERT(output.str() == "# ATOMDATA\tx=3\tu=3\tF\tstress\tId\tneighbors=5\timprData\tGroupMeasureTypeNo\tType\textType\tname\tresName\tchainID\tresSeq\toccupancy\ttempFactor\tsegID\tCharge\tcharge\tGrpTypeNo\ttorsion\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t-\t0\tH\t-\t-\t-\t0\t0\t0\t0\t0\t0\t0\t0\t-\t\n");
+
+  cout << "testing the tremolo parser is done" << endl;
+}
Index: src/unittests/ParserUnitTest.hpp
===================================================================
--- src/unittests/ParserUnitTest.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
+++ src/unittests/ParserUnitTest.hpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -0,0 +1,40 @@
+/*
+ * ParserUnitTest.hpp
+ *
+ *  Created on: Mar 3, 2010
+ *      Author: metzler
+ */
+#ifndef PARSERUNITTEST_HPP_
+#define PARSERUNITTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <string>
+
+class ParserUnitTest :  public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( ParserUnitTest ) ;
+  CPPUNIT_TEST ( rewriteAnXyzTest );
+  CPPUNIT_TEST ( readTremoloPreliminaryCommentsTest );
+  CPPUNIT_TEST ( readTremoloCoordinatesTest );
+  CPPUNIT_TEST ( readTremoloVelocityTest );
+  CPPUNIT_TEST ( readTremoloNeighborInformationTest );
+  CPPUNIT_TEST ( readAndWriteTremoloImprDataInformationTest );
+  CPPUNIT_TEST ( readAndWriteTremoloTorsionInformationTest );
+  CPPUNIT_TEST ( writeTremoloTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void rewriteAnXyzTest();
+  void readTremoloPreliminaryCommentsTest();
+  void readTremoloCoordinatesTest();
+  void readTremoloVelocityTest();
+  void readTremoloNeighborInformationTest();
+  void readAndWriteTremoloImprDataInformationTest();
+  void readAndWriteTremoloTorsionInformationTest();
+  void writeTremoloTest();
+};
+
+#endif /* PARSERUNITTEST_HPP_ */
Index: src/unittests/SingletonTest.cpp
===================================================================
--- src/unittests/SingletonTest.cpp	(revision bdedb126fe1a1073239174c61698ac3e49dc53b1)
+++ src/unittests/SingletonTest.cpp	(revision b9b604056c3887ec9d83c4814e5d8b0c68daabc1)
@@ -52,5 +52,5 @@
     count1++;
   }
-  // explicit copy constructor to catch if thsi is ever called
+  // explicit copy constructor to catch if this is ever called
   SingletonStub2(const SingletonStub2&){
     CPPUNIT_FAIL    ( "Copy constructor of Singleton called" );
