Index: src/molecule.cpp
===================================================================
--- src/molecule.cpp	(revision 920c708861f3c5528d44b9973722fa719f892ce0)
+++ src/molecule.cpp	(revision 1024cbc27eef62ed70b770868d078bd3df38ada6)
@@ -35,17 +35,11 @@
  * Initialises molecule list with correctly referenced start and end, and sets molecule::last_atom to zero.
  */
-molecule::molecule(const periodentafel * const teil) : elemente(teil), start(World::getInstance().createAtom()), end(World::getInstance().createAtom()),
-  first(new bond(start, end, 1, -1)), last(new bond(start, end, 1, -1)), MDSteps(0), AtomCount(0), 
+molecule::molecule(const periodentafel * const teil) : elemente(teil),
+  first(new bond(0, 0, 1, -1)), last(new bond(0, 0, 1, -1)), MDSteps(0),
   BondCount(0), ElementCount(0), NoNonHydrogen(0), NoNonBonds(0), NoCyclicBonds(0), BondDistance(0.), 
   ActiveFlag(false), IndexNr(-1),
   formula(this,boost::bind(&molecule::calcFormula,this)),
-  last_atom(0),
-  InternalPointer(start)
-{
-  // init atom chain list
-  start->father = NULL;
-  end->father = NULL;
-  link(start,end);
-
+  AtomCount(this,boost::bind(&molecule::doCountAtoms,this)), last_atom(0),  InternalPointer(begin())
+{
   // init bond chain list
   link(first,last);
@@ -69,6 +63,4 @@
   delete(first);
   delete(last);
-  end->getWorld()->destroyAtom(end);
-  start->getWorld()->destroyAtom(start);
 };
 
@@ -81,4 +73,8 @@
 const std::string molecule::getName(){
   return std::string(name);
+}
+
+int molecule::getAtomCount() const{
+  return *AtomCount;
 }
 
@@ -104,6 +100,6 @@
   stringstream sstr;
   periodentafel *periode = World::getInstance().getPeriode();
-  for(atom *Walker = start; Walker != end; Walker = Walker->next) {
-    counts[Walker->type->getNumber()]++;
+  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
+    counts[(*iter)->type->getNumber()]++;
   }
   std::map<atomicNumber_t,unsigned int>::reverse_iterator iter;
@@ -115,4 +111,65 @@
 }
 
+/************************** Access to the List of Atoms ****************/
+
+
+molecule::iterator molecule::begin(){
+  return molecule::iterator(atoms.begin(),this);
+}
+
+molecule::const_iterator molecule::begin() const{
+  return atoms.begin();
+}
+
+molecule::iterator molecule::end(){
+  return molecule::iterator(atoms.end(),this);
+}
+
+molecule::const_iterator molecule::end() const{
+  return atoms.end();
+}
+
+bool molecule::empty() const
+{
+  return (begin() == end());
+}
+
+size_t molecule::size() const
+{
+  size_t counter = 0;
+  for (molecule::const_iterator iter = begin(); iter != end (); ++iter)
+    counter++;
+  return counter;
+}
+
+molecule::const_iterator molecule::erase( const_iterator loc )
+{
+  molecule::const_iterator iter = loc;
+  iter--;
+  atoms.erase( loc );
+  return iter;
+}
+
+molecule::const_iterator molecule::erase( atom *& key )
+{
+  cout << "trying to erase atom" << endl;
+  molecule::const_iterator iter = find(key);
+  if (iter != end()){
+    // remove this position and step forward (post-increment)
+    atoms.erase( iter++ );
+  }
+  return iter;
+}
+
+molecule::const_iterator molecule::find ( atom *& key ) const
+{
+  return atoms.find( key );
+}
+
+pair<molecule::iterator,bool> molecule::insert ( atom * const key )
+{
+  pair<atomSet::iterator,bool> res = atoms.insert(key);
+  return pair<iterator,bool>(iterator(res.first,this),res.second);
+}
 
 /** Adds given atom \a *pointer from molecule list.
@@ -123,10 +180,7 @@
 bool molecule::AddAtom(atom *pointer)
 {
-  bool retval = false;
   OBSERVE;
   if (pointer != NULL) {
     pointer->sort = &pointer->nr;
-    pointer->nr = last_atom++;  // increase number within molecule
-    AtomCount++;
     if (pointer->type != NULL) {
       if (ElementsInMolecule[pointer->type->Z] == 0)
@@ -141,7 +195,7 @@
       }
     }
-    retval = add(pointer, end);
-  }
-  return retval;
+    insert(pointer);
+  }
+  return true;
 };
 
@@ -157,12 +211,9 @@
   if (pointer != NULL) {
     atom *walker = pointer->clone();
-    stringstream sstr;
-    sstr << pointer->getName();
-    walker->setName(sstr.str());
+    walker->setName(pointer->getName());
     walker->nr = last_atom++;  // increase number within molecule
-    add(walker, end);
+    insert(walker);
     if ((pointer->type != NULL) && (pointer->type->Z != 1))
       NoNonHydrogen++;
-    AtomCount++;
     retval=walker;
   }
@@ -575,5 +626,4 @@
 
   // copy values
-  copy->CountAtoms();
   copy->CountElements();
   if (first->next != last) {  // if adjaceny list is present
@@ -610,14 +660,18 @@
 {
   bond *Binder = NULL;
-  if ((atom1 != NULL) && (FindAtom(atom1->nr) != NULL) && (atom2 != NULL) && (FindAtom(atom2->nr) != NULL)) {
-    Binder = new bond(atom1, atom2, degree, BondCount++);
-    atom1->RegisterBond(Binder);
-    atom2->RegisterBond(Binder);
-    if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
-      NoNonBonds++;
-    add(Binder, last);
-  } else {
-    DoeLog(1) && (eLog()<< Verbose(1) << "Could not add bond between " << atom1->getName() << " and " << atom2->getName() << " as one or both are not present in the molecule." << endl);
-  }
+
+  // some checks to make sure we are able to create the bond
+  ASSERT(atom1, "First atom in bond-creation was an invalid pointer");
+  ASSERT(atom2, "Second atom in bond-creation was an invalid pointer");
+  ASSERT(FindAtom(atom1->nr),"First atom in bond-creation was not part of molecule");
+  ASSERT(FindAtom(atom2->nr),"Second atom in bond-creation was not parto of molecule");
+
+  Binder = new bond(atom1, atom2, degree, BondCount++);
+  atom1->RegisterBond(Binder);
+  atom2->RegisterBond(Binder);
+  if ((atom1->type != NULL) && (atom1->type->Z != 1) && (atom2->type != NULL) && (atom2->type->Z != 1))
+    NoNonBonds++;
+  add(Binder, last);
+
   return Binder;
 };
@@ -693,7 +747,8 @@
 bool molecule::RemoveAtom(atom *pointer)
 {
+  ASSERT(pointer, "Null pointer passed to molecule::RemoveAtom().");
+  OBSERVE;
   if (ElementsInMolecule[pointer->type->Z] != 0)  { // this would indicate an error
     ElementsInMolecule[pointer->type->Z]--;  // decrease number of atom of this element
-    AtomCount--;
   } else
     DoeLog(1) && (eLog()<< Verbose(1) << "Atom " << pointer->getName() << " is of element " << pointer->type->Z << " but the entry in the table of the molecule is 0!" << endl);
@@ -701,5 +756,6 @@
     ElementCount--;
   RemoveBonds(pointer);
-  return remove(pointer, start, end);
+  erase(pointer);
+  return true;
 };
 
@@ -718,5 +774,5 @@
   if (ElementsInMolecule[pointer->type->Z] == 0)  // was last atom of this element?
     ElementCount--;
-  unlink(pointer);
+  erase(pointer);
   return true;
 };
@@ -727,5 +783,7 @@
 bool molecule::CleanupMolecule()
 {
-  return (cleanup(first,last) && cleanup(start,end));
+  for (molecule::iterator iter = begin(); !empty(); iter = begin())
+      erase(iter);
+  return (cleanup(first,last));
 };
 
@@ -734,9 +792,13 @@
  * \return pointer to atom or NULL
  */
-atom * molecule::FindAtom(int Nr)  const{
-  atom * walker = find(&Nr, start,end);
-  if (walker != NULL) {
+atom * molecule::FindAtom(int Nr)  const
+{
+  molecule::const_iterator iter = begin();
+  for (; iter != end(); ++iter)
+    if ((*iter)->nr == Nr)
+      break;
+  if (iter != end()) {
     //Log() << Verbose(0) << "Found Atom Nr. " << walker->nr << endl;
-    return walker;
+    return (*iter);
   } else {
     DoLog(0) && (Log() << Verbose(0) << "Atom not found in list." << endl);
@@ -868,5 +930,5 @@
     now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
     for (int step=0;step<MDSteps;step++) {
-      *output << AtomCount << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
+      *output << getAtomCount() << "\n\tCreated by molecuilder, step " << step << ", on " << ctime(&now);
       ActOnAllAtoms( &atom::OutputTrajectoryXYZ, output, step );
     }
@@ -885,5 +947,5 @@
   if (output != NULL) {
     now = time((time_t *)NULL);   // Get the system time and put it into 'now' as 'calender time'
-    *output << AtomCount << "\n\tCreated by molecuilder on " << ctime(&now);
+    *output << getAtomCount() << "\n\tCreated by molecuilder on " << ctime(&now);
     ActOnAllAtoms( &atom::OutputXYZLine, output );
     return true;
@@ -895,35 +957,20 @@
  * \param *out output stream for debugging
  */
-void molecule::CountAtoms()
-{
+int molecule::doCountAtoms()
+{
+  int res = size();
   int i = 0;
-  atom *Walker = start;
-  while (Walker->next != end) {
-    Walker = Walker->next;
+  NoNonHydrogen = 0;
+  for (molecule::const_iterator iter = atoms.begin(); iter != atoms.end(); ++iter) {
+    (*iter)->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
+    if ((*iter)->type->Z != 1) // count non-hydrogen atoms whilst at it
+      NoNonHydrogen++;
+    stringstream sstr;
+    sstr << (*iter)->type->symbol << (*iter)->nr+1;
+    (*iter)->setName(sstr.str());
+    Log() << Verbose(3) << "Naming atom nr. " << (*iter)->nr << " " << (*iter)->getName() << "." << endl;
     i++;
   }
-  if ((AtomCount == 0) || (i != AtomCount)) {
-    DoLog(3) && (Log() << Verbose(3) << "Mismatch in AtomCount " << AtomCount << " and recounted number " << i << ", renaming all." << endl);
-    AtomCount = i;
-
-    // count NonHydrogen atoms and give each atom a unique name
-    if (AtomCount != 0) {
-      i=0;
-      NoNonHydrogen = 0;
-      Walker = start;
-      while (Walker->next != end) {
-        Walker = Walker->next;
-        Walker->nr = i;   // update number in molecule (for easier referencing in FragmentMolecule lateron)
-        if (Walker->type->Z != 1) // count non-hydrogen atoms whilst at it
-          NoNonHydrogen++;
-        stringstream sstr;
-        sstr << Walker->type->symbol << Walker->nr+1;
-        Walker->setName(sstr.str());
-        DoLog(3) && (Log() << Verbose(3) << "Naming atom nr. " << Walker->nr << " " << Walker->getName() << "." << endl);
-        i++;
-      }
-    } else
-      DoLog(3) && (Log() << Verbose(3) << "AtomCount is still " << AtomCount << ", thus counting nothing." << endl);
-  }
+  return res;
 };
 
@@ -987,6 +1034,4 @@
   /// first count both their atoms and elements and update lists thereby ...
   //Log() << Verbose(0) << "Counting atoms, updating list" << endl;
-  CountAtoms();
-  OtherMolecule->CountAtoms();
   CountElements();
   OtherMolecule->CountElements();
@@ -995,8 +1040,8 @@
   /// -# AtomCount
   if (result) {
-    if (AtomCount != OtherMolecule->AtomCount) {
-      DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl);
+    if (getAtomCount() != OtherMolecule->getAtomCount()) {
+      DoLog(4) && (Log() << Verbose(4) << "AtomCounts don't match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl);
       result = false;
-    } else Log() << Verbose(4) << "AtomCounts match: " << AtomCount << " == " << OtherMolecule->AtomCount << endl;
+    } else Log() << Verbose(4) << "AtomCounts match: " << getAtomCount() << " == " << OtherMolecule->getAtomCount() << endl;
   }
   /// -# ElementCount
@@ -1035,9 +1080,9 @@
   if (result) {
     DoLog(5) && (Log() << Verbose(5) << "Calculating distances" << endl);
-    Distances = new double[AtomCount];
-    OtherDistances = new double[AtomCount];
+    Distances = new double[getAtomCount()];
+    OtherDistances = new double[getAtomCount()];
     SetIndexedArrayForEachAtomTo ( Distances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);
     SetIndexedArrayForEachAtomTo ( OtherDistances, &atom::nr, &atom::DistanceSquaredToVector, (const Vector &)CenterOfGravity);
-    for(int i=0;i<AtomCount;i++) {
+    for(int i=0;i<getAtomCount();i++) {
       Distances[i] = 0.;
       OtherDistances[i] = 0.;
@@ -1046,17 +1091,17 @@
     /// ... sort each list (using heapsort (o(N log N)) from GSL)
     DoLog(5) && (Log() << Verbose(5) << "Sorting distances" << endl);
-    PermMap = new size_t[AtomCount];
-    OtherPermMap = new size_t[AtomCount];
-    for(int i=0;i<AtomCount;i++) {
+    PermMap = new size_t[getAtomCount()];
+    OtherPermMap = new size_t[getAtomCount()];
+    for(int i=0;i<getAtomCount();i++) {
       PermMap[i] = 0;
       OtherPermMap[i] = 0;
     }
-    gsl_heapsort_index (PermMap, Distances, AtomCount, sizeof(double), CompareDoubles);
-    gsl_heapsort_index (OtherPermMap, OtherDistances, AtomCount, sizeof(double), CompareDoubles);
-    PermutationMap = new int[AtomCount];
-    for(int i=0;i<AtomCount;i++)
+    gsl_heapsort_index (PermMap, Distances, getAtomCount(), sizeof(double), CompareDoubles);
+    gsl_heapsort_index (OtherPermMap, OtherDistances, getAtomCount(), sizeof(double), CompareDoubles);
+    PermutationMap = new int[getAtomCount()];
+    for(int i=0;i<getAtomCount();i++)
       PermutationMap[i] = 0;
     DoLog(5) && (Log() << Verbose(5) << "Combining Permutation Maps" << endl);
-    for(int i=AtomCount;i--;)
+    for(int i=getAtomCount();i--;)
       PermutationMap[PermMap[i]] = (int) OtherPermMap[i];
 
@@ -1064,5 +1109,5 @@
     DoLog(4) && (Log() << Verbose(4) << "Comparing distances" << endl);
     flag = 0;
-    for (int i=0;i<AtomCount;i++) {
+    for (int i=0;i<getAtomCount();i++) {
       DoLog(5) && (Log() << Verbose(5) << "Distances squared: |" << Distances[PermMap[i]] << " - " << OtherDistances[OtherPermMap[i]] << "| = " << fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) << " ?<? " <<  threshold << endl);
       if (fabs(Distances[PermMap[i]] - OtherDistances[OtherPermMap[i]]) > threshold*threshold)
@@ -1100,32 +1145,27 @@
 int * molecule::GetFatherSonAtomicMap(molecule *OtherMolecule)
 {
-  atom *Walker = NULL, *OtherWalker = NULL;
   DoLog(3) && (Log() << Verbose(3) << "Begin of GetFatherAtomicMap." << endl);
-  int *AtomicMap = new int[AtomCount];
-  for (int i=AtomCount;i--;)
+  int *AtomicMap = new int[getAtomCount()];
+  for (int i=getAtomCount();i--;)
     AtomicMap[i] = -1;
   if (OtherMolecule == this) {  // same molecule
-    for (int i=AtomCount;i--;) // no need as -1 means already that there is trivial correspondence
+    for (int i=getAtomCount();i--;) // no need as -1 means already that there is trivial correspondence
       AtomicMap[i] = i;
     DoLog(4) && (Log() << Verbose(4) << "Map is trivial." << endl);
   } else {
     DoLog(4) && (Log() << Verbose(4) << "Map is ");
-    Walker = start;
-    while (Walker->next != end) {
-      Walker = Walker->next;
-      if (Walker->father == NULL) {
-        AtomicMap[Walker->nr] = -2;
+    for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
+      if ((*iter)->father == NULL) {
+        AtomicMap[(*iter)->nr] = -2;
       } else {
-        OtherWalker = OtherMolecule->start;
-        while (OtherWalker->next != OtherMolecule->end) {
-          OtherWalker = OtherWalker->next;
+        for (molecule::const_iterator runner = OtherMolecule->begin(); runner != OtherMolecule->end(); ++runner) {
       //for (int i=0;i<AtomCount;i++) { // search atom
-        //for (int j=0;j<OtherMolecule->AtomCount;j++) {
-          //Log() << Verbose(4) << "Comparing father " << Walker->father << " with the other one " << OtherWalker->father << "." << endl;
-          if (Walker->father == OtherWalker)
-            AtomicMap[Walker->nr] = OtherWalker->nr;
+        //for (int j=0;j<OtherMolecule->getAtomCount();j++) {
+          //Log() << Verbose(4) << "Comparing father " << (*iter)->father << " with the other one " << (*runner)->father << "." << endl;
+          if ((*iter)->father == (*runner))
+            AtomicMap[(*iter)->nr] = (*runner)->nr;
         }
       }
-      DoLog(0) && (Log() << Verbose(0) << AtomicMap[Walker->nr] << "\t");
+      DoLog(0) && (Log() << Verbose(0) << AtomicMap[(*iter)->nr] << "\t");
     }
     DoLog(0) && (Log() << Verbose(0) << endl);
@@ -1161,8 +1201,6 @@
 void molecule::SetIndexedArrayForEachAtomTo ( atom **array, int ParticleInfo::*index) const
 {
-  atom *Walker = start;
-  while (Walker->next != end) {
-    Walker = Walker->next;
-    array[(Walker->*index)] = Walker;
+  for (molecule::const_iterator iter = begin(); iter != end(); ++iter) {
+    array[((*iter)->*index)] = (*iter);
   }
 };
