Index: src/Fragmentation/Automation/Pool/WorkerPool.cpp
===================================================================
--- src/Fragmentation/Automation/Pool/WorkerPool.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/Pool/WorkerPool.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
@@ -0,0 +1,209 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2011 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * WorkerPool.cpp
+ *
+ *  Created on: 22.02.2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// boost asio needs specific operator new
+#include <boost/asio.hpp>
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "WorkerPool.hpp"
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Connection.hpp"
+
+WorkerPool::priority_t WorkerPool::default_priority = 0;
+WorkerAddress WorkerPool::emptyAddress("empty", "empty");
+
+/** Constructor for class WorkerPool.
+ *
+ */
+WorkerPool::WorkerPool()
+{}
+
+/** Destructor for class WorkerPool.
+ *
+ */
+WorkerPool::~WorkerPool()
+{}
+
+/** Helper function to check whether an address is already in the pool.
+ *
+ * @param address worker address to check
+ * @return true - address is present, false - else
+ */
+bool WorkerPool::presentInPool(const WorkerAddress &address) const
+{
+  return pool.find(address) != pool.end();
+}
+
+/** Get address of next idle worker.
+ *
+ * Note that worker is automatically marked as busy, \sa WorkerPool::markWorkerBusy()
+ *
+ * @return address of idle worker
+ */
+WorkerAddress WorkerPool::getNextIdleWorker()
+{
+  // get first idle worker
+  ASSERT( presentIdleWorkers(),
+      "WorkerPool::getNextIdleWorker() - there is no idle worker.");
+  if (!presentIdleWorkers())
+    return emptyAddress;
+  Idle_Queue_t::iterator iter = idle_queue.begin();
+  const WorkerAddress returnaddress = iter->second;
+
+  // enter in busy queue
+  markWorkerBusy( iter );
+
+  // return address
+  return returnaddress;
+}
+
+/** Checks whether a worker is busy or not.
+ *
+ * @param address address of worker to check
+ */
+bool WorkerPool::isWorkerBusy(const WorkerAddress &address) const
+{
+  Busy_Queue_t::const_iterator iter = busy_queue.find(address);
+  if (iter != busy_queue.end())
+    return true;
+#ifndef NDEBUG
+  else {
+    Idle_Queue_t::const_iterator iter = idle_queue.begin();
+    for(;iter != idle_queue.end(); ++iter)
+      if (iter->second == address)
+        break;
+    ASSERT( iter != idle_queue.end(),
+        "WorkerPool::isWorkerBusy() - worker "+toString(address)
+        +" is neither busy nor idle.");
+
+  }
+#endif
+  return false;
+}
+
+/** Adds another worker to the pool by noting down its address.
+ *
+ * @param address host and service address of the listening worker
+ * @return true - added successfully, false - not added
+ */
+bool WorkerPool::addWorker(const WorkerAddress& address)
+{
+  std::pair<Pool_t::iterator, bool> inserter =
+      pool.insert( address );
+  if (inserter.second) { // if new also add to queue
+    LOG(1, "INFO: Successfully added "+toString(address)+" to pool.");
+    idle_queue.insert( make_pair( default_priority, address ) );
+    return true;
+  } else {
+    LOG(1, "INFO: "+toString(address)+" is already present pool.");
+    return false;
+  }
+}
+
+/** Removes a worker from the pool.
+ *
+ * @param address host and service address of the listening worker
+ * @return true - removed successfully, false - not removed
+ */
+bool WorkerPool::removeWorker(const WorkerAddress& address)
+{
+  Pool_t::iterator iter = pool.find( address );
+  if (iter != pool.end()) {
+    Idle_Queue_t::iterator idleiter = idle_queue.begin();
+    while (idleiter != idle_queue.end()) {
+      if (idleiter->second == address) {
+        idle_queue.erase(idleiter);
+        break;
+      }
+    }
+    Busy_Queue_t::iterator busyiter = busy_queue.find(address);
+    if (busyiter != busy_queue.end())
+      busy_queue.erase(busyiter);
+    ASSERT( idleiter != idle_queue.end() || busyiter != busy_queue.end(),
+        "WorkerPool::removeWorker() - Worker "+toString(address)
+        +" is in pool but neither idle nor busy!");
+    ASSERT( !(idleiter != idle_queue.end() && busyiter != busy_queue.end()),
+        "WorkerPool::removeWorker() - Worker "+toString(address)
+        +" is in pool and both idle and busy!");
+    pool.erase(iter);
+    return true;
+  } else {
+    ELOG(1, "Worker "+toString(address)+" is not present pool.");
+    return false;
+  }
+}
+
+/** Sends shutdown to all current workers in the pool.
+ *
+ */
+void WorkerPool::removeAllWorkers()
+{
+  // empty pool and queue
+  idle_queue.clear();
+  busy_queue.clear();
+  pool.clear();
+}
+
+/** Helper function to mark a worker as busy.
+ *
+ * Removes from idle_queue and places into busy_queue.
+ * Sets \a iter to Idle_Queue_t::end().
+ *
+ * @param iter iterator on idle worker
+ */
+void WorkerPool::markWorkerBusy(Idle_Queue_t::iterator &iter)
+{
+  if (isWorkerBusy(iter->second))
+    return;
+  const WorkerAddress returnaddress = iter->second;
+  const priority_t priority = iter->first;
+
+  // remove from idle queue
+  idle_queue.erase(iter);
+
+  // insert into busy queue
+#ifndef NDEBUG
+  std::pair< Busy_Queue_t::iterator, bool > inserter =
+#endif
+  busy_queue.insert( make_pair(returnaddress, priority) );
+  ASSERT( inserter.second,
+      "WorkerPool::sendJobToWorker() - Worker "+toString(inserter.first->first)+" is already busy.");
+
+  LOG(1, "INFO: Worker " << returnaddress << " is now marked busy.");
+}
+
+/** Helper function to unmark a worker as busy.
+ *
+ * Removes worker from busy_queue and returns it to idle_queue.
+ *
+ * @param address address of worker
+ */
+void WorkerPool::unmarkWorkerBusy(const WorkerAddress &address)
+{
+  if (isWorkerBusy(address)) {
+    Busy_Queue_t::const_iterator iter = busy_queue.find(address);
+    const priority_t priority = iter->second;
+    busy_queue.erase(address);
+    idle_queue.insert( make_pair( priority, address) );
+  }
+}
Index: src/Fragmentation/Automation/Pool/WorkerPool.hpp
===================================================================
--- src/Fragmentation/Automation/Pool/WorkerPool.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/Pool/WorkerPool.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
@@ -0,0 +1,82 @@
+/*
+ * WorkerPool.hpp
+ *
+ *  Created on: 22.02.2012
+ *      Author: heber
+ */
+
+#ifndef WORKERPOOL_HPP_
+#define WORKERPOOL_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "WorkerAddress.hpp"
+
+class FragmentQueue;
+class WorkerPoolTest;
+
+/** Class WorkerPool contains a number of PoolWorkers that connect to it
+ * and wait for jobs to be sent to them. The class manages this pool of
+ * workers.
+ *
+ */
+class WorkerPool
+{
+  //!> grant unit test access
+  friend class WorkerPoolTest;
+public:
+  WorkerPool();
+  ~WorkerPool();
+
+  bool addWorker(const WorkerAddress &address);
+  bool presentInPool(const WorkerAddress &address) const;
+  bool presentIdleWorkers() const {
+    return !idle_queue.empty();
+  }
+  WorkerAddress getNextIdleWorker();
+  bool isWorkerBusy(const WorkerAddress &address) const;
+  bool removeWorker(const WorkerAddress& address);
+  void unmarkWorkerBusy(const WorkerAddress &address);
+
+private:
+  //!> typedef of the priority in the idle queue of a worker
+  typedef size_t priority_t;
+
+  //!> typedef for the worker queue being a map with priority and address of worker
+  typedef std::multimap<priority_t, WorkerAddress> Idle_Queue_t;
+
+  //!> typedef for the worker queue being a map with priority and address of worker
+  typedef std::map<WorkerAddress, priority_t> Busy_Queue_t;
+
+  //!> typedef for the pool of workers being a set to keep only unique addresses
+  typedef std::set<WorkerAddress> Pool_t;
+
+private:
+  void markWorkerBusy(Idle_Queue_t::iterator &iter);
+  void removeAllWorkers();
+
+private:
+  //!> static for defining default priority for new workers
+  static priority_t default_priority;
+
+  //!> empty address in case queue is idle
+  static WorkerAddress emptyAddress;
+
+  //!> pool of all worker addresses to connect to and work on jobs
+  Pool_t pool;
+
+  //!> pool of worker addresses to connect to and work on jobs
+  Idle_Queue_t idle_queue;
+
+  //!> pool of worker addresses to connect to and work on jobs
+  mutable Busy_Queue_t busy_queue;
+};
+
+#endif /* WORKERPOOL_HPP_ */
Index: src/Fragmentation/Automation/unittests/Makefile.am
===================================================================
--- src/Fragmentation/Automation/unittests/Makefile.am	(revision edbf88b839d69b6e01bba6c317710295d1c45d26)
+++ src/Fragmentation/Automation/unittests/Makefile.am	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
@@ -9,6 +9,7 @@
   unittests/MPQCDataUnitTest.cpp \
   unittests/SystemCommandJobUnitTest.cpp \
-  unittests/WorkerAddressUnitTest.cpp
-
+  unittests/WorkerAddressUnitTest.cpp \
+  unittests/WorkerPoolUnitTest.cpp
+  
 FRAGMENTATIONAUTOMATIONTESTSHEADERS = \
   unittests/FragmentJobUnitTest.hpp \
@@ -18,5 +19,6 @@
   unittests/MPQCDataUnitTest.hpp \
   unittests/SystemCommandJobUnitTest.hpp \
-  unittests/WorkerAddressUnitTest.hpp
+  unittests/WorkerAddressUnitTest.hpp \
+  unittests/WorkerPoolUnitTest.hpp
 
 FRAGMENTATIONAUTOMATIONTESTS = \
@@ -27,5 +29,6 @@
   MPQCDataUnitTest \
   SystemCommandJobUnitTest \
-  WorkerAddressUnitTest
+  WorkerAddressUnitTest \
+  WorkerPoolUnitTest
 
 
@@ -137,3 +140,17 @@
   ${CodePatterns_LIBS}
 
+WorkerPoolUnitTest_LDFLAGS = ${CodePatterns_LIBS} $(CPPUNIT_LIBS) -ldl
+WorkerPoolUnitTest_CPPFLAGS = ${BOOST_CPPFLAGS} $(CPPUNIT_CFLAGS) ${CodePatterns_CFLAGS}
+WorkerPoolUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+  unittests/WorkerPoolUnitTest.cpp \
+  unittests/WorkerPoolUnitTest.hpp \
+  Pool/WorkerPool.cpp \
+  Pool/WorkerPool.hpp \
+  WorkerAddress.cpp \
+  WorkerAddress.hpp
+WorkerPoolUnitTest_LDADD = \
+  $(BOOST_SERIALIZATION_LDFLAGS) $(BOOST_SERIALIZATION_LIBS) \
+  $(BOOST_SYSTEM_LDFLAGS) $(BOOST_SYSTEM_LIBS) \
+  ${CodePatterns_LIBS}
+
 #AUTOMAKE_OPTIONS = parallel-tests
Index: src/Fragmentation/Automation/unittests/WorkerPoolUnitTest.cpp
===================================================================
--- src/Fragmentation/Automation/unittests/WorkerPoolUnitTest.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/unittests/WorkerPoolUnitTest.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+/*
+ * WorkerPoolUnitTest.cpp
+ *
+ *  Created on: Feb 28, 2012
+ *      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 "WorkerPoolUnitTest.hpp"
+
+#include <vector>
+
+#include "CodePatterns/Assert.hpp"
+#include "Pool/WorkerPool.hpp"
+#include "WorkerAddress.hpp"
+
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+#include "stubs/FragmentJobStub.hpp"
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( WorkerPoolTest );
+
+
+void WorkerPoolTest::setUp()
+{
+  // Throw assertions
+  ASSERT_DO(Assert::Throw);
+
+  pool = new WorkerPool();
+}
+
+void WorkerPoolTest::tearDown()
+{
+  delete pool;
+}
+
+/** UnitTest for working add/removeWorker
+ */
+void WorkerPoolTest::WorkerTest()
+{
+  WorkerAddress address("service", "port");
+  WorkerAddress otheraddress("otherservice", "otherport");
+
+  // add worker
+  CPPUNIT_ASSERT( pool->addWorker(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->busy_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->pool.size() );
+
+  // remove non-present worker
+  std::cout << "The following error message is intended and does not indicate a failure." << std::endl;
+  CPPUNIT_ASSERT( !pool->removeWorker(otheraddress) );
+
+  // check for presence
+  CPPUNIT_ASSERT( pool->presentInPool(address) );
+  CPPUNIT_ASSERT( !pool->presentInPool(otheraddress) );
+
+  // remove worker
+  CPPUNIT_ASSERT( pool->removeWorker(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->busy_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->pool.size() );
+}
+
+/** UnitTest for working (un)markWorkerBusy
+ */
+void WorkerPoolTest::markBusyTest()
+{
+  WorkerAddress address("service", "port");
+  CPPUNIT_ASSERT( pool->addWorker(address) );
+
+  // check that not busy
+  CPPUNIT_ASSERT( !pool->isWorkerBusy(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->busy_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->pool.size() );
+
+  // unmark and check
+  pool->unmarkWorkerBusy(address);
+  CPPUNIT_ASSERT( !pool->isWorkerBusy(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->busy_queue.size() );
+
+  // mark as busy and check
+  const WorkerAddress otheraddress = pool->getNextIdleWorker();
+  CPPUNIT_ASSERT( pool->isWorkerBusy(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->busy_queue.size() );
+
+  // get one more
+  CPPUNIT_ASSERT( !pool->presentIdleWorkers() );
+#ifndef NDEBUG
+  std::cout << "The following assertion is intended and does not indicate a failure." << std::endl;
+  CPPUNIT_ASSERT_THROW( pool->getNextIdleWorker(), Assert::AssertionFailure );
+#else
+  const WorkerAddress emptyAddress = pool->getNextIdleWorker();
+#endif
+  CPPUNIT_ASSERT( pool->isWorkerBusy(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->busy_queue.size() );
+
+  // unmark and check
+  pool->unmarkWorkerBusy(address);
+  CPPUNIT_ASSERT( !pool->isWorkerBusy(address) );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, pool->idle_queue.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)0, pool->busy_queue.size() );
+}
Index: src/Fragmentation/Automation/unittests/WorkerPoolUnitTest.hpp
===================================================================
--- src/Fragmentation/Automation/unittests/WorkerPoolUnitTest.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/unittests/WorkerPoolUnitTest.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
@@ -0,0 +1,40 @@
+/*
+ * WorkerPoolUnitTest.hpp
+ *
+ *  Created on: Feb 28, 2012
+ *      Author: heber
+ */
+
+#ifndef WORKERPOOLUNITTEST_HPP_
+#define WORKERPOOLUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class WorkerPool;
+
+/********************************************** Test classes **************************************/
+
+class WorkerPoolTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( WorkerPoolTest) ;
+    CPPUNIT_TEST ( WorkerTest );
+    CPPUNIT_TEST ( markBusyTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void WorkerTest();
+      void markBusyTest();
+
+private:
+      WorkerPool *pool;
+};
+
+#endif /* WORKERPOOLUNITTEST_HPP_ */
