Index: src/Actions/MoleculeAction/VerletIntegrationAction.cpp
===================================================================
--- src/Actions/MoleculeAction/VerletIntegrationAction.cpp	(revision 7e51e12e82c5637d2660d794f1e024fda52a5aa6)
+++ src/Actions/MoleculeAction/VerletIntegrationAction.cpp	(revision 1e45f1fb84ae30e44c393f19156012e19f962ac3)
@@ -3,4 +3,5 @@
  * Description: creates and alters molecular systems
  * Copyright (C)  2010-2012 University of Bonn. All rights reserved.
+ * Copyright (C)  2013-2014 Frederik Heber. All rights reserved.
  * 
  *
@@ -35,5 +36,7 @@
 #include "CodePatterns/MemDebug.hpp"
 
+#include "Actions/UndoRedoHelpers.hpp"
 #include "Atom/atom.hpp"
+#include "Atom/AtomicInfo.hpp"
 #include "Atom/AtomSet.hpp"
 #include "CodePatterns/Log.hpp"
@@ -53,4 +56,11 @@
 using namespace MoleCuilder;
 
+enum {
+  PositionIndex=0,
+  VelocityIndex=1,
+  ForceIndex=2,
+  MAXINDEX
+} VectorIndexType;
+
 // and construct the stuff
 #include "VerletIntegrationAction.def"
@@ -64,5 +74,5 @@
   }
   // we always operate relative to current time step
-  size_t CurrentStep = WorldTime::getInstance().getTime();
+  const size_t CurrentStep = WorldTime::getInstance().getTime();
   VerletForceIntegration<std::vector<atom *> > Verlet(set, params.Deltat.get(), true);
   // parse forces into next step
@@ -74,30 +84,81 @@
       LOG(2, "File " << params.forcesfile.get() << " found and parsed.");
   }
+
+  // create undo state for all selected atoms (undo info)
+  std::vector<AtomicInfo> UndoInfo;
+  UndoInfo.reserve(set.size());
+  {
+    for (World::AtomSelectionConstIterator iter = World::getInstance().beginAtomSelection();
+        iter != World::getInstance().endAtomSelection();
+        ++iter)
+      UndoInfo.push_back(AtomicInfo(*(iter->second)));
+  }
+
   // perform velocity verlet update
-  bool status = Verlet(CurrentStep+1, 1, 0, params.FixedCenterOfMass.get());
-  if (!status) {
-    ELOG(1, "Velocity verlet failed.");
-    return Action::failure;
-  } else {
-    LOG(2, "DEBUG: Successfully performed updates on velocity and position.");
-    // increment to next time step
-    World::getInstance().setTime(CurrentStep+1);
+  Verlet(CurrentStep+1, 1, 0, params.FixedCenterOfMass.get());
+  LOG(0, "STATUS: Successfully performed updates on velocity and position.");
+  // increment to next time step
+  World::getInstance().setTime(CurrentStep+1);
+
+  // create undo state for all selected atoms (redo info):
+  // we need:
+  // -# forces from last step (possible parsing forces file, already in UndoInfo)
+  // -# velocities from last step (..UpdateU(), already in UndoInfo)
+  // -# current position (..UpdateX())
+  std::vector<Vectors_t> UpdatedStep(MAXINDEX);
+  UpdatedStep[PositionIndex].reserve(set.size());
+  UpdatedStep[VelocityIndex].reserve(set.size());
+  UpdatedStep[ForceIndex].reserve(set.size());
+  {
+    for (World::AtomSelectionConstIterator iter = World::getInstance().beginAtomSelection();
+        iter != World::getInstance().endAtomSelection();
+        ++iter) {
+      UpdatedStep[PositionIndex].push_back(iter->second->getPositionAtStep(CurrentStep+1));
+      UpdatedStep[VelocityIndex].push_back(iter->second->getAtomicVelocityAtStep(CurrentStep));
+      UpdatedStep[ForceIndex].push_back(iter->second->getAtomicForceAtStep(CurrentStep));
+    }
   }
-  return Action::success;
+  MoleculeVerletIntegrationState *UndoState =
+      new MoleculeVerletIntegrationState(UndoInfo, UpdatedStep, params);
+
+  return ActionState::ptr(UndoState);
 }
 
 ActionState::ptr MoleculeVerletIntegrationAction::performUndo(ActionState::ptr _state) {
-//  MoleculeVerletIntegrationState *state = assert_cast<MoleculeVerletIntegrationState*>(_state.get());
+  MoleculeVerletIntegrationState *state =
+      assert_cast<MoleculeVerletIntegrationState*>(_state.get());
 
-//  string newName = state->mol->getName();
-//  state->mol->setName(state->lastName);
+  // go back one step
+  const size_t CurrentStep = WorldTime::getInstance().getTime();
+  World::getInstance().setTime(CurrentStep-1);
 
-  STATUS("Undo of MoleculeVerletIntegrationAction not implemented.");
-  return Action::failure;
+  // remove current step for all modified atoms
+  removeLastStep(getIdsFromAtomicInfo(state->UndoInfo));
+
+  // and set back the old step (forces have been changed)
+  SetAtomsFromAtomicInfo(state->UndoInfo);
+
+  return ActionState::ptr(_state);
 }
 
 ActionState::ptr MoleculeVerletIntegrationAction::performRedo(ActionState::ptr _state){
-  STATUS("Rddo of MoleculeVerletIntegrationAction not implemented.");
-  return Action::failure;
+  MoleculeVerletIntegrationState *state =
+      assert_cast<MoleculeVerletIntegrationState*>(_state.get());
+
+  // set forces and velocities
+  ResetAtomVelocity(state->UndoInfo, state->UpdatedStep[VelocityIndex]);
+  ResetAtomForce(state->UndoInfo, state->UpdatedStep[ForceIndex]);
+
+  // set stored new state
+  addNewStep(state->UndoInfo);
+
+  // add a new time step
+  size_t CurrentStep = WorldTime::getInstance().getTime();
+  World::getInstance().setTime(CurrentStep+1);
+
+  // and set positions of the new step
+  ResetAtomPosition(state->UndoInfo, state->UpdatedStep[PositionIndex]);
+
+  return ActionState::ptr(_state);
 }
 
Index: src/Actions/MoleculeAction/VerletIntegrationAction.def
===================================================================
--- src/Actions/MoleculeAction/VerletIntegrationAction.def	(revision 7e51e12e82c5637d2660d794f1e024fda52a5aa6)
+++ src/Actions/MoleculeAction/VerletIntegrationAction.def	(revision 1e45f1fb84ae30e44c393f19156012e19f962ac3)
@@ -7,5 +7,7 @@
 
 // all includes and forward declarations necessary for non-integral types below
-class MoleculeListClass;
+#include "LinearAlgebra/Vector.hpp"
+#include <vector>
+typedef std::vector<Vector> Vectors_t;
 
 #include "Parameters/Validators/DummyValidator.hpp"
@@ -27,6 +29,6 @@
 (DummyValidator< bool >())
 
-#undef statetypes
-#undef statereferences
+#define statetypes (std::vector<AtomicInfo>)(std::vector<Vectors_t>)
+#define statereferences (UndoInfo)(UpdatedStep)
 
 // some defines for all the names, you may use ACTION, STATE and PARAMS
Index: src/Dynamics/VerletForceIntegration.hpp
===================================================================
--- src/Dynamics/VerletForceIntegration.hpp	(revision 7e51e12e82c5637d2660d794f1e024fda52a5aa6)
+++ src/Dynamics/VerletForceIntegration.hpp	(revision 1e45f1fb84ae30e44c393f19156012e19f962ac3)
@@ -58,8 +58,7 @@
    * \param DoConstrainedMD whether a constrained MD shall be done
    * \param FixedCenterOfMass whether forces and velocities are correct to have fixed center of mass
-   * \return true - file found and parsed, false - no atoms, file not found or imparsable
    * \todo This is not yet checked if it is correctly working with DoConstrainedMD set >0.
    */
-  bool operator()(const int NextStep, const size_t offset, const int DoConstrainedMD, const bool FixedCenterOfMass)
+  void operator()(const int NextStep, const size_t offset, const int DoConstrainedMD, const bool FixedCenterOfMass)
   {
     Info FunctionInfo(__func__);
@@ -104,7 +103,4 @@
           AtomicForceManipulator<T>::IsAngstroem);
     }
-
-    // exit
-    return true;
   }
 };
Index: tests/regression/Molecules/VerletIntegration/post/test-undo.conf
===================================================================
--- tests/regression/Molecules/VerletIntegration/post/test-undo.conf	(revision 1e45f1fb84ae30e44c393f19156012e19f962ac3)
+++ tests/regression/Molecules/VerletIntegration/post/test-undo.conf	(revision 1e45f1fb84ae30e44c393f19156012e19f962ac3)
@@ -0,0 +1,83 @@
+# ParallelCarParinello - main configuration file - created with molecuilder
+
+mainname	pcp	# programm name (for runtime files)
+defaultpath	not specified	# where to put files during runtime
+pseudopotpath	not specified	# where to find pseudopotentials
+
+ProcPEGamma	8	# for parallel computing: share constants
+ProcPEPsi	1	# for parallel computing: share wave functions
+DoOutVis	0	# Output data for OpenDX
+DoOutMes	1	# Output data for measurements
+DoOutOrbitals	0	# Output all Orbitals
+DoOutCurr	0	# Ouput current density for OpenDx
+DoOutNICS	0	# Output Nucleus independent current shieldings
+DoPerturbation	0	# Do perturbation calculate and determine susceptibility and shielding
+DoFullCurrent	0	# Do full perturbation
+DoConstrainedMD	0	# Do perform a constrained (>0, relating to current MD step) instead of unconstrained (0) MD
+Thermostat	Berendsen	2.5	# Which Thermostat and its parameters to use in MD case.
+CommonWannier	0	# Put virtual centers at indivual orbits, all common, merged by variance, to grid point, to cell center
+SawtoothStart	0.01	# Absolute value for smooth transition at cell border 
+VectorPlane	0	# Cut plane axis (x, y or z: 0,1,2) for two-dim current vector plot
+VectorCut	0	# Cut plane axis value
+AddGramSch	1	# Additional GramSchmidtOrtogonalization to be safe
+Seed		1	# initial value for random seed for Psi coefficients
+
+MaxOuterStep	10	# number of MolecularDynamics/Structure optimization steps
+Deltat	0.01	# time per MD step
+OutVisStep	10	# Output visual data every ...th step
+OutSrcStep	5	# Output "restart" data every ..th step
+TargetTemp	0.000950045	# Target temperature
+MaxPsiStep	3	# number of Minimisation steps per state (0 - default)
+EpsWannier	1e-07	# tolerance value for spread minimisation of orbitals
+
+# Values specifying when to stop
+MaxMinStep	100	# Maximum number of steps
+RelEpsTotalE	1e-07	# relative change in total energy
+RelEpsKineticE	1e-05	# relative change in kinetic energy
+MaxMinStopStep	10	# check every ..th steps
+MaxMinGapStopStep	1	# check every ..th steps
+
+# Values specifying when to stop for INIT, otherwise same as above
+MaxInitMinStep	100	# Maximum number of steps
+InitRelEpsTotalE	1e-05	# relative change in total energy
+InitRelEpsKineticE	0.0001	# relative change in kinetic energy
+InitMaxMinStopStep	10	# check every ..th steps
+InitMaxMinGapStopStep	1	# check every ..th steps
+
+BoxLength			# (Length of a unit cell)
+20	
+0	20	
+0	0	20	
+
+ECut		128	# energy cutoff for discretization in Hartrees
+MaxLevel	5	# number of different levels in the code, >=2
+Level0Factor	2	# factor by which node number increases from S to 0 level
+RiemannTensor	0	# (Use metric)
+PsiType		0	# 0 - doubly occupied, 1 - SpinUp,SpinDown
+MaxPsiDouble	10	# here: specifying both maximum number of SpinUp- and -Down-states
+PsiMaxNoUp	10	# here: specifying maximum number of SpinUp-states
+PsiMaxNoDown	10	# here: specifying maximum number of SpinDown-states
+AddPsis		0	# Additional unoccupied Psis for bandgap determination
+
+RCut		20	# R-cut for the ewald summation
+StructOpt	0	# Do structure optimization beforehand
+IsAngstroem	1	# 0 - Bohr, 1 - Angstroem
+RelativeCoord	0	# whether ion coordinates are relative (1) or absolute (0)
+MaxTypes	2	# maximum number of different ion types
+
+# Ion type data (PP = PseudoPotential, Z = atomic number)
+#Ion_TypeNr.	Amount	Z	RGauss	L_Max(PP)L_Loc(PP)IonMass	# chemical name, symbol
+Ion_Type1	8	1	1.0	3	3	1.00800000000	Hydrogen	H
+Ion_Type2	3	6	1.0	3	3	12.01100000000	Carbon	C
+#Ion_TypeNr._Nr.R[0]    R[1]    R[2]    MoveType (0 MoveIon, 1 FixedIon)
+Ion_Type1_1	9.782085945	2.645886050	2.645886050	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 0
+Ion_Type1_2	9.782085945	2.645886050	4.425886024	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 1
+Ion_Type1_3	10.672039608	3.904536878	3.535886037	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 2
+Ion_Type1_4	8.532785963	4.787886018	2.645886050	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 3
+Ion_Type1_5	8.532785963	4.787886018	4.425886024	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 4
+Ion_Type1_6	6.393632318	3.904536877	3.535886037	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 5
+Ion_Type1_7	7.283585982	2.645886050	2.645886050	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 6
+Ion_Type1_8	7.283585982	2.645886050	4.425886024	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 7
+Ion_Type2_1	9.782085945	3.275186040	3.535886037	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 8
+Ion_Type2_2	8.532785963	4.158586027	3.535886037	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 9
+Ion_Type2_3	7.283585982	3.275186040	3.535886037	0	1.000000e-01	0.000000e+00	0.000000e+00	 # molecule nr 10
Index: tests/regression/Molecules/VerletIntegration/testsuite-molecules-verlet-integration.at
===================================================================
--- tests/regression/Molecules/VerletIntegration/testsuite-molecules-verlet-integration.at	(revision 7e51e12e82c5637d2660d794f1e024fda52a5aa6)
+++ tests/regression/Molecules/VerletIntegration/testsuite-molecules-verlet-integration.at	(revision 1e45f1fb84ae30e44c393f19156012e19f962ac3)
@@ -32,5 +32,4 @@
 
 AT_SETUP([Molecules - Verlet force integration with Undo])
-AT_XFAIL_IF([/bin/true])
 AT_KEYWORDS([molecules verlet-integration undo])
 
@@ -39,6 +38,6 @@
 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Molecules/VerletIntegration/pre/test.forces .], 0)
 AT_CHECK([chmod u+w $file], 0)
-AT_CHECK([../../molecuilder -i $file --select-all-atoms --verlet-integration --forces-file test.forces --MDSteps 1 --deltat 0.01 --keep-fixed-CenterOfMass 0 --undo], 0, [stdout], [stderr])
-AT_CHECK([diff $file ${abs_top_srcdir}/tests/regression/Molecules/VerletIntegration/post/test.conf], 0, [ignore], [ignore])
+AT_CHECK([../../molecuilder -i $file --select-all-atoms --verlet-integration --forces-file test.forces --deltat 0.01 --keep-fixed-CenterOfMass 0 --undo], 0, [stdout], [stderr])
+AT_CHECK([diff $file ${abs_top_srcdir}/tests/regression/Molecules/VerletIntegration/post/test-undo.conf], 0, [ignore], [ignore])
 
 AT_CLEANUP
@@ -46,5 +45,4 @@
 
 AT_SETUP([Molecules - Verlet force integration with Redo])
-AT_XFAIL_IF([/bin/true])
 AT_KEYWORDS([molecules verlet-integration redo])
 
@@ -53,5 +51,5 @@
 AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Molecules/VerletIntegration/pre/test.forces .], 0)
 AT_CHECK([chmod u+w $file], 0)
-AT_CHECK([../../molecuilder -i $file --select-all-atoms --verlet-integration --forces-file test.forces --MDSteps 1 --deltat 0.01 --keep-fixed-CenterOfMass 0 --undo --redo], 0, [stdout], [stderr])
+AT_CHECK([../../molecuilder -i $file --select-all-atoms --verlet-integration --forces-file test.forces --deltat 0.01 --keep-fixed-CenterOfMass 0 --undo --redo], 0, [stdout], [stderr])
 AT_CHECK([diff $file ${abs_top_srcdir}/tests/regression/Molecules/VerletIntegration/post/test.conf], 0, [ignore], [ignore])
 
