Index: src/Actions/MoleculeAction/CreateMicelleAction.cpp
===================================================================
--- src/Actions/MoleculeAction/CreateMicelleAction.cpp	(revision c88597db2d870358b59615ead9c13f587c938698)
+++ src/Actions/MoleculeAction/CreateMicelleAction.cpp	(revision 473237055cdf05b40bc70aa53d5b35d6960b4daf)
@@ -51,6 +51,4 @@
 #include "Action_impl_pre.hpp"
 
-using namespace std;
-
 #include "UIElements/UIFactory.hpp"
 #include "UIElements/Dialog.hpp"
@@ -71,31 +69,35 @@
   // we don't need to create one and add them all to it
   MoleculeVector all = World::getInstance().getSelectedMolecules();
-  ASSERT(!all.empty(), "MoleculeCreateMicelleAction::performCall() - no molecules selected.");
+
+  // return success when none are selected
+  if (all.empty())
+    return Action::success;
+
+  // check that there is precisely one molecule
+  ASSERT(all.size() == 1,
+      "MoleculeCreateMicelleAction::performCall() - more than one molecule selected, this is not supported.");
+
   molecule *stick = *(all.begin());
 
+
+  // create undo state for original molecule
+  std::vector<Vector> stickPositions;
+  for (molecule::const_iterator iter = stick->begin(); iter != stick->end(); ++iter)
+    stickPositions.push_back((*iter)->getPosition());
+
+  // determine principal axis system and rotate such that greatest extension is along z axis
+  if(stick->size() > 1) { // only rotate if more than one molecule present
+    Vector den(0.0,0.0,1.0);
+
+    MoleculeRotateToPrincipalAxisSystem(den);
+  }
+
   // center molecule
-
   stick->CenterOrigin();
 
-  // determine principal axis system and rotate such that greatest extension is along z axis
-  Vector den(0.0,0.0,1.0);
-
-  MoleculeRotateToPrincipalAxisSystem(den);
-  /* determine
-  principal axis system and make greatest eigenvector be aligned along
-  (0,0,1)
-  */
-  string path;
-
-  Line RotationAxis(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0)); // pt is the current Vector of point on surface
-
-  //for (molecule::iterator it=stick->begin(); it !=stick->end(); ++it)
-    //(*it)->setPosition(RotationAxis.rotateVector((*it)->getPosition(),M_PI));
-
   /// Align molecule with its PAS multiple times with the some surface
 
   // get points on surface
 
-  int ka =0;
   //double radius= 1.5*sqrt(pow(1.55, 2)*params.N);
 
@@ -104,31 +106,42 @@
 
   // mirror along x-y plane
+
+  // additionally invert molecule if desired
+  if (params.DoRotate) {
+    for (molecule::iterator it2=stick->begin();it2 !=stick->end();++it2)
+    {
+      Vector pos= (**it2).getPosition();
+      pos[2]= - pos[2];// -Min[2]
+      (**it2).setPosition(pos);
+    }
+  }
+
+  // shift molecule by its extension along z axis
 
   for (molecule::iterator it2=stick->begin();it2 !=stick->end();++it2)
   {
 	  Vector pos= (**it2).getPosition();
-	  pos[2]= - pos[2];// -Min[2]
+	  pos[2]=pos[2]+params.radius;
 	  (**it2).setPosition(pos);
   }
 
-  // shift molecule by its extension along z axis
-
-  for (molecule::iterator it2=stick->begin();it2 !=stick->end();++it2)
-  {
-	  Vector pos= (**it2).getPosition();
-	  pos[2]=pos[2]+params.radius; // -Min[2]
-	  (**it2).setPosition(pos);
-  }
-
   // copy molecule N times and rotate it to point radially away from surface
 
   //double MYEPSILON=1e-10;
 
-  for (ka = 0; ka<pt.size()-1; ka++)
+  // gather created molecules for undo state
+  std::vector<molecule *> CreatedMolecules;
+
+  // TODO: remove this when we do not need MoleculeListClass anymore
+  MoleculeListClass *&molecules = World::getInstance().getMolecules();
+
+  size_t ka = 0;
+  for (; ka<pt.size()-1; ka++)
   {
     LOG(1, "STATUS: Creating " << ka+1 << " copy of tenside molecule 'stick' with " << stick->getAtomCount() << " atoms, ");
-	  molecule *Tensid=stick->CopyMolecule();
-
-	  LOG(2, "INFO: Rotating ... ");
+    molecule *Tensid=stick->CopyMolecule();
+    molecules->insert(Tensid);
+    CreatedMolecules.push_back(Tensid);
+
     Vector ZAxis(Vector(0.0,0.0,1.0));
     Vector Axis(pt[ka]);
@@ -136,4 +149,5 @@
     Axis.VectorProduct(ZAxis);
     Line RotationAxis(Vector(0.0,0.0,1.0), Axis);	// pt is the current Vector of point on surface
+    LOG(2, "INFO: Rotating along axis " << RotationAxis << " by angle " << alpha << ".");
 
     for (molecule::iterator it2=Tensid->begin();it2 !=Tensid->end();++it2)
@@ -142,5 +156,4 @@
       *(*it2)+=params.center;
     }
-    LOG(2, "INFO: \tdone.");
 
     Tensid=NULL;
@@ -148,51 +161,77 @@
 
   // shift molecule at given position on surface
-
-  LOG(1, "STATUS: Shifting " << ka+1 << " copy of tenside molecule, ");
-  molecule *Tensid=stick;
-  LOG(2, "INFO: Rotating ...");
-  Vector ZAxis(Vector(0.0,0.0,1.0));
-  Vector Axis(pt[pt.size()-1]);
-  const double alpha = ZAxis.Angle(Axis);
-  Axis.VectorProduct(ZAxis);
-  Line RotationAxis2(Vector(0.0,0.0,1.0), Axis);	// pt is the current Vector of point on surface
-
-  for (molecule::iterator it2=Tensid->begin();it2 !=Tensid->end();++it2)
   {
-    (*it2)->setPosition(RotationAxis.rotateVector((*it2)->getPosition(),alpha));
-    *(*it2)+=params.center;
-  }
-  LOG(2, "INFO: \tdone.");
-
-  Tensid=NULL;
-
-  return Action::success;
+    LOG(1, "STATUS: Shifting " << ka+1 << " copy of tenside molecule 'stick' with " << stick->getAtomCount() << " atoms, ");
+    molecule *Tensid=stick;
+    // this molecule was present before, hence do not remove it!
+    //CreatedMolecules.push_back(Tensid);
+
+    Vector ZAxis(Vector(0.0,0.0,1.0));
+    Vector Axis(pt[pt.size()-1]);
+    const double alpha = ZAxis.Angle(Axis);
+    Axis.VectorProduct(ZAxis);
+    Line RotationAxis(Vector(0.0,0.0,1.0), Axis);	// pt is the current Vector of point on surface
+    LOG(2, "INFO: Rotating along axis " << RotationAxis << " by angle " << alpha << ".");
+
+    for (molecule::iterator it2=Tensid->begin();it2 !=Tensid->end();++it2)
+    {
+      (*it2)->setPosition(RotationAxis.rotateVector((*it2)->getPosition(),alpha));
+      *(*it2)+=params.center;
+    }
+  }
+
+
+  return Action::state_ptr(new MoleculeCreateMicelleState(CreatedMolecules, stick, stickPositions, params));
 }
 
 Action::state_ptr MoleculeCreateMicelleAction::performUndo(Action::state_ptr _state)
 {
-  //  MoleculeFillVoidWithMoleculeState *state = assert_cast<MoleculeFillVoidWithMoleculeState*>(_state.());
-
-  //  string newName = state->mol->Name();
-  //  state->mol->setName(state->lastName);
-
+  MoleculeCreateMicelleState *state = assert_cast<MoleculeCreateMicelleState*>(_state.get());
+
+  // removing all created molecules
+  MoleculeListClass *&molecules = World::getInstance().getMolecules();
+  LOG(0, "STATUS: Removing " << state->CreatedMolecules.size() << " molecules again.");
+  for(std::vector<molecule *>::const_iterator iter = state->CreatedMolecules.begin();
+     iter != state->CreatedMolecules.end();
+     ++iter) {
+    LOG(2, "INFO: Removing " << (*iter)->getName());
+    for(molecule::iterator AtomRunner = (*iter)->begin();
+      !(*iter)->empty();
+      AtomRunner = (*iter)->begin()) {
+      World::getInstance().destroyAtom(*AtomRunner);
+    }
+    //LOG(3, "INFO: molecules contains still " << molecules->ListOfMolecules.size() << " molecules.");
+    molecules->erase(*iter);
+    World::getInstance().destroyMolecule(*iter);
+  }
+  
+  // undo changes to original molecule
+  ASSERT(state->stickPositions.size() == state->stick->size(),
+      "MoleculeCreateMicelleAction::performUndo() - number of stored positions ("
+      +toString(state->stickPositions.size())+") and number of atoms ("
+      +toString(state->stick->size())+") do not match.");
+  std::vector<Vector>::const_iterator PosIter = state->stickPositions.begin();
+  molecule::iterator iter = state->stick->begin();
+  for (; iter != state->stick->end(); ++iter, ++PosIter)
+    (*iter)->setPosition(*PosIter);
+
+  return Action::state_ptr(_state);
+}
+
+Action::state_ptr MoleculeCreateMicelleAction::performRedo(Action::state_ptr _state)
+{
+  LOG(0, "STATUS: CreateMicelleAction::performRedo() is nit implemented yet.");
   return Action::failure;
 }
 
-Action::state_ptr MoleculeCreateMicelleAction::performRedo(Action::state_ptr _state)
-{
-  // Undo and redo have to do the same for this action
-  return performUndo(_state);
-}
-
 
 bool MoleculeCreateMicelleAction::canUndo()
 {
-  return false;
+  return true;
 }
 
 bool MoleculeCreateMicelleAction::shouldUndo()
 {
-  return false;
+  return true;
 }
 
