Index: src/Actions/RandomNumbersAction/SetRandomNumbersDistributionAction.cpp
===================================================================
--- src/Actions/RandomNumbersAction/SetRandomNumbersDistributionAction.cpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/Actions/RandomNumbersAction/SetRandomNumbersDistributionAction.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -45,10 +45,10 @@
   CommandSetRandomNumbersDistributionState *state =
       new CommandSetRandomNumbersDistributionState(
-          RandomNumberGeneratorFactory::getInstance().getDistribution(),
+          RandomNumberGeneratorFactory::getInstance().getDistributionName(),
           params);
   RandomNumberGeneratorFactory::getInstance().setDistribution(params.distribution_type);
 
   DoLog(0) && (Log() << Verbose(0) << "Distribution of random number generator is now: "
-      << RandomNumberGeneratorFactory::getInstance().getDistribution() << std::endl);
+      << RandomNumberGeneratorFactory::getInstance().getDistributionName() << std::endl);
 
   return Action::state_ptr(state);
@@ -60,10 +60,10 @@
   CommandSetRandomNumbersDistributionState *newstate =
       new CommandSetRandomNumbersDistributionState(
-          RandomNumberGeneratorFactory::getInstance().getDistribution(),
+          RandomNumberGeneratorFactory::getInstance().getDistributionName(),
           state->params);
   RandomNumberGeneratorFactory::getInstance().setDistribution(state->old_distribution_type);
 
   DoLog(0) && (Log() << Verbose(0) << "Distribution of random number generator is undone to: "
-      << RandomNumberGeneratorFactory::getInstance().getDistribution() << std::endl);
+      << RandomNumberGeneratorFactory::getInstance().getDistributionName() << std::endl);
 
   return Action::state_ptr(newstate);
Index: src/Actions/RandomNumbersAction/SetRandomNumbersEngineAction.cpp
===================================================================
--- src/Actions/RandomNumbersAction/SetRandomNumbersEngineAction.cpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/Actions/RandomNumbersAction/SetRandomNumbersEngineAction.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -45,10 +45,10 @@
   CommandSetRandomNumbersEngineState *state =
       new CommandSetRandomNumbersEngineState(
-          RandomNumberGeneratorFactory::getInstance().getEngine(),
+          RandomNumberGeneratorFactory::getInstance().getEngineName(),
           params);
   RandomNumberGeneratorFactory::getInstance().setEngine(params.engine_type);
 
   DoLog(0) && (Log() << Verbose(0) << "Engine of random number generator is now: "
-      << RandomNumberGeneratorFactory::getInstance().getEngine() << std::endl);
+      << RandomNumberGeneratorFactory::getInstance().getEngineName() << std::endl);
 
   return Action::state_ptr(state);
@@ -60,10 +60,10 @@
   CommandSetRandomNumbersEngineState *newstate =
       new CommandSetRandomNumbersEngineState(
-          RandomNumberGeneratorFactory::getInstance().getEngine(),
+          RandomNumberGeneratorFactory::getInstance().getEngineName(),
           state->params);
   RandomNumberGeneratorFactory::getInstance().setEngine(state->old_engine_type);
 
   DoLog(0) && (Log() << Verbose(0) << "Engine of random number generator is undone to: "
-      << RandomNumberGeneratorFactory::getInstance().getEngine() << std::endl);
+      << RandomNumberGeneratorFactory::getInstance().getEngineName() << std::endl);
 
   return Action::state_ptr(newstate);
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/Makefile.am	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -123,11 +123,23 @@
 
 RANDOMSOURCE = \
+	RandomNumbers/RandomNumberDistributionFactory.cpp \
+	RandomNumbers/RandomNumberEngineFactory.cpp \
 	RandomNumbers/RandomNumberGeneratorFactory.cpp
 
 RANDOMHEADER = \
+	RandomNumbers/RandomNumberDistribution.hpp \
+	RandomNumbers/RandomNumberDistribution_Creator.hpp \
+	RandomNumbers/RandomNumberDistribution_Encapsulation.hpp \
+	RandomNumbers/RandomNumberDistributionFactory.hpp \
+	RandomNumbers/RandomNumberEngine.hpp \
+	RandomNumbers/RandomNumberEngine_Creator.hpp \
+	RandomNumbers/RandomNumberEngine_Encapsulation.hpp \
+	RandomNumbers/RandomNumberEngineFactory.hpp \
 	RandomNumbers/RandomNumberGenerator.hpp \
+	RandomNumbers/RandomNumberGenerator_Creator.hpp \
+	RandomNumbers/RandomNumberGenerator_Encapsulation.hpp \
+	RandomNumbers/RandomNumberGeneratorFactory.hpp \
 	RandomNumbers/TemplatePowerSetGenerator.hpp \
-	RandomNumbers/RandomNumberGenerator_Encapsulation.hpp \
-	RandomNumbers/RandomNumberGeneratorFactory.hpp
+	RandomNumbers/EmptyPrototypeTable.hpp
   
 THERMOSTATSOURCE = \
Index: src/RandomNumbers/Creator_impl.hpp
===================================================================
--- src/RandomNumbers/Creator_impl.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/Creator_impl.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,62 @@
+/*
+ * Creator_impl.hpp
+ *
+ *  Created on: Jan 3, 2011
+ *      Author: heber
+ */
+
+#ifndef CREATOR_IMPL_HPP_
+#define CREATOR_IMPL_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+/** This class wraps another one and implements a create() function for it.
+ *
+ * This pattern is sometimes called 'type erasure': we want to present
+ * the user with a abstract interface only (name) but in
+ * order to create a copy (such that handed out instances are independent from
+ * one another) we have to know about the type of underlying (complex) class.
+ *
+ * Hence, we create this templated creator class (name##_Creator), which has an
+ * abstract creation interface (I##name##_Creator).
+ *
+ * This pattern is e.g. very useful when multiple (proto)types have to be
+ * stored in the table of a factory. Factories can serve only a general
+ * (abstract) type and not the specific one due to a necessary general function
+ * signature.
+ *
+ * <h1> Howto </h1>
+ *
+ * Wrap the classes to instantiate by the factory in this creator
+ * pattern. The factory in its tables only stores the abstract creation
+ * interface (I##name##_Creator). Let the factory call create() when it has to
+ * produce an instance, which is passed through to the templated creation class
+ * (name##_Creator), dealing out the copy.
+ *
+ * <h1>Best Practice </h1>
+ *
+ * NOTE: It is best-practice to place the call to CONSTRUCT_CREATOR in its
+ * own header file and include this file only. Otherwise, one might get
+ * redefinition errors.
+ */
+#define CONSTRUCT_CREATOR(name) \
+class name; \
+struct I##name##_Creator \
+{ \
+  virtual ~I##name##_Creator() {}; \
+  virtual  name * create() const =0; \
+}; \
+template <class T> \
+struct name##_Creator : public I##name##_Creator \
+{ \
+  virtual name * create() const { \
+    return new T(); \
+  }; \
+};
+
+
+#endif /* CREATOR_IMPL_HPP_ */
Index: src/RandomNumbers/EmptyPrototypeTable.hpp
===================================================================
--- src/RandomNumbers/EmptyPrototypeTable.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/EmptyPrototypeTable.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,36 @@
+/*
+ * EmptyPrototypeTable.hpp
+ *
+ *  Created on: Jan 3, 2011
+ *      Author: heber
+ */
+
+#ifndef EMPTYPROTOTYPETABLE_HPP_
+#define EMPTYPROTOTYPETABLE_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/** Removes all pointers to instances from a table while free'ing memory.
+ *
+ * I.e. we assume class T to be a map of some key with its values pointers to
+ * some classes that have to be free'd.
+ *
+ * \param _PrototypeTable table to empty
+ */
+template <class T>
+void EmptyPrototypeTable(T &_PrototypeTable)
+{
+  for (typename T::iterator iter = _PrototypeTable.begin();
+      !_PrototypeTable.empty();
+      iter = _PrototypeTable.begin()) {
+    delete (iter->second);
+    _PrototypeTable.erase(iter);
+  }
+  _PrototypeTable.clear();
+}
+
+
+#endif /* EMPTYPROTOTYPETABLE_HPP_ */
Index: src/RandomNumbers/RandomNumberDistributionFactory.cpp
===================================================================
--- src/RandomNumbers/RandomNumberDistributionFactory.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberDistributionFactory.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+/*
+ * RandomNumberDistributionFactory.cpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <utility>
+#include "CodePatterns/Singleton_impl.hpp"
+#include "CodePatterns/Assert.hpp"
+
+#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/exponential_distribution.hpp>
+#include <boost/random/gamma_distribution.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/lognormal_distribution.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/poisson_distribution.hpp>
+#include <boost/random/triangle_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_on_sphere.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_smallint.hpp>
+
+#include <boost/preprocessor/facilities/empty.hpp>
+#include <boost/preprocessor/punctuation/paren.hpp>
+
+#include "TemplatePowerSetGenerator.hpp"
+#include "EmptyPrototypeTable.hpp"
+
+#include "RandomNumberDistribution_Encapsulation.hpp"
+
+#include "RandomNumberDistributionFactory.hpp"
+#include "RandomNumberDistributionFactory.def"
+
+//enum RandomNumberDistributionFactory::Distribution RandomNumberDistributionFactory::distribution = (enum RandomNumberDistributionFactory::Distribution) 0;
+RandomNumberDistributionFactory::DistributionMap RandomNumberDistributionFactory::distributions;
+RandomNumberDistributionFactory::DistributionNamesMap RandomNumberDistributionFactory::distributionNames;
+RandomNumberDistributionFactory::DistributionTable RandomNumberDistributionFactory::DistributionPrototypeTable;
+
+
+RandomNumberDistributionFactory::RandomNumberDistributionFactory()
+{
+  FillEnumTable();
+  FillPrototypeTable();
+}
+
+RandomNumberDistributionFactory::~RandomNumberDistributionFactory()
+{
+  // clear out factories map to allow boost::shared_ptr to do their work (i.e. to release mem)
+  // this is necessary as factories is a object
+  distributions.clear();
+  distributionNames.clear();
+  EmptyPrototypeTable<DistributionTable> (DistributionPrototypeTable);
+}
+
+void RandomNumberDistributionFactory::FillEnumTable()
+{
+  // insert all known distributions
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, distribution_seq, distributions)
+#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distribution_seq)-1 )
+#include BOOST_PP_LOCAL_ITERATE()
+  for (DistributionMap::const_iterator iter = distributions.begin();
+      iter != distributions.end();
+      ++iter) {
+    distributionNames.insert(make_pair(iter->second, iter->first));
+  }
+}
+
+void RandomNumberDistributionFactory::FillPrototypeTable()
+{
+  // fill DistributionPrototypeTable
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, distribution_seq, DistributionPrototypeTable, new RandomNumberDistribution_Creator< RandomNumberDistribution_Encapsulation, boost::, <> > )
+#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distribution_seq)-1 )
+#include BOOST_PP_LOCAL_ITERATE()
+}
+
+RandomNumberDistribution* RandomNumberDistributionFactory::getDistribution(enum Distribution distribution_type) const
+{
+  return DistributionPrototypeTable[distribution_type]->create();
+}
+
+RandomNumberDistribution* RandomNumberDistributionFactory::getDistribution(const std::string distribution_name) const
+{
+  ASSERT(distributions.count(distribution_name) != 0,
+      "RandomNumberDistributionFactory::getDistribution() - distribution "+distribution_name+" is not registered.");
+  return DistributionPrototypeTable[ distributions[distribution_name] ]->create();
+}
+
+const std::string &RandomNumberDistributionFactory::getName(enum Distribution distribution_type) const
+{
+  return distributionNames[distribution_type];
+}
+
+enum RandomNumberDistributionFactory::Distribution RandomNumberDistributionFactory::getEnum(const std::string distribution_name) const
+{
+  ASSERT(distributions.count(distribution_name) != 0,
+      "RandomNumberDistributionFactory::getEnum() - distribution "+distribution_name+" is not registered.");
+  return distributions[distribution_name];
+}
+
+CONSTRUCT_SINGLETON(RandomNumberDistributionFactory)
+
+#include "RandomNumberDistributionFactory.undef"
+
Index: src/RandomNumbers/RandomNumberDistributionFactory.def
===================================================================
--- src/RandomNumbers/RandomNumberDistributionFactory.def	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberDistributionFactory.def	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,28 @@
+#ifndef RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
+#define RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
+
+/** BOOST_PP_SEQ of all random::boost distribution types,
+ * see see http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/reference.html#boost_random.reference.concepts
+ */
+#define distribution_seq \
+(uniform_smallint)\
+(uniform_int)
+
+/*
+(uniform_01)\
+(uniform_real)\
+(bernoulli_distribution)\
+(binomial_distribution)\
+(cauchy_distribution)\
+(gamma_distribution)\
+(poisson_distribution)\
+(geometric_distribution)\
+(triangle_distribution)\
+(exponential_distribution)\
+(normal_distribution)\
+(lognormal_distribution)\
+(uniform_on_sphere)
+*/
+#define distribution_seq_size BOOST_PP_SEQ_SIZE(distribution_seq)
+
+#endif /* RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_ */
Index: src/RandomNumbers/RandomNumberDistributionFactory.hpp
===================================================================
--- src/RandomNumbers/RandomNumberDistributionFactory.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberDistributionFactory.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,116 @@
+/*
+ * RandomNumberDistributionFactory.hpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERDISTRIBUTIONFACTORY_HPP_
+#define RANDOMNUMBERDISTRIBUTIONFACTORY_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/Singleton.hpp"
+
+#include <map>
+
+#include "TemplatePowerSetGenerator.hpp"
+#include "RandomNumberDistributionFactory.def"
+
+#include "RandomNumberDistribution_Creator.hpp"
+
+#include "unittests/RandomNumberDistributionFactoryUnitTest.hpp"
+
+class RandomNumberDistribution;
+
+/** This is the abstract factory class for random number distributions.
+ *
+ * The reason for creating the distributions as this is that we would like to set
+ * the distributions parameters, via some Action, and then onward only have
+ * random number distributions of this type using these parameters. Hence, we have
+ * a singleton factory that is controlled by the Action and can then create
+ * distributions wherever we like in the code by having the factory create one.
+ *
+ */
+class RandomNumberDistributionFactory : public Singleton<RandomNumberDistributionFactory>
+{
+  friend class Singleton<RandomNumberDistributionFactory>;
+  friend class RandomNumberDistributionFactoryTest;
+public:
+
+protected:
+  RandomNumberDistributionFactory();
+  virtual ~RandomNumberDistributionFactory();
+
+public:
+  /** Enumeration of all distribution implemented in random::boost.
+   */
+  enum Distribution {
+BOOST_PP_REPEAT( distribution_seq_size, seqitems_as_enum, distribution_seq)
+  };
+
+  /** Getter for current type of distribution.
+   *
+   * @param enumeration index of distribution
+   * @return reference to copy of distribution
+   */
+  RandomNumberDistribution* getDistribution(enum Distribution distribution_type) const;
+
+  /** Getter for current type of distribution.
+   *
+   * @param name of distribution
+   * @return reference to copy of distribution
+   */
+  RandomNumberDistribution* getDistribution(const std::string distribution_name) const;
+
+  /** Getter for the name of the current type of distribution.
+   *
+   * @return name of distribution
+   */
+  const std::string &getName(enum Distribution distribution_type) const;
+
+  /** Getter for the enumeration index of the current type of distribution.
+   *
+   * @return enum of distribution
+   */
+  enum Distribution getEnum(const std::string distribution_name) const;
+
+
+protected:
+private:
+
+  /** Creates instances of all possible distribution types
+   *  and stores them in \a DistributionPrototypeTable.
+   */
+  void FillPrototypeTable();
+
+  /** Create association for enums to strings and vice versa
+   *  and stores them in \a distributions tables.
+   */
+  void FillEnumTable();
+
+  typedef std::map<
+      std::string,
+      enum Distribution
+      > DistributionMap;
+  typedef std::map<
+      enum Distribution,
+      IRandomNumberDistribution_Creator *
+      > DistributionTable;
+  typedef std::map<
+      enum Distribution,
+      std::string
+      > DistributionNamesMap;
+
+  //static enum Distribution distribution;
+  static DistributionMap distributions;
+  static DistributionTable DistributionPrototypeTable;
+  static DistributionNamesMap distributionNames;
+};
+
+#include "RandomNumberDistributionFactory.undef"
+
+#endif /* RANDOMNUMBERDISTRIBUTIONFACTORY_HPP_ */
Index: src/RandomNumbers/RandomNumberDistributionFactory.undef
===================================================================
--- src/RandomNumbers/RandomNumberDistributionFactory.undef	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberDistributionFactory.undef	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,8 @@
+#ifdef RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
+
+#undef distribution_seq
+#undef distribution_seq_size
+
+#undef RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_
+
+#endif /* RANDOMNUMBERDISTRIBUTIONFACTORY_DEF_ */
Index: src/RandomNumbers/RandomNumberDistribution_Creator.hpp
===================================================================
--- src/RandomNumbers/RandomNumberDistribution_Creator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberDistribution_Creator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,20 @@
+/*
+ * RandomNumberDistribution_Creator.hpp
+ *
+ *  Created on: Jan 3, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERDISTRIBUTION_CREATOR_HPP_
+#define RANDOMNUMBERDISTRIBUTION_CREATOR_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Creator_impl.hpp"
+
+CONSTRUCT_CREATOR(RandomNumberDistribution)
+
+#endif /* RANDOMNUMBERDISTRIBUTION_CREATOR_HPP_ */
Index: src/RandomNumbers/RandomNumberDistribution_Encapsulation.hpp
===================================================================
--- src/RandomNumbers/RandomNumberDistribution_Encapsulation.hpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/RandomNumberDistribution_Encapsulation.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -15,7 +15,4 @@
 
 #include <typeinfo>
-
-#include "RandomNumberDistribution.hpp"
-#include "RandomNumberGeneratorFactory.hpp"
 
 #include <boost/nondet_random.hpp>
@@ -38,4 +35,8 @@
 #include <boost/random/uniform_smallint.hpp>
 
+#include "RandomNumberDistribution_Creator.hpp"
+#include "RandomNumberDistribution.hpp"
+#include "RandomNumberGeneratorFactory.hpp"
+
 #include "unittests/RandomNumberGeneratorFactoryUnitTest.hpp"
 
@@ -48,5 +49,5 @@
  */
 template <class distribution>
-class RandomNumberDistribution_Encapsulation : public RandomNumberDistribution
+class RandomNumberDistribution_Encapsulation : public RandomNumberDistribution, public RandomNumberDistribution_Creator< RandomNumberDistribution_Encapsulation<distribution> >
 {
   /**
@@ -83,5 +84,5 @@
    *
    */
-  ~RandomNumberDistribution_Encapsulation() {}
+  virtual ~RandomNumberDistribution_Encapsulation() {}
 private:
   distribution distribution_type;
Index: src/RandomNumbers/RandomNumberEngineFactory.cpp
===================================================================
--- src/RandomNumbers/RandomNumberEngineFactory.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberEngineFactory.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/*
+ * RandomNumberEngineFactory.cpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include <utility>
+#include "CodePatterns/Singleton_impl.hpp"
+#include "CodePatterns/Assert.hpp"
+
+#include <boost/preprocessor/facilities/empty.hpp>
+#include <boost/preprocessor/punctuation/paren.hpp>
+
+#include "TemplatePowerSetGenerator.hpp"
+#include "EmptyPrototypeTable.hpp"
+
+#include "RandomNumberEngine_Encapsulation.hpp"
+
+#include "RandomNumberEngineFactory.hpp"
+#include "RandomNumberEngineFactory.def"
+
+//enum RandomNumberEngineFactory::Engine RandomNumberEngineFactory::engine = (enum RandomNumberEngineFactory::Engine) 0;
+RandomNumberEngineFactory::EngineMap RandomNumberEngineFactory::engines;
+RandomNumberEngineFactory::EngineNamesMap RandomNumberEngineFactory::engineNames;
+RandomNumberEngineFactory::EngineTable RandomNumberEngineFactory::EnginePrototypeTable;
+
+
+RandomNumberEngineFactory::RandomNumberEngineFactory()
+{
+  FillEnumTable();
+  FillPrototypeTable();
+}
+
+
+RandomNumberEngineFactory::~RandomNumberEngineFactory()
+{
+  // clear out factories map to allow boost::shared_ptr to do their work (i.e. to release mem)
+  // this is necessary as factories is a object
+  engines.clear();
+  engineNames.clear();
+  EmptyPrototypeTable<EngineTable> (EnginePrototypeTable);
+}
+
+void RandomNumberEngineFactory::FillEnumTable()
+{
+  // insert all known engines
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, engine_seq, engines)
+#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq)-1 )
+#include BOOST_PP_LOCAL_ITERATE()
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, engine_seq_a, engines)
+#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq_a)-1 )
+#include BOOST_PP_LOCAL_ITERATE()
+  for (EngineMap::const_iterator iter = engines.begin();
+      iter != engines.end();
+      ++iter) {
+    engineNames.insert(make_pair(iter->second, iter->first));
+  }
+}
+
+void RandomNumberEngineFactory::FillPrototypeTable()
+{
+  // fill EnginePrototypeTable
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, engine_seq, EnginePrototypeTable, new RandomNumberEngine_Creator< RandomNumberEngine_Encapsulation , boost::, >)
+#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq)-1 )
+#include BOOST_PP_LOCAL_ITERATE()
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, engine_seq_a, EnginePrototypeTable, new RandomNumberEngine_Creator< RandomNumberEngine_Encapsulation , boost::, >)
+#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq_a)-1 )
+#include BOOST_PP_LOCAL_ITERATE()
+}
+
+RandomNumberEngine* RandomNumberEngineFactory::getEngine(enum Engine engine_type) const
+{
+  return EnginePrototypeTable[engine_type]->create();
+}
+
+RandomNumberEngine* RandomNumberEngineFactory::getEngine(const std::string engine_name) const
+{
+  ASSERT(engines.count(engine_name) != 0,
+      "RandomNumberEngineFactory::getEngine() - engine "+engine_name+" is not registered.");
+  return EnginePrototypeTable[ engines[engine_name] ]->create();
+}
+
+const std::string &RandomNumberEngineFactory::getName(enum Engine engine_type) const
+{
+  return engineNames[engine_type];
+}
+
+enum RandomNumberEngineFactory::Engine RandomNumberEngineFactory::getEnum(const std::string engine_name) const
+{
+  ASSERT(engines.count(engine_name) != 0,
+      "RandomNumberEngineFactory::getEnum() - engine "+engine_name+" is not registered.");
+  return engines[engine_name];
+}
+
+CONSTRUCT_SINGLETON(RandomNumberEngineFactory)
+
+#include "RandomNumberEngineFactory.undef"
+
Index: src/RandomNumbers/RandomNumberEngineFactory.def
===================================================================
--- src/RandomNumbers/RandomNumberEngineFactory.def	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberEngineFactory.def	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,44 @@
+#ifndef RANDOMNUMBERENGINEFACTORY_DEF_
+#define RANDOMNUMBERENGINEFACTORY_DEF_
+
+/** BOOST_PP_SEQ of all random::boost engine types,
+ * see see http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/reference.html#boost_random.reference.concepts
+ */
+#define engine_seq \
+(minstd_rand0)
+
+/*
+(minstd_rand)\
+(rand48)\
+(ecuyer1988)\
+(kreutzer1986)\
+(taus88)\
+(hellekalek1995)\
+(mt11213b)\
+(mt19937)
+*/
+#define engine_seq_a \
+(lagged_fibonacci607)
+
+/*
+(lagged_fibonacci1279)\
+(lagged_fibonacci2281)\
+(lagged_fibonacci3217)\
+(lagged_fibonacci4423)\
+(lagged_fibonacci9689)\
+(lagged_fibonacci19937)\
+(lagged_fibonacci23209)\
+(lagged_fibonacci44497)\
+(ranlux3)\
+(ranlux4)\
+(ranlux64_3)\
+(ranlux64_4)\
+(ranlux3_01)\
+(ranlux4_01)\
+(ranlux64_3_01)\
+(ranlux64_4_01)
+*/
+#define engine_seq_size BOOST_PP_SEQ_SIZE(engine_seq)
+#define engine_seq_a_size BOOST_PP_SEQ_SIZE(engine_seq_a)
+
+#endif /* RANDOMNUMBERENGINEFACTORY_DEF_ */
Index: src/RandomNumbers/RandomNumberEngineFactory.hpp
===================================================================
--- src/RandomNumbers/RandomNumberEngineFactory.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberEngineFactory.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,119 @@
+/*
+ * RandomNumberEngineFactory.hpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERENGINEFACTORY_HPP_
+#define RANDOMNUMBERENGINEFACTORY_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/Singleton.hpp"
+
+
+#include <map>
+
+#include "TemplatePowerSetGenerator.hpp"
+#include "RandomNumberEngineFactory.def"
+
+#include "unittests/RandomNumberEngineFactoryUnitTest.hpp"
+
+#include "RandomNumberEngine_Creator.hpp"
+
+class RandomNumberEngine;
+
+/** This is the abstract factory class for random number engines.
+ *
+ * The reason for creating the engines as this is that we would like to set
+ * the engines parameters, via some Action, and then onward only have
+ * random number engines of this type using these parameters. Hence, we have
+ * a singleton factory that is controlled by the Action and can then create
+ * engines wherever we like in the code by having the factory create one.
+ *
+ */
+class RandomNumberEngineFactory : public Singleton<RandomNumberEngineFactory>
+{
+  friend class Singleton<RandomNumberEngineFactory>;
+  friend class RandomNumberEngineFactoryTest;
+public:
+
+protected:
+  RandomNumberEngineFactory();
+  virtual ~RandomNumberEngineFactory();
+
+public:
+  /** Enumeration of all (pseudo-)random number engines implemented in
+   *  boost::random, see
+   *  http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/reference.html#boost_random.reference.concepts
+   */
+  enum Engine {
+BOOST_PP_REPEAT( engine_seq_size, seqitems_as_enum, engine_seq)
+,
+BOOST_PP_REPEAT( engine_seq_a_size, seqitems_as_enum, engine_seq_a)
+  };
+
+  /** Getter for current type of engine.
+   *
+   * @param enumeration index of engine
+   * @return reference to copy of engine
+   */
+  RandomNumberEngine* getEngine(enum Engine engine_type) const;
+
+  /** Getter for current type of engine.
+   *
+   * @param name of engine
+   * @return reference to copy of engine
+   */
+  RandomNumberEngine* getEngine(const std::string engine_name) const;
+
+  /** Getter for the name of the current type of engine.
+   *
+   * @return name of engine
+   */
+  const std::string &getName(enum Engine engine_type) const;
+
+  /** Getter for the enumeration index of the current type of engine.
+   *
+   * @return enum of engine
+   */
+  enum Engine getEnum(const std::string engine_name) const;
+
+protected:
+private:
+  /** Creates instances of all possible engine types
+   *  and stores them in \a EnginePrototypeTable.
+   */
+  void FillPrototypeTable();
+
+  /** Create association for enums to strings and vice versa
+   *  and stores them in \a engines tables.
+   */
+  void FillEnumTable();
+
+  typedef std::map<
+      std::string,
+      enum Engine
+      > EngineMap;
+  typedef std::map<
+      enum Engine,
+      IRandomNumberEngine_Creator *
+      > EngineTable;
+  typedef std::map<
+      enum Engine,
+      std::string
+        > EngineNamesMap;
+
+  //static enum Engine engine;
+  static EngineMap engines;
+  static EngineTable EnginePrototypeTable;
+  static EngineNamesMap engineNames;
+};
+
+#include "RandomNumberEngineFactory.undef"
+
+#endif /* RANDOMNUMBERENGINEFACTORY_HPP_ */
Index: src/RandomNumbers/RandomNumberEngineFactory.undef
===================================================================
--- src/RandomNumbers/RandomNumberEngineFactory.undef	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberEngineFactory.undef	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,10 @@
+#ifdef RANDOMNUMBERENGINEFACTORY_DEF_
+
+#undef engine_seq
+#undef engine_seq_size
+#undef engine_seq_a
+#undef engine_seq_a_size
+
+#undef RANDOMNUMBERENGINEFACTORY_DEF_
+
+#endif /* RANDOMNUMBERENGINEFACTORY_DEF_ */
Index: src/RandomNumbers/RandomNumberEngine_Creator.hpp
===================================================================
--- src/RandomNumbers/RandomNumberEngine_Creator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberEngine_Creator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,20 @@
+/*
+ * RandomNumberEngine_Creator.hpp
+ *
+ *  Created on: Jan 3, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERENGINE_CREATOR_HPP_
+#define RANDOMNUMBERENGINE_CREATOR_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Creator_impl.hpp"
+
+CONSTRUCT_CREATOR(RandomNumberEngine)
+
+#endif /* RANDOMNUMBERENGINE_CREATOR_HPP_ */
Index: src/RandomNumbers/RandomNumberEngine_Encapsulation.hpp
===================================================================
--- src/RandomNumbers/RandomNumberEngine_Encapsulation.hpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/RandomNumberEngine_Encapsulation.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -16,7 +16,4 @@
 #include <typeinfo>
 
-#include "RandomNumberEngine.hpp"
-#include "RandomNumberGeneratorFactory.hpp"
-
 #include <boost/nondet_random.hpp>
 #include <boost/random.hpp>
@@ -34,4 +31,8 @@
 #include <boost/random/xor_combine.hpp>
 
+#include "RandomNumberEngine_Creator.hpp"
+#include "RandomNumberEngine.hpp"
+
+#include "RandomNumberGeneratorFactory.hpp"
 #include "unittests/RandomNumberGeneratorFactoryUnitTest.hpp"
 
@@ -44,5 +45,5 @@
  */
 template <class engine>
-class RandomNumberEngine_Encapsulation : public RandomNumberEngine
+class RandomNumberEngine_Encapsulation : public RandomNumberEngine, public RandomNumberEngine_Creator< RandomNumberEngine_Encapsulation<engine> >
 {
   /**
@@ -86,5 +87,5 @@
    *
    */
-  ~RandomNumberEngine_Encapsulation() {}
+  virtual ~RandomNumberEngine_Encapsulation() {}
 private:
   engine engine_type;
Index: src/RandomNumbers/RandomNumberGeneratorFactory.cpp
===================================================================
--- src/RandomNumbers/RandomNumberGeneratorFactory.cpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/RandomNumberGeneratorFactory.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -25,74 +25,30 @@
 
 #include "TemplatePowerSetGenerator.hpp"
+#include "EmptyPrototypeTable.hpp"
 
-#include "RandomNumberEngine_Encapsulation.hpp"
-#include "RandomNumberDistribution_Encapsulation.hpp"
+#include "RandomNumberEngineFactory.hpp"
+#include "RandomNumberDistributionFactory.hpp"
 #include "RandomNumberGenerator_Encapsulation.hpp"
 
 #include <boost/preprocessor/facilities/empty.hpp>
 #include <boost/preprocessor/punctuation/paren.hpp>
+#include <boost/preprocessor/seq/for_each_product.hpp>
+#include <boost/preprocessor/facilities/identity.hpp>
+#include <boost/preprocessor/facilities/expand.hpp>
+#include <boost/preprocessor/seq/seq.hpp>
+
 
 #include "RandomNumberGeneratorFactory.hpp"
-#include "RandomNumberGeneratorFactory.def"
+#include "RandomNumberDistributionFactory.def"
+#include "RandomNumberEngineFactory.def"
 
-enum RandomNumberGeneratorFactory::Engine RandomNumberGeneratorFactory::engine = (enum RandomNumberGeneratorFactory::Engine) 0;
-enum RandomNumberGeneratorFactory::Distribution RandomNumberGeneratorFactory::distribution = (enum RandomNumberGeneratorFactory::Distribution) 0;
-RandomNumberGeneratorFactory::EngineMap RandomNumberGeneratorFactory::engines;
-RandomNumberGeneratorFactory::EngineNamesMap RandomNumberGeneratorFactory::engineNames;
-RandomNumberGeneratorFactory::DistributionMap RandomNumberGeneratorFactory::distributions;
-RandomNumberGeneratorFactory::DistributionNamesMap RandomNumberGeneratorFactory::distributionNames;
-RandomNumberGeneratorFactory::EngineTable RandomNumberGeneratorFactory::EnginePrototypeTable;
-RandomNumberGeneratorFactory::DistributionTable RandomNumberGeneratorFactory::DistributionPrototypeTable;
+enum RandomNumberDistributionFactory::Distribution RandomNumberGeneratorFactory::distribution = (enum RandomNumberDistributionFactory::Distribution) 0;
+enum RandomNumberEngineFactory::Engine RandomNumberGeneratorFactory::engine = (enum RandomNumberEngineFactory::Engine) 0;
 RandomNumberGeneratorFactory::EngineDistributionTable RandomNumberGeneratorFactory::GeneratorPrototypeTable;
-
 
 RandomNumberGeneratorFactory::RandomNumberGeneratorFactory()
 {
-  // insert all known engines
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, engine_seq, engines)
-#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq)-1 )
-#include BOOST_PP_LOCAL_ITERATE()
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, engine_seq_a, engines)
-#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq_a)-1 )
-#include BOOST_PP_LOCAL_ITERATE()
-  for (EngineMap::const_iterator iter = engines.begin();
-      iter != engines.end();
-      ++iter) {
-    engineNames.insert(make_pair(iter->second, iter->first));
-  }
-
-	// insert all known distributions
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_string_enum_map(~, n, distribution_seq, distributions)
-#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distribution_seq)-1 )
-#include BOOST_PP_LOCAL_ITERATE()
-  for (DistributionMap::const_iterator iter = distributions.begin();
-      iter != distributions.end();
-      ++iter) {
-    distributionNames.insert(make_pair(iter->second, iter->first));
-  }
-
-	FillPrototypeTables();
+	FillPrototypeTable();
 }
-
-/** Removes all pointers to instances from a table while free'ing memory.
- *
- * I.e. we assume class T to be a map of some key with its values pointers to
- * some classes that have to be free'd.
- *
- * \param _PrototypeTable table to empty
- */
-template <class T>
-void EmptyPrototypeTable(T &_PrototypeTable)
-{
-  for (typename T::iterator iter = _PrototypeTable.begin();
-      !_PrototypeTable.empty();
-      iter = _PrototypeTable.begin()) {
-    delete (iter->second);
-    _PrototypeTable.erase(iter);
-  }
-  _PrototypeTable.clear();
-}
-
-
 
 RandomNumberGeneratorFactory::~RandomNumberGeneratorFactory()
@@ -100,14 +56,8 @@
   // clear out factories map to allow boost::shared_ptr to do their work (i.e. to release mem)
   // this is necessary as factories is a object
-  engines.clear();
-  engineNames.clear();
-  EmptyPrototypeTable<EngineTable> (EnginePrototypeTable);
-  distributions.clear();
-  distributionNames.clear();
-  EmptyPrototypeTable<DistributionTable> (DistributionPrototypeTable);
   for (EngineDistributionTable::iterator iter = GeneratorPrototypeTable.begin();
       !GeneratorPrototypeTable.empty();
       iter = GeneratorPrototypeTable.begin()) {
-    EmptyPrototypeTable< std::map<enum Distribution,RandomNumberGenerator *> > (iter->second);
+    EmptyPrototypeTable< std::map<enum RandomNumberDistributionFactory::Distribution,IRandomNumberGenerator_Creator *> > (iter->second);
     GeneratorPrototypeTable.erase(iter);
   }
@@ -115,34 +65,27 @@
 }
 
-void RandomNumberGeneratorFactory::FillPrototypeTables()
+void RandomNumberGeneratorFactory::FillPrototypeTable()
 {
-  // fill EnginePrototypeTable
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, engine_seq, EnginePrototypeTable, new RandomNumberEngine_Encapsulation, boost::, )
-#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq)-1 )
-#include BOOST_PP_LOCAL_ITERATE()
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, engine_seq_a, EnginePrototypeTable, new RandomNumberEngine_Encapsulation, boost::, )
-#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(engine_seq_a)-1 )
-#include BOOST_PP_LOCAL_ITERATE()
+  // fill GeneratorPrototypeTable
+#define SequenceElementizer(z,data) (data)
 
-  // fill DistributionPrototypeTable
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_map(~, n, distribution_seq, DistributionPrototypeTable, new RandomNumberDistribution_Encapsulation, boost::, <>)
-#define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distribution_seq)-1 )
-#include BOOST_PP_LOCAL_ITERATE()
+#define distributionengine_seqseq \
+  BOOST_PP_SEQ_FOR_EACH_PRODUCT(SequenceElementizer, (engine_seq)(distribution_seq))
+#define distributionengine_seqseq_a \
+  BOOST_PP_SEQ_FOR_EACH_PRODUCT(SequenceElementizer, (engine_seq_a)(distribution_seq))
 
-  // fill GeneratorPrototypeTable
-#define DoubleElementSequenceElementizer(z,data,elem) ((data)(elem))
+#define suffixseq ()(<> > )
+#define tableseq (*EnginePrototypeTable)(*DistributionPrototypeTable)
+#define name_spaces_seq (RandomNumberEngineFactory::)(RandomNumberDistributionFactory::)
 
-#define seqseqiterate(z,n,seq) BOOST_PP_SEQ_FOR_EACH(DoubleElementSequenceElementizer, BOOST_PP_SEQ_ELEM(n,seq), distribution_seq)
-
-#define distributionengine_seqseq BOOST_PP_REPEAT( \
-  BOOST_PP_SEQ_SIZE(engine_seq), seqseqiterate, engine_seq )
-
-#define distributionengine_seqseq_a BOOST_PP_REPEAT( \
-  BOOST_PP_SEQ_SIZE(engine_seq_a), seqseqiterate, engine_seq_a )
-
-#define suffixseq ()(<>)
-#define tableseq (*EnginePrototypeTable)(*DistributionPrototypeTable)
+#define size_tupels BOOST_PP_SEQ_SIZE(tableseq)
 
 #define TableItemPrinter(z,n,sequence) \
+  [ \
+  BOOST_PP_SEQ_ELEM(n,name_spaces_seq) \
+  BOOST_PP_SEQ_ELEM(n,sequence) \
+  ]
+
+#define TemplateItemPrinter(z,n,sequence) \
   BOOST_PP_COMMA_IF(n) \
   boost:: \
@@ -150,71 +93,64 @@
   BOOST_PP_SEQ_ELEM(n,suffixseq)
 
-#define ParamItemPrinter(z,n,sequence) \
-  BOOST_PP_COMMA_IF(n) \
-  BOOST_PP_SEQ_ELEM(n,tableseq) \
-  [ \
-  BOOST_PP_SEQ_ELEM(n,sequence) \
-  ]
+#define ParamItemPrinter(z,n,sequence)
 
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, distributionengine_seqseq, GeneratorPrototypeTable, new RandomNumberGenerator_Encapsulation, TableItemPrinter, ParamItemPrinter)
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, size_tupels, distributionengine_seqseq, GeneratorPrototypeTable, TableItemPrinter, new RandomNumberGenerator_Creator< RandomNumberGenerator_Encapsulation , TemplateItemPrinter, ParamItemPrinter)
 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distributionengine_seqseq)-1 )
 #include BOOST_PP_LOCAL_ITERATE()
 
-#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, distributionengine_seqseq_a, GeneratorPrototypeTable, new RandomNumberGenerator_Encapsulation, TableItemPrinter, ParamItemPrinter)
+#define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(~, n, size_tupels, distributionengine_seqseq_a, GeneratorPrototypeTable, TableItemPrinter, new RandomNumberGenerator_Creator< RandomNumberGenerator_Encapsulation , TemplateItemPrinter, ParamItemPrinter)
 #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(distributionengine_seqseq_a)-1 )
 #include BOOST_PP_LOCAL_ITERATE()
 }
 
-RandomNumberGenerator& RandomNumberGeneratorFactory::makeRandomNumberGenerator() const
+RandomNumberGenerator* RandomNumberGeneratorFactory::makeRandomNumberGenerator() const
 {
   // Instantiate and return (implicitly creates a copy of the stored prototype)
-  return *GeneratorPrototypeTable[engine][distribution];
+  return (GeneratorPrototypeTable[engine][distribution]->create());
 }
 
-RandomNumberGenerator& RandomNumberGeneratorFactory::makeRandomNumberGenerator(std::string engine_type, std::string distribution_type) const
+RandomNumberGenerator* RandomNumberGeneratorFactory::makeRandomNumberGenerator(
+    std::string engine_type,
+    std::string distribution_type
+    ) const
 {
-  enum Engine eng_type;
-  enum Distribution dis_type;
+  enum RandomNumberEngineFactory::Engine eng_type;
+  enum RandomNumberDistributionFactory::Distribution dis_type;
 
   // Instantiate and return (implicitly creates a copy of the stored prototype)
   if (!engine_type.empty()) {
-    ASSERT(engines.count(engine_type) != 0,
-      "RandomNumberGeneratorFactory::makeRandomNumberGenerator() - Selected engine "+engine_type+"is not registered.");
-    eng_type = engines[engine_type];
+    eng_type = RandomNumberEngineFactory::getInstance().getEnum(engine_type);
   } else
     eng_type = engine;
   if (!distribution_type.empty()) {
-    ASSERT(distributions.count(distribution_type) != 0,
-        "RandomNumberGeneratorFactory::makeRandomNumberGenerator() - Selected distribution "+distribution_type+"is not registered.");
-    dis_type = distributions[distribution_type];
+    dis_type = RandomNumberDistributionFactory::getInstance().getEnum(distribution_type);
   } else
     dis_type = distribution;
-  return *GeneratorPrototypeTable[ eng_type ][ dis_type ];
+  return (GeneratorPrototypeTable[ eng_type ][ dis_type ]->create());
 }
 
 void RandomNumberGeneratorFactory::setEngine(std::string engine_type)
 {
-  ASSERT(engines.count(engine_type) != 0,"Selected engine "+engine_type+"is not registered.");
-  engine = engines[engine_type];
+  engine = RandomNumberEngineFactory::getInstance().getEnum(engine_type);
 }
 
-const std::string &RandomNumberGeneratorFactory::getEngine() const
+const std::string &RandomNumberGeneratorFactory::getEngineName() const
 {
-  return engineNames[engine];
+  return RandomNumberEngineFactory::getInstance().getName(engine);
 }
 
 void RandomNumberGeneratorFactory::setDistribution(std::string distribution_type)
 {
-  ASSERT(distributions.count(distribution_type) != 0 ,"Selected distribution "+distribution_type+"is not registered.");
-  distribution = distributions[distribution_type];
+  distribution = RandomNumberDistributionFactory::getInstance().getEnum(distribution_type);
 }
 
-const std::string &RandomNumberGeneratorFactory::getDistribution() const
+const std::string &RandomNumberGeneratorFactory::getDistributionName() const
 {
-  return distributionNames[distribution];
+  return RandomNumberDistributionFactory::getInstance().getName(distribution);
 }
 
 CONSTRUCT_SINGLETON(RandomNumberGeneratorFactory)
 
-#include "RandomNumberGeneratorFactory.undef"
+#include "RandomNumberDistributionFactory.undef"
+#include "RandomNumberEngineFactory.undef"
 
Index: c/RandomNumbers/RandomNumberGeneratorFactory.def
===================================================================
--- src/RandomNumbers/RandomNumberGeneratorFactory.def	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ 	(revision )
@@ -1,68 +1,0 @@
-#ifndef RANDOMNUMBERGENERATORFACTORY_DEF_
-#define RANDOMNUMBERGENERATORFACTORY_DEF_
-
-/** BOOST_PP_SEQ of all random::boost engine types,
- * see see http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/reference.html#boost_random.reference.concepts
- */
-#define engine_seq \
-(minstd_rand0)
-
-/*
-(minstd_rand)\
-(rand48)\
-(ecuyer1988)\
-(kreutzer1986)\
-(taus88)\
-(hellekalek1995)\
-(mt11213b)\
-(mt19937)
-*/
-#define engine_seq_a \
-(lagged_fibonacci607)
-
-/*
-(lagged_fibonacci1279)\
-(lagged_fibonacci2281)\
-(lagged_fibonacci3217)\
-(lagged_fibonacci4423)\
-(lagged_fibonacci9689)\
-(lagged_fibonacci19937)\
-(lagged_fibonacci23209)\
-(lagged_fibonacci44497)\
-(ranlux3)\
-(ranlux4)\
-(ranlux64_3)\
-(ranlux64_4)\
-(ranlux3_01)\
-(ranlux4_01)\
-(ranlux64_3_01)\
-(ranlux64_4_01)
-*/
-#define engine_seq_size BOOST_PP_SEQ_SIZE(engine_seq)
-#define engine_seq_a_size BOOST_PP_SEQ_SIZE(engine_seq_a)
-
-/** BOOST_PP_SEQ of all random::boost distribution types,
- * see see http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/reference.html#boost_random.reference.concepts
- */
-#define distribution_seq \
-(uniform_smallint)\
-(uniform_int)
-
-/*
-(uniform_01)\
-(uniform_real)\
-(bernoulli_distribution)\
-(binomial_distribution)\
-(cauchy_distribution)\
-(gamma_distribution)\
-(poisson_distribution)\
-(geometric_distribution)\
-(triangle_distribution)\
-(exponential_distribution)\
-(normal_distribution)\
-(lognormal_distribution)\
-(uniform_on_sphere)
-*/
-#define distribution_seq_size BOOST_PP_SEQ_SIZE(distribution_seq)
-
-#endif /* RANDOMNUMBERGENERATORFACTORY_DEF_ */
Index: src/RandomNumbers/RandomNumberGeneratorFactory.hpp
===================================================================
--- src/RandomNumbers/RandomNumberGeneratorFactory.hpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/RandomNumberGeneratorFactory.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -16,14 +16,14 @@
 #include "CodePatterns/Singleton.hpp"
 
-#include "RandomNumberDistribution.hpp"
-#include "RandomNumberEngine.hpp"
-#include "RandomNumberGenerator.hpp"
+#include "RandomNumberDistributionFactory.hpp"
+#include "RandomNumberEngineFactory.hpp"
 
 #include <map>
 
-#include "TemplatePowerSetGenerator.hpp"
-#include "RandomNumberGeneratorFactory.def"
+#include "RandomNumberGenerator_Creator.hpp"
 
 #include "unittests/RandomNumberGeneratorFactoryUnitTest.hpp"
+
+class RandomNumberGenerator;
 
 /** This is the abstract factory class for random number generators.
@@ -40,4 +40,5 @@
   friend class Singleton<RandomNumberGeneratorFactory>;
   friend class RandomNumberGeneratorFactoryTest;
+
 public:
 
@@ -47,25 +48,9 @@
 
 public:
-  /** Enumeration of all (pseudo-)random number engines implemented in
-   *  boost::random, see
-   *  http://www.boost.org/doc/libs/1_45_0/doc/html/boost_random/reference.html#boost_random.reference.concepts
-   */
-  enum Engine {
-BOOST_PP_REPEAT( engine_seq_size, seqitems_as_enum, engine_seq)
-,
-BOOST_PP_REPEAT( engine_seq_a_size, seqitems_as_enum, engine_seq_a)
-  };
-
-  /** Enumeration of all distribution implemented in random::boost.
-   */
-  enum Distribution {
-BOOST_PP_REPEAT( distribution_seq_size, seqitems_as_enum, distribution_seq)
-  };
-
   /** Create a Generator of previously set type.
    *
    * \return random number generator instance
    */
-  RandomNumberGenerator& makeRandomNumberGenerator() const;
+  RandomNumberGenerator* makeRandomNumberGenerator() const;
 
   /** Create a Generator of desired combination of engine and distribution.
@@ -75,8 +60,9 @@
    *
    * \param engine_type name of engine, give empty string for current default
-   * \param distribution_type name of distribution, give empty string for current default
+   * \param distribution_type name of distribution, give empty string for
+   *        current default
    * \return random number generator instance
    */
-  RandomNumberGenerator& makeRandomNumberGenerator(std::string engine_type, std::string distribution_type) const;
+  RandomNumberGenerator* makeRandomNumberGenerator(std::string engine_type, std::string distribution_type) const;
 
   /** Specify the precise type of the engine to build
@@ -86,9 +72,9 @@
   void setEngine(std::string engine_type);
 
-  /** Getter for current type of engine.
+  /** Getter for the name of the current type of engine.
    *
    * @return name of engine
    */
-  const std::string &getEngine() const;
+  const std::string &getEngineName() const;
 
   /** Specify the precise type of the distribution to build
@@ -98,9 +84,9 @@
   void setDistribution(std::string distribution_type);
 
-  /** Getter for current type of distribution.
+  /** Getter for the name of the current type of distribution.
    *
    * @return name of distribution
    */
-  const std::string &getDistribution() const;
+  const std::string &getDistributionName() const;
 
 protected:
@@ -109,51 +95,17 @@
    *  and stores them in \a PrototypeTable.
    */
-  void FillPrototypeTables();
+  void FillPrototypeTable();
 
   typedef std::map<
-      std::string,
-      enum Engine
-      > EngineMap;
-  typedef std::map<
-      enum Engine,
-      RandomNumberEngine *
-      > EngineTable;
-  typedef std::map<
-      enum Engine,
-      std::string
-        > EngineNamesMap;
-
-  typedef std::map<
-      std::string,
-      enum Distribution
-      > DistributionMap;
-  typedef std::map<
-      enum Distribution,
-      RandomNumberDistribution *
-      > DistributionTable;
-  typedef std::map<
-      enum Distribution,
-      std::string
-      > DistributionNamesMap;
-
-  typedef std::map<
-      enum Engine,
+      enum RandomNumberEngineFactory::Engine,
       std::map<
-        enum Distribution,
-        RandomNumberGenerator *>
+        enum RandomNumberDistributionFactory::Distribution,
+        IRandomNumberGenerator_Creator *>
   > EngineDistributionTable;
 
-  static enum Engine engine;
-  static enum Distribution distribution;
-  static EngineMap engines;
-  static EngineTable EnginePrototypeTable;
-  static EngineNamesMap engineNames;
-  static DistributionMap distributions;
-  static DistributionTable DistributionPrototypeTable;
-  static DistributionNamesMap distributionNames;
+  static enum RandomNumberDistributionFactory::Distribution distribution;
+  static enum RandomNumberEngineFactory::Engine engine;
   static EngineDistributionTable GeneratorPrototypeTable;
 };
 
-#include "RandomNumberGeneratorFactory.undef"
-
 #endif /* RANDOMNUMBERGENERATORFACTORY_HPP_ */
Index: c/RandomNumbers/RandomNumberGeneratorFactory.undef
===================================================================
--- src/RandomNumbers/RandomNumberGeneratorFactory.undef	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ 	(revision )
@@ -1,10 +1,0 @@
-#ifdef RANDOMNUMBERGENERATORFACTORY_DEF_
-
-#undef distribution_seq
-#undef distribution_seq_size
-#undef generator_seq
-#undef generator_seq_size
-
-#undef RANDOMNUMBERGENERATORFACTORY_DEF_
-
-#endif /* RANDOMNUMBERGENERATORFACTORY_DEF_ */
Index: src/RandomNumbers/RandomNumberGenerator_Creator.hpp
===================================================================
--- src/RandomNumbers/RandomNumberGenerator_Creator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/RandomNumberGenerator_Creator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,20 @@
+/*
+ * RandomNumberGenerator_Creator.hpp
+ *
+ *  Created on: Jan 3, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERGENERATOR_CREATOR_HPP_
+#define RANDOMNUMBERGENERATOR_CREATOR_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Creator_impl.hpp"
+
+CONSTRUCT_CREATOR(RandomNumberGenerator)
+
+#endif /* RANDOMNUMBERGENERATOR_CREATOR_HPP_ */
Index: src/RandomNumbers/RandomNumberGenerator_Encapsulation.hpp
===================================================================
--- src/RandomNumbers/RandomNumberGenerator_Encapsulation.hpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/RandomNumberGenerator_Encapsulation.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -14,9 +14,42 @@
 #endif
 
-#include "RandomNumberDistribution.hpp"
-#include "RandomNumberEngine.hpp"
+#include <boost/nondet_random.hpp>
+#include <boost/random.hpp>
+#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/exponential_distribution.hpp>
+#include <boost/random/gamma_distribution.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/lognormal_distribution.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/poisson_distribution.hpp>
+#include <boost/random/triangle_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_on_sphere.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_smallint.hpp>
+#include <boost/random/additive_combine.hpp>
+#include <boost/random/discard_block.hpp>
+#include <boost/random/inversive_congruential.hpp>
+#include <boost/random/lagged_fibonacci.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/linear_feedback_shift.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/random_number_generator.hpp>
+#include <boost/random/ranlux.hpp>
+#include <boost/random/shuffle_output.hpp>
+#include <boost/random/subtract_with_carry.hpp>
+#include <boost/random/xor_combine.hpp>
+#include <boost/random/variate_generator.hpp>
+
+#include <typeinfo>
+
+#include "RandomNumberGenerator_Creator.hpp"
 #include "RandomNumberGenerator.hpp"
+
 #include "RandomNumberGeneratorFactory.hpp"
-
 #include "unittests/RandomNumberGeneratorFactoryUnitTest.hpp"
 
@@ -36,5 +69,5 @@
  */
 template <class engine, class distribution>
-class RandomNumberGenerator_Encapsulation : public RandomNumberGenerator
+class RandomNumberGenerator_Encapsulation : public RandomNumberGenerator, public RandomNumberGenerator_Creator< RandomNumberGenerator_Encapsulation<engine, distribution> >
 {
   /**
@@ -43,4 +76,6 @@
   friend class RandomNumberGeneratorFactory;
   friend class RandomNumberGeneratorFactoryTest;
+
+  friend class RandomNumberGenerator_Creator< RandomNumberGenerator_Encapsulation<engine, distribution> >;
 
 public:
@@ -64,5 +99,5 @@
    */
   std::string EngineName() {
-    return engine_type.name();
+    return typeid(engine_type).name();
   }
 
@@ -71,7 +106,8 @@
    */
   std::string DistributionName() {
-    return distribution_type.name();
+    return typeid(distribution_type).name();
   }
 
+protected:
   /** Constructor that instantiates a specific random number generator and
    * distribution.
@@ -79,14 +115,10 @@
    * @param _distribution_type instance of the desired distribution
    */
-  RandomNumberGenerator_Encapsulation(
-      RandomNumberEngine &_engine_type,
-      RandomNumberDistribution &_distribution_type
-      ) :
-    engine_type(static_cast<RandomNumberEngine_Encapsulation<engine> &>(_engine_type)),
-    distribution_type(static_cast<RandomNumberDistribution_Encapsulation<distribution> &>(_distribution_type)),
-    randomgenerator(boost::variate_generator<engine, distribution> (
-        engine_type.getEngine(),
-        distribution_type.getDistribution()
-        ))
+  RandomNumberGenerator_Encapsulation() :
+    randomgenerator(
+        boost::variate_generator<engine, distribution> (
+            engine_type,
+            distribution_type)
+        )
   {
     // note that we instantiate the variate_generator with the copied instances!
@@ -96,8 +128,8 @@
    *
    */
-  ~RandomNumberGenerator_Encapsulation() {}
+  virtual ~RandomNumberGenerator_Encapsulation() {}
 private:
-  RandomNumberEngine_Encapsulation<engine> engine_type;
-  RandomNumberDistribution_Encapsulation<distribution> distribution_type;
+  engine engine_type;
+  distribution distribution_type;
   mutable boost::variate_generator<engine, distribution> randomgenerator;
 };
Index: src/RandomNumbers/TemplatePowerSetGenerator.hpp
===================================================================
--- src/RandomNumbers/TemplatePowerSetGenerator.hpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/TemplatePowerSetGenerator.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -25,4 +25,5 @@
 #include <boost/preprocessor/seq/enum.hpp>
 #include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/for_each_i.hpp>
 #include <boost/preprocessor/stringize.hpp>
 #include <boost/preprocessor/tuple/elem.hpp>
@@ -36,6 +37,7 @@
  * [test]
  */
-#define SquareBracketize(r, data, elem)  \
+#define SquareBracketize(r, data, i, elem)  \
 [ \
+BOOST_PP_SEQ_ELEM(i, data) \
 elem \
 ]
@@ -142,5 +144,5 @@
  * then we use
  * #define tableprinter(z,n,seq) BOOST_PP_SEQ_ELEM(n,seq)
- * #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(seqsize, n, seqseq, MultiMap, test::, tableprinter)
+ * #define BOOST_PP_LOCAL_MACRO(n) seqitems_as_enum_key_multidimmap(seqsize, n, seqseq, bla::, MultiMap, test::testfunction, test_printer, tableprinter)
  * #define BOOST_PP_LOCAL_LIMITS  (0, BOOST_PP_SEQ_SIZE(seqseq)-1 )
  * #include BOOST_PP_LOCAL_ITERATE()
@@ -152,10 +154,10 @@
 
  */
-#define seqitems_as_enum_key_multidimmap(z,n,seq_of_tupels, map, template_function, template_arg_printer, param_arg_printer) \
+#define seqitems_as_enum_key_multidimmap(z,n, size_tupels, seq_of_tupels, map, tableitems_arg_printer, template_function, template_arg_printer, param_arg_printer) \
   map \
-  BOOST_PP_SEQ_FOR_EACH(SquareBracketize, ~, BOOST_PP_SEQ_ELEM(n, seq_of_tupels)) \
+  BOOST_PP_REPEAT (size_tupels, tableitems_arg_printer,  BOOST_PP_SEQ_ELEM(n, seq_of_tupels) ) \
   = template_function \
-  < BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(tableseq), template_arg_printer,  BOOST_PP_SEQ_ELEM(n, seq_of_tupels) ) > (\
-  BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(tableseq), param_arg_printer,  BOOST_PP_SEQ_ELEM(n, seq_of_tupels) ) );
+  < BOOST_PP_REPEAT(size_tupels, template_arg_printer,  BOOST_PP_SEQ_ELEM(n, seq_of_tupels) ) > (\
+  BOOST_PP_REPEAT(size_tupels, param_arg_printer,  BOOST_PP_SEQ_ELEM(n, seq_of_tupels) ) );
 
 
Index: src/RandomNumbers/unittests/Makefile.am
===================================================================
--- src/RandomNumbers/unittests/Makefile.am	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/unittests/Makefile.am	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -8,5 +8,8 @@
 
 TESTS = \
-  RandomNumberGeneratorFactoryUnitTest
+  RandomNumberDistributionFactoryUnitTest \
+  RandomNumberEngineFactoryUnitTest \
+  RandomNumberGeneratorFactoryUnitTest \
+  RandomNumberGeneratorUnitTest
 
 
@@ -31,11 +34,40 @@
 PARSERLIBS = ../../Parser/libMolecuilderParser.la
 
+RandomNumberDistributionFactoryUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	RandomNumberDistributionFactoryUnitTest.cpp \
+	RandomNumberDistributionFactoryUnitTest.hpp \
+	$(srcdir)/../RandomNumberDistributionFactory.cpp \
+	$(srcdir)/../RandomNumberDistributionFactory.hpp
+RandomNumberDistributionFactoryUnitTest_LDADD = ${GSLLIBS}
+
+RandomNumberEngineFactoryUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	RandomNumberEngineFactoryUnitTest.cpp \
+	RandomNumberEngineFactoryUnitTest.hpp \
+	$(srcdir)/../RandomNumberEngineFactory.cpp \
+	$(srcdir)/../RandomNumberEngineFactory.hpp
+RandomNumberEngineFactoryUnitTest_LDADD = ${GSLLIBS}
+
 RandomNumberGeneratorFactoryUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
 	RandomNumberGeneratorFactoryUnitTest.cpp \
 	RandomNumberGeneratorFactoryUnitTest.hpp \
+	$(srcdir)/../RandomNumberDistributionFactory.cpp \
+	$(srcdir)/../RandomNumberDistributionFactory.hpp \
+	$(srcdir)/../RandomNumberEngineFactory.cpp \
+	$(srcdir)/../RandomNumberEngineFactory.hpp \
 	$(srcdir)/../RandomNumberGeneratorFactory.cpp \
 	$(srcdir)/../RandomNumberGeneratorFactory.hpp
 RandomNumberGeneratorFactoryUnitTest_LDADD = ${GSLLIBS}
 
+RandomNumberGeneratorUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+	RandomNumberGeneratorUnitTest.cpp \
+	RandomNumberGeneratorUnitTest.hpp \
+	$(srcdir)/../RandomNumberDistributionFactory.cpp \
+	$(srcdir)/../RandomNumberDistributionFactory.hpp \
+	$(srcdir)/../RandomNumberEngineFactory.cpp \
+	$(srcdir)/../RandomNumberEngineFactory.hpp \
+	$(srcdir)/../RandomNumberGeneratorFactory.cpp \
+	$(srcdir)/../RandomNumberGeneratorFactory.hpp
+RandomNumberGeneratorUnitTest_LDADD = ${GSLLIBS}
+
 
 #AUTOMAKE_OPTIONS = parallel-tests
Index: src/RandomNumbers/unittests/RandomNumberDistributionFactoryUnitTest.cpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberDistributionFactoryUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/unittests/RandomNumberDistributionFactoryUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+/*
+ * RandomNumberDistributionFactoryUnitTest.cpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include "CodePatterns/Assert.hpp"
+
+#include "RandomNumberDistributionFactoryUnitTest.hpp"
+#include "RandomNumbers/RandomNumberDistribution_Encapsulation.hpp"
+#include "RandomNumbers/RandomNumberDistributionFactory.hpp"
+
+#include <boost/nondet_random.hpp>
+#include <boost/random.hpp>
+#include <boost/random/additive_combine.hpp>
+#include <boost/random/discard_block.hpp>
+#include <boost/random/inversive_congruential.hpp>
+#include <boost/random/lagged_fibonacci.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/linear_feedback_shift.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/random_number_generator.hpp>
+#include <boost/random/ranlux.hpp>
+#include <boost/random/shuffle_output.hpp>
+#include <boost/random/subtract_with_carry.hpp>
+#include <boost/random/xor_combine.hpp>
+#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/exponential_distribution.hpp>
+#include <boost/random/gamma_distribution.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/lognormal_distribution.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/poisson_distribution.hpp>
+#include <boost/random/triangle_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_on_sphere.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_smallint.hpp>
+
+#include <typeinfo>
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( RandomNumberDistributionFactoryTest );
+
+void RandomNumberDistributionFactoryTest::setUp()
+{
+  RandomNumberDistributionFactory::getInstance();
+}
+
+void RandomNumberDistributionFactoryTest::tearDown()
+{
+  RandomNumberDistributionFactory::purgeInstance();
+}
+
+void RandomNumberDistributionFactoryTest::DistributionTest()
+{
+  // check the injectiveness of enum and string map
+  for (RandomNumberDistributionFactory::DistributionNamesMap::const_iterator
+      iter = RandomNumberDistributionFactory::getInstance().distributionNames.begin();
+      iter != RandomNumberDistributionFactory::getInstance().distributionNames.end();
+      ++iter) {
+    CPPUNIT_ASSERT_EQUAL(
+        iter->second,
+        RandomNumberDistributionFactory::getInstance().getName(
+            RandomNumberDistributionFactory::getInstance().getEnum(
+                iter->second
+            )
+        )
+    );
+  }
+
+  // check one of the distributions in the table
+  RandomNumberDistribution * rnd =
+      RandomNumberDistributionFactory::getInstance().
+      DistributionPrototypeTable[RandomNumberDistributionFactory::uniform_smallint]->create();
+  CPPUNIT_ASSERT_EQUAL(
+      std::string(typeid(boost::uniform_smallint<> ).name()),
+      rnd->name()
+  );
+  delete rnd;
+}
Index: src/RandomNumbers/unittests/RandomNumberDistributionFactoryUnitTest.hpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberDistributionFactoryUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/unittests/RandomNumberDistributionFactoryUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,34 @@
+/*
+ * RandomNumberDistributionFactoryUnitTest.hpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERDISTRIBUTIONFACTORYUNITTEST_HPP_
+#define RANDOMNUMBERDISTRIBUTIONFACTORYUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class RandomNumberDistributionFactoryTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( RandomNumberDistributionFactoryTest );
+  CPPUNIT_TEST ( DistributionTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void DistributionTest();
+
+private:
+};
+
+#endif /* RANDOMNUMBERDISTRIBUTIONFACTORYUNITTEST_HPP_ */
Index: src/RandomNumbers/unittests/RandomNumberEngineFactoryUnitTest.cpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberEngineFactoryUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/unittests/RandomNumberEngineFactoryUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+/*
+ * RandomNumberEngineFactoryUnitTest.cpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "RandomNumberEngineFactoryUnitTest.hpp"
+
+#include "RandomNumbers/RandomNumberEngine_Encapsulation.hpp"
+#include "RandomNumbers/RandomNumberEngineFactory.hpp"
+
+#include <boost/nondet_random.hpp>
+#include <boost/random.hpp>
+#include <boost/random/additive_combine.hpp>
+#include <boost/random/discard_block.hpp>
+#include <boost/random/inversive_congruential.hpp>
+#include <boost/random/lagged_fibonacci.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/linear_feedback_shift.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/random_number_generator.hpp>
+#include <boost/random/ranlux.hpp>
+#include <boost/random/shuffle_output.hpp>
+#include <boost/random/subtract_with_carry.hpp>
+#include <boost/random/xor_combine.hpp>
+#include <boost/random/bernoulli_distribution.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/cauchy_distribution.hpp>
+#include <boost/random/exponential_distribution.hpp>
+#include <boost/random/gamma_distribution.hpp>
+#include <boost/random/geometric_distribution.hpp>
+#include <boost/random/linear_congruential.hpp>
+#include <boost/random/lognormal_distribution.hpp>
+#include <boost/random/normal_distribution.hpp>
+#include <boost/random/poisson_distribution.hpp>
+#include <boost/random/triangle_distribution.hpp>
+#include <boost/random/uniform_01.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_on_sphere.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/uniform_smallint.hpp>
+
+#include <typeinfo>
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( RandomNumberEngineFactoryTest );
+
+void RandomNumberEngineFactoryTest::setUp()
+{
+  RandomNumberEngineFactory::getInstance();
+}
+
+void RandomNumberEngineFactoryTest::tearDown()
+{
+  RandomNumberEngineFactory::purgeInstance();
+}
+
+void RandomNumberEngineFactoryTest::EngineTest()
+{
+  // check the injectiveness of enum and string map
+  for (RandomNumberEngineFactory::EngineNamesMap::const_iterator
+      iter = RandomNumberEngineFactory::getInstance().engineNames.begin();
+      iter != RandomNumberEngineFactory::getInstance().engineNames.end();
+      ++iter) {
+    CPPUNIT_ASSERT_EQUAL(
+        iter->second,
+        RandomNumberEngineFactory::getInstance().getName(
+            RandomNumberEngineFactory::getInstance().getEnum(
+                iter->second
+            )
+        )
+    );
+  }
+
+  // check one of the engines in the table
+  RandomNumberEngine* rng =
+      RandomNumberEngineFactory::getInstance().
+      EnginePrototypeTable[RandomNumberEngineFactory::minstd_rand0]->create();
+  CPPUNIT_ASSERT_EQUAL(
+      std::string(typeid(boost::minstd_rand0).name()),
+      rng->name()
+  );
+  delete rng;
+}
Index: src/RandomNumbers/unittests/RandomNumberEngineFactoryUnitTest.hpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberEngineFactoryUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/unittests/RandomNumberEngineFactoryUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,34 @@
+/*
+ * RandomNumberEngineFactoryUnitTest.hpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERENGINEFACTORYUNITTEST_HPP_
+#define RANDOMNUMBERENGINEFACTORYUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class RandomNumberEngineFactoryTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( RandomNumberEngineFactoryTest );
+  CPPUNIT_TEST ( EngineTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void EngineTest();
+
+private:
+};
+
+#endif /* RANDOMNUMBERENGINEFACTORYUNITTEST_HPP_ */
Index: src/RandomNumbers/unittests/RandomNumberGeneratorFactoryUnitTest.cpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberGeneratorFactoryUnitTest.cpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/unittests/RandomNumberGeneratorFactoryUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -9,5 +9,5 @@
  * RandomNumberGeneratorFactoryUnitTest.cpp
  *
- *  Created on: Dec 31, 2010
+ *  Created on: Jan 03, 2011
  *      Author: heber
  */
@@ -26,7 +26,7 @@
 #include "RandomNumberGeneratorFactoryUnitTest.hpp"
 
-#include "RandomNumbers/RandomNumberDistribution_Encapsulation.hpp"
-#include "RandomNumbers/RandomNumberEngine_Encapsulation.hpp"
-#include "RandomNumbers/RandomNumberGenerator_Encapsulation.hpp"
+#include "RandomNumbers/RandomNumberGenerator.hpp"
+#include "RandomNumbers/RandomNumberEngineFactory.hpp"
+#include "RandomNumbers/RandomNumberDistributionFactory.hpp"
 #include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
 
@@ -80,61 +80,26 @@
 void RandomNumberGeneratorFactoryTest::tearDown()
 {
+  RandomNumberDistributionFactory::purgeInstance();
+  RandomNumberEngineFactory::purgeInstance();
   RandomNumberGeneratorFactory::purgeInstance();
-}
-
-void RandomNumberGeneratorFactoryTest::EngineTest()
-{
-  // check default value
-  CPPUNIT_ASSERT_EQUAL(
-      std::string("minstd_rand0"),
-      RandomNumberGeneratorFactory::getInstance().getEngine());
-
-  // check one of the engines in the table
-  CPPUNIT_ASSERT_EQUAL(
-      std::string(typeid(boost::minstd_rand0).name()),
-      RandomNumberGeneratorFactory::getInstance().
-            EnginePrototypeTable[RandomNumberGeneratorFactory::minstd_rand0]->name()
-  );
-}
-
-void RandomNumberGeneratorFactoryTest::DistributionTest()
-{
-  // check default value
-  CPPUNIT_ASSERT_EQUAL(
-      std::string("uniform_smallint"),
-      RandomNumberGeneratorFactory::getInstance().getDistribution());
-
-  // check one of the distributions in the table
-  CPPUNIT_ASSERT_EQUAL(
-      std::string(typeid(boost::uniform_smallint<> ).name()),
-      RandomNumberGeneratorFactory::getInstance().
-            DistributionPrototypeTable[RandomNumberGeneratorFactory::uniform_smallint]->name()
-  );
 }
 
 void RandomNumberGeneratorFactoryTest::GeneratorTest()
 {
+  RandomNumberGenerator *rng = NULL;
   // check one of the engines and distributions
+  rng = RandomNumberGeneratorFactory::getInstance().
+      GeneratorPrototypeTable[RandomNumberEngineFactory::minstd_rand0]
+                              [RandomNumberDistributionFactory::uniform_smallint]->create();
   CPPUNIT_ASSERT_EQUAL(
       std::string(typeid(boost::minstd_rand0).name()),
-      RandomNumberGeneratorFactory::getInstance().
-            GeneratorPrototypeTable[RandomNumberGeneratorFactory::minstd_rand0][RandomNumberGeneratorFactory::uniform_smallint]
-                                                                                ->EngineName()
+      rng->EngineName()
   );
   CPPUNIT_ASSERT_EQUAL(
       std::string(typeid(boost::uniform_smallint<> ).name()),
-      RandomNumberGeneratorFactory::getInstance().
-            GeneratorPrototypeTable[RandomNumberGeneratorFactory::minstd_rand0][RandomNumberGeneratorFactory::uniform_smallint]
-                                                                                ->DistributionName()
+      rng->DistributionName()
   );
+  delete rng;
 
-  // obtain some random values for uniform_smallint
-  RandomNumberGeneratorFactory::getInstance().setDistribution("uniform_smallint");
-  RandomNumberGenerator &rng = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
-  for (size_t i=0; i < 1000; ++i) {
-    const int testint = rng();
-    CPPUNIT_ASSERT_MESSAGE("randon number from uniform_smallint is out of [0:9]!", testint >= 0);
-    CPPUNIT_ASSERT_MESSAGE("randon number from uniform_smallint is out of [0:9]!", testint <= 9);
-  }
 }
 
Index: src/RandomNumbers/unittests/RandomNumberGeneratorFactoryUnitTest.hpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberGeneratorFactoryUnitTest.hpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/RandomNumbers/unittests/RandomNumberGeneratorFactoryUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -2,5 +2,5 @@
  * RandomNumberGeneratorFactoryUnitTest.hpp
  *
- *  Created on: Dec 31, 2010
+ *  Created on: Jan 03, 2011
  *      Author: heber
  */
@@ -20,6 +20,4 @@
 {
   CPPUNIT_TEST_SUITE( RandomNumberGeneratorFactoryTest );
-  CPPUNIT_TEST ( EngineTest );
-  CPPUNIT_TEST ( DistributionTest );
   CPPUNIT_TEST ( GeneratorTest );
   CPPUNIT_TEST_SUITE_END();
@@ -29,6 +27,4 @@
   void tearDown();
 
-  void EngineTest();
-  void DistributionTest();
   void GeneratorTest();
 
Index: src/RandomNumbers/unittests/RandomNumberGeneratorUnitTest.cpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberGeneratorUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/unittests/RandomNumberGeneratorUnitTest.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+/*
+ * RandomNumberGeneratorUnitTest.cpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "CodePatterns/Assert.hpp"
+
+#include "RandomNumberGeneratorUnitTest.hpp"
+
+#include "RandomNumbers/RandomNumberGenerator.hpp"
+#include "RandomNumbers/RandomNumberGeneratorFactory.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( RandomNumberGeneratorTest );
+
+void RandomNumberGeneratorTest::setUp()
+{
+}
+
+void RandomNumberGeneratorTest::tearDown()
+{
+  RandomNumberDistributionFactory::purgeInstance();
+  RandomNumberEngineFactory::purgeInstance();
+  RandomNumberGeneratorFactory::purgeInstance();
+}
+
+/** We check that the RandomNumberGenerator instance received
+ * from the RandomNumberGeneratorFactory is truely a copy and
+ * not the prototype instance.
+ */
+void RandomNumberGeneratorTest::PrototypeCopyTest()
+{
+  RandomNumberGenerator *rng1 = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
+  RandomNumberGenerator *rng2 = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
+
+  double random1_1 = (*rng1)();
+  double random1_2 = (*rng1)();
+  double random2_1 = (*rng2)();
+  double random2_2 = (*rng2)();
+
+  CPPUNIT_ASSERT(random1_1 == random2_1);
+  CPPUNIT_ASSERT(random1_2 == random2_2);
+
+  delete rng1;
+  delete rng2;
+}
+
+void RandomNumberGeneratorTest::Range_uniform_smallint_Test()
+{
+  // obtain some random values for uniform_smallint
+  RandomNumberGeneratorFactory::getInstance().setDistribution("uniform_smallint");
+  RandomNumberGenerator* rng = RandomNumberGeneratorFactory::getInstance().makeRandomNumberGenerator();
+  for (size_t i=0; i < 1000; ++i) {
+    const int testint = (*rng)();
+    CPPUNIT_ASSERT_MESSAGE("randon number from uniform_smallint is out of [0:9]!", testint >= 0);
+    CPPUNIT_ASSERT_MESSAGE("randon number from uniform_smallint is out of [0:9]!", testint <= 9);
+  }
+  delete rng;
+}
Index: src/RandomNumbers/unittests/RandomNumberGeneratorUnitTest.hpp
===================================================================
--- src/RandomNumbers/unittests/RandomNumberGeneratorUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
+++ src/RandomNumbers/unittests/RandomNumberGeneratorUnitTest.hpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -0,0 +1,36 @@
+/*
+ * RandomNumberGeneratorUnitTest.hpp
+ *
+ *  Created on: Jan 03, 2011
+ *      Author: heber
+ */
+
+#ifndef RANDOMNUMBERGENERATORUNITTEST_HPP_
+#define RANDOMNUMBERGENERATORUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class RandomNumberGeneratorTest : public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( RandomNumberGeneratorTest );
+  CPPUNIT_TEST ( PrototypeCopyTest );
+  CPPUNIT_TEST ( Range_uniform_smallint_Test );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void PrototypeCopyTest();
+  void Range_uniform_smallint_Test();
+
+private:
+};
+
+#endif /* RANDOMNUMBERGENERATORUNITTEST_HPP_ */
Index: src/builder_init.cpp
===================================================================
--- src/builder_init.cpp	(revision 3f9eba726fa6ba97ad9f47ad397aa83f8f1fc923)
+++ src/builder_init.cpp	(revision c9bc2b7e55bf61ed1abfd0a5314ce53adea45fa9)
@@ -169,4 +169,6 @@
 void cleanUp()
 {
+  RandomNumberDistributionFactory::purgeInstance();
+  RandomNumberEngineFactory::purgeInstance();
   RandomNumberGeneratorFactory::purgeInstance();
   FormatParserStorage::purgeInstance();
