Index: src/Actions/WorldAction/CenterInBoxAction.cpp
===================================================================
--- src/Actions/WorldAction/CenterInBoxAction.cpp	(revision e670e4be73c7724177f5fef761653d7f8432d689)
+++ src/Actions/WorldAction/CenterInBoxAction.cpp	(revision 23526ca91bfbf2679afc5840c9ee7c434447dce7)
@@ -18,8 +18,16 @@
 #endif
 
+// include headers that implement a archive in simple text format
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include "boost/serialization/vector.hpp"
+
 #include "CodePatterns/MemDebug.hpp"
+
+#include <boost/shared_ptr.hpp>
 
 #include "Box.hpp"
 #include "CodePatterns/Log.hpp"
+#include "LinearAlgebra/MatrixContent.hpp"
 #include "LinearAlgebra/RealSpaceMatrix.hpp"
 #include "molecule.hpp"
@@ -28,4 +36,5 @@
 #include <iostream>
 #include <string>
+#include <vector>
 
 #include "Actions/WorldAction/CenterInBoxAction.hpp"
@@ -41,9 +50,30 @@
   getParametersfromValueStorage();
 
+  // create undo state
+  std::stringstream undostream;
+  boost::archive::text_oarchive oa(undostream);
+  RealSpaceMatrix matrix(World::getInstance().getDomain().getM());
+  oa << matrix;
+  std::vector< boost::shared_ptr<Vector> > OldPositions;
+  std::vector<molecule*> AllMolecules = World::getInstance().getAllMolecules();
+  for (std::vector<molecule*>::iterator MolRunner = AllMolecules.begin();
+      MolRunner != AllMolecules.end();
+      ++MolRunner) {
+    for(molecule::const_iterator AtomRunner = (*MolRunner)->begin();
+        AtomRunner != (*MolRunner)->end();
+        ++AtomRunner) {
+      OldPositions.push_back(
+          boost::shared_ptr<Vector>(new Vector(
+              (*AtomRunner)->getPosition()
+              ))
+          );
+    }
+  }
+
+  // set new domain
   World::getInstance().setDomain(params.cell_size.getM());
 
-  // center
-  vector<molecule *> AllMolecules = World::getInstance().getAllMolecules();
-  for (vector<molecule*>::iterator MolRunner = AllMolecules.begin(); MolRunner != AllMolecules.end(); ++MolRunner) {
+  // center atoms
+  for (std::vector<molecule*>::iterator MolRunner = AllMolecules.begin(); MolRunner != AllMolecules.end(); ++MolRunner) {
     (*MolRunner)->CenterInBox();
   }
@@ -52,27 +82,70 @@
   LOG(0, "Box domain is now " << World::getInstance().getDomain().getM());
 
-  return Action::success;
+  // create undo state
+  WorldCenterInBoxState *UndoState =
+      new WorldCenterInBoxState(
+          undostream.str(),
+          OldPositions,
+          params
+          );
+
+  return Action::state_ptr(UndoState);
 }
 
 Action::state_ptr WorldCenterInBoxAction::performUndo(Action::state_ptr _state) {
-//  ParserLoadXyzState *state = assert_cast<ParserLoadXyzState*>(_state.get());
+  WorldCenterInBoxState *state = assert_cast<WorldCenterInBoxState*>(_state.get());
 
-  return Action::failure;
-//  string newName = state->mol->getName();
-//  state->mol->setName(state->lastName);
-//
-//  return Action::state_ptr(new ParserLoadXyzState(state->mol,newName));
+  // restore domain
+  RealSpaceMatrix matrix;
+  std::stringstream undostream(state->undostring);
+  boost::archive::text_iarchive ia(undostream);
+  ia >> matrix;
+  World::getInstance().setDomain(matrix);
+
+  // place atoms on old positions
+  std::vector< boost::shared_ptr<Vector> >::const_iterator OldPositionsIter = state->OldPositions.begin();
+  std::vector<molecule*> AllMolecules = World::getInstance().getAllMolecules();
+  for (std::vector<molecule*>::iterator MolRunner = AllMolecules.begin();
+      MolRunner != AllMolecules.end();
+      ++MolRunner) {
+    for(molecule::const_iterator AtomRunner = (*MolRunner)->begin();
+        AtomRunner != (*MolRunner)->end();
+        ++AtomRunner) {
+      ASSERT(OldPositionsIter != state->OldPositions.end(),
+          "WorldBoundInBoxAction::performUndo() - too few positions stored in UndoState.");
+      (*AtomRunner)->setPosition(**(OldPositionsIter++));
+    }
+  }
+
+  // give final box size
+  LOG(0, "Box domain restored to " << World::getInstance().getDomain().getM());
+
+  return Action::state_ptr(_state);
 }
 
 Action::state_ptr WorldCenterInBoxAction::performRedo(Action::state_ptr _state){
-  return Action::failure;
+  WorldCenterInBoxState *state = assert_cast<WorldCenterInBoxState*>(_state.get());
+
+  // set new domain
+  World::getInstance().setDomain(state->params.cell_size.getM());
+
+  // center atoms
+  std::vector<molecule *> AllMolecules = World::getInstance().getAllMolecules();
+  for (std::vector<molecule*>::iterator MolRunner = AllMolecules.begin(); MolRunner != AllMolecules.end(); ++MolRunner) {
+    (*MolRunner)->CenterInBox();
+  }
+
+  // give final box size
+  LOG(0, "Box domain is again " << World::getInstance().getDomain().getM());
+
+  return Action::state_ptr(_state);
 }
 
 bool WorldCenterInBoxAction::canUndo() {
-  return false;
+  return true;
 }
 
 bool WorldCenterInBoxAction::shouldUndo() {
-  return false;
+  return true;
 }
 /** =========== end of function ====================== */
Index: src/Actions/WorldAction/CenterInBoxAction.def
===================================================================
--- src/Actions/WorldAction/CenterInBoxAction.def	(revision e670e4be73c7724177f5fef761653d7f8432d689)
+++ src/Actions/WorldAction/CenterInBoxAction.def	(revision 23526ca91bfbf2679afc5840c9ee7c434447dce7)
@@ -9,4 +9,6 @@
 #include "Actions/Values.hpp"
 #include "Box.hpp"
+#include "LinearAlgebra/Vector.hpp"
+#include <boost/shared_ptr.hpp>
 
 // i.e. there is an integer with variable name Z that can be found in
@@ -19,6 +21,6 @@
 #define paramreferences (cell_size)
 
-#undef statetypes
-#undef statereferences
+#define statetypes (std::string)(std::vector< boost::shared_ptr<Vector> >)
+#define statereferences (undostring)(OldPositions)
 
 // some defines for all the names, you may use ACTION, STATE and PARAMS
