Index: src/Actions/Makefile.am
===================================================================
--- src/Actions/Makefile.am	(revision a42054a57dce05541025613b38ddca2bfb93603a)
+++ src/Actions/Makefile.am	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -91,4 +91,5 @@
   MoleculeAction/CopyAction.cpp \
   MoleculeAction/FillWithMoleculeAction.cpp \
+  MoleculeAction/FillVoidWithMoleculeAction.cpp \
   MoleculeAction/LinearInterpolationofTrajectoriesAction.cpp \
   MoleculeAction/RotateAroundSelfByAngleAction.cpp \
@@ -104,4 +105,5 @@
   MoleculeAction/CopyAction.hpp \
   MoleculeAction/FillWithMoleculeAction.hpp \
+  MoleculeAction/FillVoidWithMoleculeAction.hpp \
   MoleculeAction/LinearInterpolationofTrajectoriesAction.hpp \
   MoleculeAction/RotateAroundSelfByAngleAction.hpp \
Index: src/Actions/MapOfActions.cpp
===================================================================
--- src/Actions/MapOfActions.cpp	(revision a42054a57dce05541025613b38ddca2bfb93603a)
+++ src/Actions/MapOfActions.cpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -71,4 +71,5 @@
 #include "Actions/MoleculeAction/CopyAction.hpp"
 #include "Actions/MoleculeAction/FillWithMoleculeAction.hpp"
+#include "Actions/MoleculeAction/FillVoidWithMoleculeAction.hpp"
 #include "Actions/MoleculeAction/LinearInterpolationofTrajectoriesAction.hpp"
 #include "Actions/MoleculeAction/RotateAroundSelfByAngleAction.hpp"
@@ -221,5 +222,6 @@
   DescriptionMap["element-db"] = "setting the path where the element databases can be found";
   DescriptionMap["fastparsing"] = "setting whether trajectories shall be parsed completely (n) or just first step (y)";
-  DescriptionMap["fill-molecule"] = "fill empty space of box with a filler molecule";
+  DescriptionMap["fill-molecule"] = "fill around molecules' surface with a filler molecule";
+  DescriptionMap["fill-void"] = "fill void space of box with a filler molecule";
   DescriptionMap["fragment-mol"] = "create for a given molecule into fragments up to given order";
   DescriptionMap["help"] = "Give this help screen";
@@ -361,4 +363,5 @@
   TypeMap["fastparsing"] = &typeid(bool);
   TypeMap["fill-molecule"] = &typeid(std::string);
+  TypeMap["fill-void"] = &typeid(std::string);
   TypeMap["fragment-mol"] = &typeid(std::string);
   TypeMap["input"] = &typeid(std::string);
@@ -498,4 +501,5 @@
   MenuContainsActionMap.insert( pair<std::string, std::string> ("molecule", "change-molname") );
   MenuContainsActionMap.insert( pair<std::string, std::string> ("molecule", "fill-molecule") );
+  MenuContainsActionMap.insert( pair<std::string, std::string> ("molecule", "fill-void") );
   MenuContainsActionMap.insert( pair<std::string, std::string> ("molecule", "linear-interpolate") );
   MenuContainsActionMap.insert( pair<std::string, std::string> ("molecule", "rotate-origin") );
@@ -571,4 +575,5 @@
 	generic.insert("fastparsing");
   generic.insert("fill-molecule");
+  generic.insert("fill-void");
   generic.insert("fragment-mol");
   generic.insert("help");
@@ -954,4 +959,5 @@
   new MoleculeCopyAction();
   new MoleculeFillWithMoleculeAction();
+  new MoleculeFillVoidWithMoleculeAction();
   new MoleculeLinearInterpolationofTrajectoriesAction();
   new MoleculeRotateAroundSelfByAngleAction();
Index: src/Actions/MoleculeAction/FillVoidWithMoleculeAction.cpp
===================================================================
--- src/Actions/MoleculeAction/FillVoidWithMoleculeAction.cpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
+++ src/Actions/MoleculeAction/FillVoidWithMoleculeAction.cpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -0,0 +1,134 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * FillVoidWithMoleculeAction.cpp
+ *
+ *  Created on: May 10, 2010
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Helpers/MemDebug.hpp"
+
+#include "atom.hpp"
+#include "bondgraph.hpp"
+#include "boundary.hpp"
+#include "config.hpp"
+#include "molecule.hpp"
+#include "Helpers/Verbose.hpp"
+#include "World.hpp"
+
+#include "Parser/MpqcParser.hpp"
+#include "Parser/PcpParser.hpp"
+#include "Parser/PdbParser.hpp"
+#include "Parser/TremoloParser.hpp"
+#include "Parser/XyzParser.hpp"
+#include "Parser/FormatParserStorage.hpp"
+
+#include <iostream>
+#include <string>
+
+using namespace std;
+
+#include "Actions/MoleculeAction/FillVoidWithMoleculeAction.hpp"
+
+// and construct the stuff
+#include "FillVoidWithMoleculeAction.def"
+#include "Action_impl_pre.hpp"
+/** =========== define the function ====================== */
+Action::state_ptr MoleculeFillVoidWithMoleculeAction::performCall() {
+
+  // obtain information
+  getParametersfromValueStorage();
+
+  DoLog(1) && (Log() << Verbose(1) << "Filling Box with water molecules, lengths(" << params.lengths[0] << "," << params.lengths[1] << "," << params.lengths[2] << "), distances (" << params.distances[0] << "," << params.distances[1] << "," << params.distances[2] << "), DoRotate " << params.DoRotate << "." << endl);
+  // construct water molecule
+  molecule *filler = World::getInstance().createMolecule();
+  std::string FilenameSuffix = params.fillername.substr(params.fillername.find_last_of('.')+1, params.fillername.length());
+  ifstream input;
+  input.open(params.fillername.c_str());
+  switch (FormatParserStorage::getInstance().getTypeFromSuffix(FilenameSuffix)) {
+    case mpqc:
+      {
+        MpqcParser mpqcparser;
+        mpqcparser.load(&input);
+        break;
+      }
+    case pcp:
+      {
+        PcpParser pcpparser;
+        pcpparser.load(&input);
+        break;
+      }
+    case pdb:
+      {
+        PdbParser pdbparser;
+        pdbparser.load(&input);
+        break;
+      }
+    case tremolo:
+      {
+        TremoloParser tremoloparser;
+        tremoloparser.load(&input);
+        break;
+      }
+    case xyz:
+      {
+        XyzParser xyzparser;
+        xyzparser.load(&input);
+        break;
+      }
+    default:
+      DoeLog(0) && (eLog()<< Verbose(0) << "Could not parse filler molecule from " << params.fillername << "." << endl);
+      break;
+  }
+  World::MoleculeIterator iter = World::getInstance().getMoleculeIter();
+  for (; iter != World::getInstance().moleculeEnd(); ++iter)
+    filler = *iter; // get last molecule
+  filler->SetNameFromFilename(params.fillername.c_str());
+  World::getInstance().getConfig()->BG->ConstructBondGraph(filler);
+
+  // call routine
+  double distance[NDIM];
+  for (int i=0;i<NDIM;i++)
+    distance[i] = params.distances[i];
+  FillVoidWithMolecule(filler, *(World::getInstance().getConfig()), distance, params.lengths[0], params.lengths[1], params.lengths[2], params.DoRotate);
+
+  return Action::success;
+}
+
+Action::state_ptr MoleculeFillVoidWithMoleculeAction::performUndo(Action::state_ptr _state) {
+//  MoleculeFillVoidWithMoleculeState *state = assert_cast<MoleculeFillVoidWithMoleculeState*>(_state.get());
+
+//  string newName = state->mol->getName();
+//  state->mol->setName(state->lastName);
+
+  return Action::failure;
+}
+
+Action::state_ptr MoleculeFillVoidWithMoleculeAction::performRedo(Action::state_ptr _state){
+  // Undo and redo have to do the same for this action
+  return performUndo(_state);
+}
+
+bool MoleculeFillVoidWithMoleculeAction::canUndo() {
+  return false;
+}
+
+bool MoleculeFillVoidWithMoleculeAction::shouldUndo() {
+  return false;
+}
+
+const string MoleculeFillVoidWithMoleculeAction::getName() {
+  return NAME;
+}
+/** =========== end of function ====================== */
Index: src/Actions/MoleculeAction/FillVoidWithMoleculeAction.def
===================================================================
--- src/Actions/MoleculeAction/FillVoidWithMoleculeAction.def	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
+++ src/Actions/MoleculeAction/FillVoidWithMoleculeAction.def	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -0,0 +1,26 @@
+/*
+ * FillVoidWithMoleculeAction.def
+ *
+ *  Created on: Aug 26, 2010
+ *      Author: heber
+ */
+
+// all includes and forward declarations necessary for non-integral types below
+#include "LinearAlgebra/Vector.hpp"
+class MoleculeListClass;
+
+// i.e. there is an integer with variable name Z that can be found in
+// ValueStorage by the token "Z" -> first column: int, Z, "Z"
+// "undefine" if no parameters are required
+#define paramtypes (std::string) (Vector) (Vector) (bool)
+#define paramtokens (MoleculeFillVoidWithMoleculeAction::NAME) ("distances") ("lengths") ("DoRotate")
+#define paramreferences (fillername) (distances) (lengths) (DoRotate)
+
+#undef statetypes
+#undef statereferences
+
+// some defines for all the names, you may use ACTION, STATE and PARAMS
+#define CATEGORY Molecule
+#define ACTIONNAME FillVoidWithMolecule
+#define TOKEN "fill-void"
+
Index: src/Actions/MoleculeAction/FillVoidWithMoleculeAction.hpp
===================================================================
--- src/Actions/MoleculeAction/FillVoidWithMoleculeAction.hpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
+++ src/Actions/MoleculeAction/FillVoidWithMoleculeAction.hpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -0,0 +1,16 @@
+/*
+ * FillVoidWithMoleculeAction.hpp
+ *
+ *  Created on: May 10, 2010
+ *      Author: heber
+ */
+
+#ifndef FILLVOIDWITHMOLECULEACTION_HPP
+#define FILLVOIDWITHMOLECULEACTION_HPP
+
+#include "Actions/Action.hpp"
+
+#include "FillVoidWithMoleculeAction.def"
+#include "Action_impl_header.hpp"
+
+#endif // FILLVOIDWITHMOLECULEACTION_HPP
Index: src/boundary.cpp
===================================================================
--- src/boundary.cpp	(revision a42054a57dce05541025613b38ddca2bfb93603a)
+++ src/boundary.cpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -770,5 +770,5 @@
 
 
-/** Fills the empty space of the simulation box with water/
+/** Fills the empty space around other molecules' surface of the simulation box with a filler.
  * \param *out output stream for debugging
  * \param *List list of molecules already present in box
@@ -925,4 +925,151 @@
 };
 
+/** Fills the empty space of the simulation box with water/
+ * \param *out output stream for debugging
+ * \param *TesselStruct contains tesselated surface
+ * \param *filler molecule which the box is to be filled with
+ * \param configuration contains box dimensions
+ * \param distance[NDIM] distance between filling molecules in each direction
+ * \param boundary length of boundary zone between molecule and filling mollecules
+ * \param epsilon distance to surface which is not filled
+ * \param RandAtomDisplacement maximum distance for random displacement per atom
+ * \param RandMolDisplacement maximum distance for random displacement per filler molecule
+ * \param DoRandomRotation true - do random rotiations, false - don't
+ */
+void FillVoidWithMolecule(molecule *filler, config &configuration, const double distance[NDIM], const double boundary, const double RandomAtomDisplacement, const double RandomMolDisplacement, const bool DoRandomRotation)
+{
+  Info FunctionInfo(__func__);
+  molecule *Filling = NULL;
+  Vector CurrentPosition;
+  int N[NDIM];
+  int n[NDIM];
+  const Matrix &M = World::getInstance().getDomain().getM();
+  Matrix Rotations;
+  const Matrix &MInverse = World::getInstance().getDomain().getMinv();
+  Vector AtomTranslations;
+  Vector FillerTranslations;
+  Vector FillerDistance;
+  Vector Inserter;
+  double FillIt = false;
+  bond *Binder = NULL;
+  double phi[NDIM];
+  map<molecule *, LinkedCell *> LCList;
+  std::vector<molecule *> List = World::getInstance().getAllMolecules();
+  MoleculeListClass *MolList = World::getInstance().getMolecules();
+
+  for (std::vector<molecule *>::iterator ListRunner = List.begin(); ListRunner != List.end(); ListRunner++)
+    if ((*ListRunner)->getAtomCount() > 0) {
+      DoLog(1) && (Log() << Verbose(1) << "Pre-creating linked cell lists for molecule " << *ListRunner << "." << endl);
+      LCList[(*ListRunner)] = new LinkedCell(*(*ListRunner), 10.); // get linked cell list
+    }
+
+  // Center filler at origin
+  filler->CenterEdge(&Inserter);
+  const int FillerCount = filler->getAtomCount();
+  DoLog(2) && (Log() << Verbose(2) << "INFO: Filler molecule has the following bonds:" << endl);
+  for(molecule::iterator AtomRunner = filler->begin(); AtomRunner != filler->end(); ++AtomRunner)
+    for(BondList::iterator BondRunner = (*AtomRunner)->ListOfBonds.begin(); BondRunner != (*AtomRunner)->ListOfBonds.end(); ++BondRunner)
+      if ((*BondRunner)->leftatom == *AtomRunner)
+        DoLog(2) && (Log() << Verbose(2) << "  " << *(*BondRunner) << endl);
+
+  // calculate filler grid in [0,1]^3
+  FillerDistance = MInverse * Vector(distance[0], distance[1], distance[2]);
+  for(int i=0;i<NDIM;i++)
+    N[i] = (int) ceil(1./FillerDistance[i]);
+  DoLog(1) && (Log() << Verbose(1) << "INFO: Grid steps are " << N[0] << ", " << N[1] << ", " << N[2] << "." << endl);
+
+  // initialize seed of random number generator to current time
+  srand ( time(NULL) );
+
+  // go over [0,1]^3 filler grid
+  for (n[0] = 0; n[0] < N[0]; n[0]++)
+    for (n[1] = 0; n[1] < N[1]; n[1]++)
+      for (n[2] = 0; n[2] < N[2]; n[2]++) {
+        // calculate position of current grid vector in untransformed box
+        CurrentPosition = M * Vector((double)n[0]/(double)N[0], (double)n[1]/(double)N[1], (double)n[2]/(double)N[2]);
+        // create molecule random translation vector ...
+        for (int i=0;i<NDIM;i++)
+          FillerTranslations[i] = RandomMolDisplacement*(rand()/(RAND_MAX/2.) - 1.);
+        DoLog(2) && (Log() << Verbose(2) << "INFO: Current Position is " << CurrentPosition << "+" << FillerTranslations << "." << endl);
+
+        // ... and rotation matrix
+        if (DoRandomRotation) {
+          for (int i=0;i<NDIM;i++) {
+            phi[i] = rand()/(RAND_MAX/(2.*M_PI));
+          }
+
+          Rotations.set(0,0,  cos(phi[0])            *cos(phi[2]) + (sin(phi[0])*sin(phi[1])*sin(phi[2])));
+          Rotations.set(0,1,  sin(phi[0])            *cos(phi[2]) - (cos(phi[0])*sin(phi[1])*sin(phi[2])));
+          Rotations.set(0,2,              cos(phi[1])*sin(phi[2])                                        );
+          Rotations.set(1,0, -sin(phi[0])*cos(phi[1])                                                    );
+          Rotations.set(1,1,  cos(phi[0])*cos(phi[1])                                                    );
+          Rotations.set(1,2,              sin(phi[1])                                                    );
+          Rotations.set(2,0, -cos(phi[0])            *sin(phi[2]) + (sin(phi[0])*sin(phi[1])*cos(phi[2])));
+          Rotations.set(2,1, -sin(phi[0])            *sin(phi[2]) - (cos(phi[0])*sin(phi[1])*cos(phi[2])));
+          Rotations.set(2,2,              cos(phi[1])*cos(phi[2])                                        );
+        }
+
+        FillIt = true;
+        // go through all atoms
+        for(molecule::const_iterator iter = filler->begin(); iter !=filler->end();++iter){
+
+          // Check whether there is anything too close by
+          LinkedCell::LinkedNodes* liste = NULL;
+          for (std::map<molecule *, LinkedCell *>::iterator ListRunner = LCList.begin(); ListRunner != LCList.end(); ++ListRunner) {
+            liste = ListRunner->second->GetPointsInsideSphere(boundary, &CurrentPosition);
+            FillIt = FillIt && (liste->size() == 0);
+            delete(liste);
+            if (!FillIt)
+              break;
+          }
+        }
+        // insert into Filling
+        if (FillIt) {
+          Inserter = CurrentPosition + FillerTranslations;
+          DoLog(1) && (Log() << Verbose(1) << "INFO: Position at " << Inserter << " is void point." << endl);
+          Filling = filler->CopyMolecule();
+          for(molecule::iterator miter = Filling->begin(); miter != Filling->end(); ++miter) {
+            if (DoRandomRotation) {
+              Vector temp = (*miter)->getPosition();
+              temp *= Rotations;
+              (*miter)->setPosition(temp);
+            }
+            // create atomic random translation vector ...
+            for (int i=0;i<NDIM;i++)
+              AtomTranslations[i] = RandomAtomDisplacement*(rand()/(RAND_MAX/2.) - 1.);
+            (*miter)->setPosition((*miter)->getPosition() + AtomTranslations);
+          }
+          Filling->Translate(&Inserter);
+          for(molecule::iterator miter = Filling->begin(); miter != Filling->end(); ) {
+            // check whether each atom is inside box
+            if (!World::getInstance().getDomain().isInside((*miter)->getPosition())) {
+              atom *Walker = *miter;
+              ++miter;
+              World::getInstance().destroyAtom(Walker);
+            } else {
+              ++miter;
+            }
+          }
+          MolList->insert(Filling);
+        } else {
+          DoLog(1) && (Log() << Verbose(1) << "INFO: Position at " << Inserter << " is non-void point, within boundary or outside of MaxDistance." << endl);
+          continue;
+        }
+      }
+  // last one is replaced by the filler, as we need the original atoms contained therein!
+  filler->Translate(&Inserter);
+  MolList->erase(Filling);
+  for (molecule::iterator iter = Filling->begin(); !Filling->empty(); iter = Filling->begin()) {
+    atom *Walker = *iter;
+    Filling->erase(iter);
+    World::getInstance().destroyAtom(Walker);
+  }
+  World::getInstance().destroyMolecule(Filling);
+
+  for (std::map<molecule *, LinkedCell *>::iterator ListRunner = LCList.begin(); !LCList.empty(); ListRunner = LCList.begin()) {
+    delete ListRunner->second;
+    LCList.erase(ListRunner);
+  }
+};
 
 /** Tesselates the non convex boundary by rolling a virtual sphere along the surface of the molecule.
Index: src/boundary.hpp
===================================================================
--- src/boundary.hpp	(revision a42054a57dce05541025613b38ddca2bfb93603a)
+++ src/boundary.hpp	(revision eee966fe34197e1773f114db10205f2b7ad6f78e)
@@ -41,5 +41,6 @@
 double ConvexizeNonconvexEnvelope(class Tesselation *&TesselStruct, const molecule * const mol, const char * const filename);
 molecule * FillBoxWithMolecule(MoleculeListClass *List, molecule *filler, config &configuration, const double MaxDistance, const double distance[NDIM], const double boundary, const double RandomAtomDisplacement, const double RandomMolDisplacement, const bool DoRandomRotation);
-void FindConvexBorder(const molecule* const mol, Boundaries *BoundaryPts, Tesselation *&TesselStruct, const LinkedCell *LCList, const char *filename);
+void FillVoidWithMolecule(molecule *filler, config &configuration, const double distance[NDIM], const double boundary, const double RandomAtomDisplacement, const double RandomMolDisplacement, const bool DoRandomRotation);
+    void FindConvexBorder(const molecule* const mol, Boundaries *BoundaryPts, Tesselation *&TesselStruct, const LinkedCell *LCList, const char *filename);
 Vector* FindEmbeddingHole(MoleculeListClass *mols, molecule *srcmol);
 bool FindNonConvexBorder(const molecule* const mol, Tesselation *&TesselStruct, const LinkedCell *&LC, const double RADIUS, const char *tempbasename);
