Index: src/World.cpp
===================================================================
--- src/World.cpp	(revision 1c51c861e1b8694410e5e4704ed0144951b98c2e)
+++ src/World.cpp	(revision 88d5869468621298db2b33f61023ef4301fd78eb)
@@ -86,7 +86,6 @@
 atom *World::createAtom(){
   OBSERVE;
-  atom *res = NewAtom();
-  assert(!atoms.count(currAtomId));
-  res->setId(currAtomId++);
+  atomId_t id = getNextAtomId();
+  atom *res = NewAtom(id);
   res->setWorld(this);
   // store the atom by ID
@@ -97,6 +96,6 @@
 int World::registerAtom(atom *atom){
   OBSERVE;
-  assert(!atoms.count(currAtomId));
-  atom->setId(currAtomId++);
+  atomId_t id = getNextAtomId();
+  atom->setId(id);
   atom->setWorld(this);
   atoms[atom->getId()] = atom;
@@ -116,4 +115,26 @@
   DeleteAtom(atom);
   atoms.erase(id);
+  releaseAtomId(id);
+}
+
+bool World::changeAtomId(atomId_t oldId, atomId_t newId, atom* target){
+  OBSERVE;
+  // in case this call did not originate from inside the atom, we redirect it,
+  // to also let it know that it has changed
+  if(!target){
+    target = atoms[oldId];
+    assert(target && "Atom with that ID not found");
+    return target->changeId(newId);
+  }
+  else{
+    if(reserveAtomId(newId)){
+      atoms.erase(oldId);
+      atoms.insert(pair<atomId_t,atom*>(newId,target));
+      return true;
+    }
+    else{
+      return false;
+    }
+  }
 }
 
@@ -136,5 +157,46 @@
   proc->signOff(this);
 }
-
+/******************************* IDManagement *****************************/
+
+atomId_t World::getNextAtomId(){
+  // see if we can reuse some Id
+  if(atomIdPool.empty()){
+    return currAtomId++;
+  }
+  else{
+    // we give out the first ID from the pool
+    atomId_t id = *(atomIdPool.begin());
+    atomIdPool.erase(id);
+  }
+}
+
+void World::releaseAtomId(atomId_t id){
+  atomIdPool.insert(id);
+  // defragmentation of the pool
+  set<atomId_t>::reverse_iterator iter;
+  // go through all Ids in the pool that lie immediately below the border
+  while(!atomIdPool.empty() && *(atomIdPool.rbegin())==(currAtomId-1)){
+    atomIdPool.erase(--currAtomId);
+  }
+}
+
+bool World::reserveAtomId(atomId_t id){
+  if(id>=currAtomId ){
+    // add all ids between the new one and current border as available
+    for(atomId_t pos=currAtomId; pos<id; ++pos){
+      atomIdPool.insert(pos);
+    }
+    currAtomId=id+1;
+    return true;
+  }
+  else if(atomIdPool.count(id)){
+    atomIdPool.erase(id);
+    return true;
+  }
+  else{
+    // this ID could not be reserved
+    return false;
+  }
+}
 /******************************* Iterators ********************************/
 
Index: src/World.hpp
===================================================================
--- src/World.hpp	(revision 1c51c861e1b8694410e5e4704ed0144951b98c2e)
+++ src/World.hpp	(revision 88d5869468621298db2b33f61023ef4301fd78eb)
@@ -130,4 +130,12 @@
    */
   void destroyAtom(atomId_t);
+
+  /**
+   * used when changing an atom Id.
+   * Unless you are calling this method from inside an atom don't fiddle with the third parameter.
+   *
+   * Return value indicates wether the change could be done or not.
+   */
+  bool changeAtomId(atomId_t oldId, atomId_t newId, atom* target=0);
 
   /**
@@ -226,6 +234,12 @@
 
 private:
+
+  atomId_t getNextAtomId();
+  void releaseAtomId(atomId_t);
+  bool reserveAtomId(atomId_t);
+
   periodentafel *periode;
   AtomSet atoms;
+  std::set<atomId_t> atomIdPool; //<!stores the pool for all available AtomIds below currAtomId
   atomId_t currAtomId; //!< stores the next available Id for atoms
   MoleculeSet molecules;
Index: src/atom.cpp
===================================================================
--- src/atom.cpp	(revision 1c51c861e1b8694410e5e4704ed0144951b98c2e)
+++ src/atom.cpp	(revision 88d5869468621298db2b33f61023ef4301fd78eb)
@@ -290,5 +290,17 @@
 }
 
-void atom::setId(int _id) {
+bool atom::changeId(atomId_t newId){
+  // first we move ourselves in the world
+  // the world lets us know if that succeeded
+  if(world->changeAtomId(id,newId,this)){
+    id = newId;
+    return true;
+  }
+  else{
+    return false;
+  }
+}
+
+void atom::setId(atomId_t _id) {
   id=_id;
 }
@@ -298,9 +310,11 @@
 }
 
-atom* NewAtom(){
-  return new atom();
-}
-
-void  DeleteAtom(atom* atom){
+atom* NewAtom(atomId_t _id){
+  atom * res =new atom();
+  res->setId(_id);
+  return res;
+}
+
+void DeleteAtom(atom* atom){
   delete atom;
 }
Index: src/atom.hpp
===================================================================
--- src/atom.hpp	(revision 1c51c861e1b8694410e5e4704ed0144951b98c2e)
+++ src/atom.hpp	(revision 88d5869468621298db2b33f61023ef4301fd78eb)
@@ -40,5 +40,5 @@
  */
 class atom : public TesselPoint, public TrajectoryParticle, public GraphNode, public BondedParticle, public virtual ParticleInfo, public virtual AtomInfo {
-  friend atom* NewAtom();
+  friend atom* NewAtom(atomId_t);
   friend void  DeleteAtom(atom*);
   public:
@@ -80,5 +80,12 @@
 
   virtual int getId();
-  virtual void setId(int);
+  virtual bool changeId(atomId_t newId);
+
+  /**
+   * this function sets the Id without notifying the world. Only use it, if the world has already
+   * gotten an ID for this Atom.
+   */
+   virtual void setId(atomId_t);
+
   protected:
     /**
@@ -101,5 +108,5 @@
   private:
     World* world;
-    int id;
+    atomId_t id;
 };
 
@@ -109,5 +116,5 @@
  * Use World::createAtom() instead.
  */
-atom* NewAtom();
+atom* NewAtom(atomId_t _id);
 
 /**
