Index: src/Fragmentation/Automation/Controller/Commands/EnrollInPoolOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/EnrollInPoolOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/EnrollInPoolOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,94 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * EnrollInPoolOperation.cpp
+ *
+ *  Created on: Feb 26, 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 "EnrollInPoolOperation.hpp"
+
+#include <boost/bind.hpp>
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "WorkerAddress.hpp"
+
+/// Handle completion of a connect operation.
+void EnrollInPoolOperation::handle_connect(const boost::system::error_code& e,
+    boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // Successfully established connection. Start operation to read the list
+    // of jobs. The connection::async_read() function will automatically
+    // decode the data that is read from the underlying socket.
+    LOG(1, "INFO: Enrolling in pool with " << address << "...");
+    connection_.async_write(address,
+      boost::bind(&Operation::handle_FinishOperation, this,
+      boost::asio::placeholders::error));
+  } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
+    // Try the next endpoint.
+    connection_.socket().close();
+    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+    connection_.socket().async_connect(endpoint,
+      boost::bind(&EnrollInPoolOperation::handle_connect, this,
+      boost::asio::placeholders::error, ++endpoint_iterator));
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    ELOG(1, e.message());
+  }
+}
+
+
+/// Handle sent of address
+void EnrollInPoolOperation::handle_sendAddress(const boost::system::error_code& e)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // Successfully established connection. Start operation to read the list
+    // of jobs. The connection::async_read() function will automatically
+    // decode the data that is read from the underlying socket.
+    connection_.async_read(flag,
+      boost::bind(&EnrollInPoolOperation::handle_FinishOperation, this,
+      boost::asio::placeholders::error));
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    ELOG(1, e.message());
+  }
+}
+
+/// Handle sent of address
+void EnrollInPoolOperation::handle_FinishOperation(const boost::system::error_code& e)
+{
+  Info info(__FUNCTION__);
+
+  if (flag == Success)
+    LOG(2, "DEBUG: Enrollment successful.");
+  else
+    LOG(2, "DEBUG: Enrollment failed.");
+
+  Operation::handle_FinishOperation(e);
+}
Index: src/Fragmentation/Automation/Controller/Commands/EnrollInPoolOperation.hpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/EnrollInPoolOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/EnrollInPoolOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,64 @@
+/*
+ * EnrollInPoolOperation.hpp
+ *
+ *  Created on: Feb 26, 2012
+ *      Author: heber
+ */
+
+#ifndef ENROLLINPOOLOPERATION_HPP_
+#define ENROLLINPOOLOPERATION_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <boost/asio.hpp>
+#include <string>
+#include <vector>
+
+#include "Connection.hpp"
+
+#include "Controller/Commands/Operation.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "Results/FragmentResult.hpp"
+#include "WorkerAddress.hpp"
+
+class EnrollInPoolOperation : public Operation  {
+public:
+  /// Constructor for class EnrollInPoolOperation.
+  EnrollInPoolOperation(Connection &_connection, const WorkerAddress &_address) :
+    Operation(std::string("enrollinpool"),_connection),
+    address(_address),
+    flag(Success)
+  {}
+  /// Destructor for class EnrollInPoolOperation
+  ~EnrollInPoolOperation() {}
+
+  enum EnrollFlag {
+    Success,
+    Fail
+  };
+
+protected:
+  // virtual function pointer to the connection handler
+  void handle_connect(const boost::system::error_code& e,
+      boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+
+  /// Handle sent of address
+  void handle_sendAddress(const boost::system::error_code& e);
+
+  /// Handle sent of address
+  void handle_FinishOperation(const boost::system::error_code& e);
+
+private:
+  //!> address to enroll with
+  WorkerAddress address;
+
+  //!> flag returned by worker pool after enroll request
+  enum EnrollFlag flag;
+};
+
+
+#endif /* ENROLLINPOOLOPERATION_HPP_ */
Index: src/Fragmentation/Automation/Controller/Commands/ObtainJobOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/ObtainJobOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/ObtainJobOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,69 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * ObtainJobOperation.cpp
+ *
+ *  Created on: Feb 26, 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 "ObtainJobOperation.hpp"
+
+#include <boost/bind.hpp>
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Jobs/FragmentJob.hpp"
+
+/// Handle completion of a connect operation.
+void ObtainJobOperation::handle_connect(const boost::system::error_code& e,
+    boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // Successfully established connection. Start operation to read the list
+    // of jobs. The connection::async_read() function will automatically
+    // decode the data that is read from the underlying socket.
+    LOG(1, "INFO: Receiving a job ...");
+    connection_.async_read(job,
+      boost::bind(&ObtainJobOperation::handle_ReceiveJob, this,
+      boost::asio::placeholders::error));
+  } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
+    // Try the next endpoint.
+    connection_.socket().close();
+    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+    connection_.socket().async_connect(endpoint,
+      boost::bind(&ObtainJobOperation::handle_connect, this,
+      boost::asio::placeholders::error, ++endpoint_iterator));
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    ELOG(1, e.message());
+  }
+}
+
+/// Callback function when job has been received.
+void ObtainJobOperation::handle_ReceiveJob(const boost::system::error_code& e)
+{
+  Info info(__FUNCTION__);
+
+  LOG(1, "INFO: Received job #" << job->getId() << ".");
+
+  Operation::handle_FinishOperation(e);
+}
Index: src/Fragmentation/Automation/Controller/Commands/ObtainJobOperation.hpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/ObtainJobOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/ObtainJobOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,58 @@
+/*
+ * ObtainJobOperation.hpp
+ *
+ *  Created on: Feb 26, 2012
+ *      Author: heber
+ */
+
+#ifndef OBTAINJOBOPERATION_HPP_
+#define OBTAINJOBOPERATION_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <boost/asio.hpp>
+#include <string>
+#include <vector>
+
+#include "Connection.hpp"
+
+#include "Controller/Commands/Operation.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "Results/FragmentResult.hpp"
+
+class ObtainJobOperation : public Operation  {
+public:
+  /// Constructor for class ObtainJobOperation.
+  ObtainJobOperation(Connection &_connection) :
+    Operation(std::string("obtainjob"),_connection) {}
+  /// Destructor for class ObtainJobOperation
+  ~ObtainJobOperation() {}
+
+  /** Getter for the obtained job.
+   *
+   * @return obtained FragmentJob
+   */
+  FragmentJob::ptr getJob()
+  {
+    return job;
+  }
+
+protected:
+  // virtual function pointer to the connection handler
+  void handle_connect(const boost::system::error_code& e,
+      boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+
+  /// Callback function when job has been received.
+  void handle_ReceiveJob(const boost::system::error_code& e);
+
+private:
+  /// The data received from the server.
+  FragmentJob::ptr job;
+};
+
+
+#endif /* OBTAINJOBOPERATION_HPP_ */
Index: src/Fragmentation/Automation/Controller/Commands/SendJobToWorkerOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/SendJobToWorkerOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/SendJobToWorkerOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,65 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * SendJobToWorkerOperation.cpp
+ *
+ *  Created on: Feb 22, 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 <boost/bind.hpp>
+#include <iostream>
+#include "Connection.hpp" // Must come before boost/serialization headers.
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "types.hpp"
+
+#include "Controller/Commands/SendJobToWorkerOperation.hpp"
+
+/** Handle connect operation to shutdown scheduler.
+ *
+ * \param e error code if something went wrong
+ * \param endpoint_iterator endpoint of the connection
+ */
+void SendJobToWorkerOperation::handle_connect(const boost::system::error_code& e,
+    boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // The connection::async_write() function will automatically
+    // serialize the data structure for us.
+    LOG(1, "INFO: Sending job #" << job->getId() << ".");
+    connection_.async_write(job,
+      boost::bind(&Operation::handle_FinishOperation, this,
+      boost::asio::placeholders::error));
+  } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
+    // Try the next endpoint.
+    connection_.socket().close();
+    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+    connection_.socket().async_connect(endpoint,
+      boost::bind(&SendJobToWorkerOperation::handle_connect, this,
+      boost::asio::placeholders::error, ++endpoint_iterator));
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    Exitflag = ErrorFlag;
+    ELOG(1, e.message());
+  }
+}
Index: src/Fragmentation/Automation/Controller/Commands/SendJobToWorkerOperation.hpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/SendJobToWorkerOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/SendJobToWorkerOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,57 @@
+/*
+ * SendJobToWorkerOperation.hpp
+ *
+ *  Created on: Feb 22, 2012
+ *      Author: heber
+ */
+
+#ifndef FRAGMENTCONTROLLER_SENDJOBTOWORKEROPERATION_HPP_
+#define FRAGMENTCONTROLLER_SENDJOBTOWORKEROPERATION_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/asio.hpp>
+#include <string>
+#include <vector>
+
+#include "Connection.hpp"
+
+#include "Controller/Commands/Operation.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "Jobs/SystemCommandJob.hpp"
+#include "WorkerAddress.hpp"
+
+class SendJobToWorkerOperation : public Operation  {
+public:
+  /// Constructor for class SendJobToWorkerOperation.
+  SendJobToWorkerOperation(Connection &_connection) :
+    Operation(std::string("sendjobtoworker"),_connection),
+    job( new SystemCommandJob(std::string("/bin/true"), std::string("donothing"), JobId::NoJob) )
+  {}
+  /// Destructor for class SendJobToWorkerOperation
+  ~SendJobToWorkerOperation() {}
+
+  /** Setter for job.
+   *
+   * @param _job job to take over internally
+   */
+  void setJob(FragmentJob::ptr &_job)
+  {
+    job.reset();
+    job = _job;
+  }
+
+public:
+  // virtual function pointer to the connection handler
+  virtual void handle_connect(const boost::system::error_code& e,
+      boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+
+private:
+  //!> job to send to
+  FragmentJob::ptr job;
+};
+
+#endif /* FRAGMENTCONTROLLER_SENDJOBTOWORKEROPERATION_HPP_ */
Index: src/Fragmentation/Automation/Controller/Commands/ShutdownOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/ShutdownOperation.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/Controller/Commands/ShutdownOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -2,5 +2,5 @@
  * Project: MoleCuilder
  * Description: creates and alters molecular systems
- * Copyright (C)  2011-2012 University of Bonn. All rights reserved.
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
  * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
  */
@@ -9,5 +9,5 @@
  * ShutdownOperation.cpp
  *
- *  Created on: Dec 11, 2011
+ *  Created on: Feb 28, 2012
  *      Author: heber
  */
Index: src/Fragmentation/Automation/Controller/Commands/SubmitResultOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/SubmitResultOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/SubmitResultOperation.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,99 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * SubmitResultOperation.cpp
+ *
+ *  Created on: Feb 26, 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 "SubmitResultOperation.hpp"
+
+#include <boost/bind.hpp>
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Results/FragmentResult.hpp"
+
+
+/// Handle completion of a connect operation.
+void SubmitResultOperation::handle_connect(const boost::system::error_code& e,
+    boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // Successfully established connection. Start operation to read the list
+    // of jobs. The connection::async_write() function will automatically
+    // decode the data that is read from the underlying socket.
+    LOG(1, "INFO: Sending address " << address << " ...");
+    connection_.async_write(address,
+      boost::bind(&SubmitResultOperation::handle_SendAddress, this,
+      boost::asio::placeholders::error));
+  } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
+    // Try the next endpoint.
+    connection_.socket().close();
+    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+    connection_.socket().async_connect(endpoint,
+      boost::bind(&SubmitResultOperation::handle_connect, this,
+      boost::asio::placeholders::error, ++endpoint_iterator));
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    exitflag = ErrorFlag;
+    ELOG(1, e.message());
+  }
+}
+
+/// Callback function when address has been sent and result is about to
+void SubmitResultOperation::handle_SendAddress(const boost::system::error_code& e)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    // Successfully established connection. Start operation to read the list
+    // of jobs. The connection::async_write() function will automatically
+    // decode the data that is read from the underlying socket.
+    LOG(1, "INFO: Sending result #" << result->getId() << " ...");
+    connection_.async_write(result,
+      boost::bind(&SubmitResultOperation::handle_SendResult, this,
+      boost::asio::placeholders::error));
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    exitflag = ErrorFlag;
+    ELOG(1, e.message());
+  }
+}
+
+/// Callback function when result has been sent.
+void SubmitResultOperation::handle_SendResult(const boost::system::error_code& e)
+{
+  Info info(__FUNCTION__);
+  if (!e) {
+    LOG(1, "INFO: result #" << result->getId() << " sent.");
+    Operation::handle_FinishOperation(e);
+  } else {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // operation the io_service will run out of work to do and the client will
+    // exit.
+    exitflag = ErrorFlag;
+    ELOG(1, e.message());
+  }
+}
Index: src/Fragmentation/Automation/Controller/Commands/SubmitResultOperation.hpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/SubmitResultOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Controller/Commands/SubmitResultOperation.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,87 @@
+/*
+ * SubmitResultOperation.hpp
+ *
+ *  Created on: Feb 26, 2012
+ *      Author: heber
+ */
+
+#ifndef SUBMITRESULTOPERATION_HPP_
+#define SUBMITRESULTOPERATION_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <boost/asio.hpp>
+#include <string>
+#include <vector>
+
+#include "Connection.hpp"
+
+#include "Controller/Commands/Operation.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "Results/FragmentResult.hpp"
+#include "WorkerAddress.hpp"
+
+class SubmitResultOperation : public Operation  {
+public:
+  /// Constructor for class SubmitResultOperation.
+  SubmitResultOperation(Connection &_connection, const WorkerAddress &_address) :
+    Operation(std::string("submitresult"),_connection),
+    result( new FragmentResult(JobId::NoJob, std::string("EmptyResult")) ),
+    address(_address),
+    exitflag(OkFlag)
+  {}
+  /// Destructor for class SubmitResultOperation
+  ~SubmitResultOperation() {}
+
+  /** Sets the result to submit.
+   *
+   * @param _result result to submit
+   */
+  void setResult(FragmentResult::ptr &_result)
+  {
+    result.reset();
+    result = _result;
+  }
+
+public:
+  enum {
+    OkFlag = 0,
+    ErrorFlag = 1
+  };
+
+  /** Returns the flag of the handled operation.
+   *
+   */
+  size_t getFlag() const
+  {
+    return exitflag;
+  }
+
+protected:
+  // virtual function pointer to the connection handler
+  void handle_connect(const boost::system::error_code& e,
+      boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+
+  /// Callback function when address has been sent and result is about to.
+  void handle_SendAddress(const boost::system::error_code& e);
+
+  /// Callback function when result has been sent.
+  void handle_SendResult(const boost::system::error_code& e);
+
+private:
+  // static entity of an empty result
+  FragmentResult::ptr result;
+
+  //!> address for listener
+  WorkerAddress address;
+
+  /// exit flag
+  size_t exitflag;
+};
+
+
+#endif /* SUBMITRESULTOPERATION_HPP_ */
Index: c/Fragmentation/Automation/Controller/Commands/WorkOnJobOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/WorkOnJobOperation.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*
- * Project: MoleCuilder
- * Description: creates and alters molecular systems
- * Copyright (C) 2012 University of Bonn. All rights reserved.
- * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
- */
-
-/*
- * WorkOnJobOperation.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 "WorkOnJobOperation.hpp"
-
-#include <boost/bind.hpp>
-#include "CodePatterns/Info.hpp"
-#include "CodePatterns/Log.hpp"
-#include "Jobs/FragmentJob.hpp"
-#include "Jobs/MPQCCommandJob.hpp"
-#include "Jobs/SystemCommandJob.hpp"
-#include "Results/FragmentResult.hpp"
-
-FragmentResult::ptr WorkOnJobOperation::EmptyResult( new FragmentResult(JobId::NoJob, std::string("EmptyResult")) );
-
-/// Handle completion of a connect operation.
-void WorkOnJobOperation::handle_connect(const boost::system::error_code& e,
-    boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
-{
-  Info info(__FUNCTION__);
-  if (!e)
-  {
-    // Successfully established connection. Start operation to read the list
-    // of jobs. The connection::async_read() function will automatically
-    // decode the data that is read from the underlying socket.
-    LOG(1, "INFO: Receiving a job ...");
-    connection_.async_read(job,
-      boost::bind(&WorkOnJobOperation::handle_ReceiveJob, this,
-      boost::asio::placeholders::error));
-  } else if (endpoint_iterator != boost::asio::ip::tcp::resolver::iterator()) {
-    // Try the next endpoint.
-    connection_.socket().close();
-    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
-    connection_.socket().async_connect(endpoint,
-      boost::bind(&WorkOnJobOperation::handle_connect, this,
-      boost::asio::placeholders::error, ++endpoint_iterator));
-  } else {
-    // An error occurred. Log it and return. Since we are not starting a new
-    // operation the io_service will run out of work to do and the client will
-    // exit.
-    exitflag = ErrorFlag;
-    ELOG(1, e.message());
-  }
-}
-
-/// Callback function when job has been received.
-void WorkOnJobOperation::handle_ReceiveJob(const boost::system::error_code& e)
-{
-  Info info(__FUNCTION__);
-  if (!e)
-  {
-    LOG(1, "INFO: Received job #" << job->getId() << ".");
-    if (job->getId() != JobId::NoJob) {
-      // Print out the data that was received.
-      std::cout << "Job id: " << job->getId() << "\n";
-
-      // do something .. right now: wait
-      LOG(1, "INFO: Calculating job #" << job->getId() << " ...");
-      FragmentResult::ptr result(job->Work());
-
-      // write the result to the server
-      LOG(1, "INFO: Sending result for job #" << job->getId() << " ...");
-      connection_.async_write(result,
-        boost::bind(&WorkOnJobOperation::handle_SendResult, this,
-        boost::asio::placeholders::error));
-
-    } else {
-      std::cout << "The server has no job for me." << std::endl;
-      // send out empty result
-      LOG(1, "INFO: Sending empty result ...");
-      connection_.async_write(EmptyResult,
-        boost::bind(&WorkOnJobOperation::handle_SendResult, this,
-        boost::asio::placeholders::error));
-      exitflag = ErrorFlag;
-    }
-  }
-  else
-  {
-    // An error occurred.
-    exitflag = ErrorFlag;
-    ELOG(1, e.message());
-  }
-
-  // Since we are not starting a new operation the io_service will run out of
-  // work to do and the client will exit.
-}
-
-/// Callback function when result has been sent.
-void WorkOnJobOperation::handle_SendResult(const boost::system::error_code& e)
-{
-  Info info(__FUNCTION__);
-  // Nothing to do.
-  LOG(1, "INFO: Job #" << job->getId() << " calculated and sent.");
-  // erase job
-  job.reset();
-}
Index: c/Fragmentation/Automation/Controller/Commands/WorkOnJobOperation.hpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/WorkOnJobOperation.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ 	(revision )
@@ -1,72 +1,0 @@
-/*
- * WorkOnJobOperation.hpp
- *
- *  Created on: 22.02.2012
- *      Author: heber
- */
-
-#ifndef WORKONJOBOPERATION_HPP_
-#define WORKONJOBOPERATION_HPP_
-
-// include config.h
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-
-#include <boost/asio.hpp>
-#include <string>
-#include <vector>
-
-#include "Connection.hpp"
-
-#include "Controller/Commands/Operation.hpp"
-#include "Jobs/FragmentJob.hpp"
-#include "Results/FragmentResult.hpp"
-
-class WorkOnJobOperation : public Operation  {
-public:
-  /// Constructor for class WorkOnJobOperation.
-  WorkOnJobOperation(Connection &_connection) :
-    Operation(std::string("workonjob"),_connection) {}
-  /// Destructor for class WorkOnJobOperation
-  ~WorkOnJobOperation() {}
-
-public:
-  enum {
-    OkFlag = 0,
-    ErrorFlag = 1
-  };
-
-  /** Returns the flag of the handled operation.
-   *
-   */
-  size_t getFlag() const
-  {
-    return exitflag;
-  }
-
-protected:
-  // virtual function pointer to the connection handler
-  void handle_connect(const boost::system::error_code& e,
-      boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
-
-  /// Callback function when job has been received.
-  void handle_ReceiveJob(const boost::system::error_code& e);
-
-  /// Callback function when result has been sent.
-  void handle_SendResult(const boost::system::error_code& e);
-
-private:
-  // static entity of an empty result
-  static FragmentResult::ptr EmptyResult;
-
-  /// The data received from the server.
-  FragmentJob::ptr job;
-
-  /// exit flag
-  size_t exitflag;
-};
-
-
-#endif /* WORKONJOBOPERATION_HPP_ */
Index: src/Fragmentation/Automation/FragmentScheduler.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentScheduler.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/FragmentScheduler.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -34,4 +34,5 @@
 #include "CodePatterns/Info.hpp"
 #include "CodePatterns/Log.hpp"
+#include "Controller/Commands/EnrollInPoolOperation.hpp"
 #include "Jobs/MPQCCommandJob.hpp"
 #include "Jobs/SystemCommandJob.hpp"
@@ -59,9 +60,15 @@
  */
 FragmentScheduler::FragmentScheduler(boost::asio::io_service& io_service, unsigned short workerport, unsigned short controllerport) :
-    WorkerListener(io_service, workerport, JobsQueue),
+    WorkerListener(io_service, workerport, JobsQueue, pool,
+        boost::bind(&FragmentScheduler::sendJobToWorker, boost::ref(*this), _1, _2)),
     ControllerListener(io_service, controllerport, JobsQueue,
-        boost::bind(&Listener::initiateSocket, boost::ref(WorkerListener)))
-{
-  Info info(__FUNCTION__);
+        boost::bind(&Listener::initiateSocket, boost::ref(WorkerListener))),
+    connection(io_service),
+    sendJobOp(connection)
+{
+  Info info(__FUNCTION__);
+
+  // listen for controller
+  ControllerListener.initiateSocket();
 
   // only initiate socket if jobs are already present
@@ -69,13 +76,9 @@
     WorkerListener.initiateSocket();
   }
-
-  ControllerListener.initiateSocket();
 }
 
 /** Handle a new worker connection.
  *
- * We check whether jobs are in the JobsQueue. If present, job is sent.
- *
- * \sa handle_SendJobtoWorker()
+ * We store the given address in the pool.
  *
  * \param e error code if something went wrong
@@ -88,28 +91,9 @@
   {
     // Successfully accepted a new connection.
-    // Check whether there are jobs in the queue
-    if (JobsQueue.isJobPresent()) {
-      // pop a job and send it to the client.
-      FragmentJob::ptr job(JobsQueue.popJob());
-      // The connection::async_write() function will automatically
-      // serialize the data structure for us.
-      LOG(1, "INFO: Sending job #" << job->getId() << ".");
-      conn->async_write(job,
-        boost::bind(&FragmentScheduler::WorkerListener_t::handle_SendJobtoWorker, this,
-        boost::asio::placeholders::error, conn));
-
-    } else {
-      // send the static NoJob
-      conn->async_write(NoJob,
-        boost::bind(&FragmentScheduler::WorkerListener_t::handle_SendJobtoWorker, this,
-        boost::asio::placeholders::error, conn));
-
-      // then there must be no read necesary
-
-      ELOG(2, "There is currently no job present in the queue.");
-    }
-  }
-  else
-  {
+    // read address
+    conn->async_read(address,
+      boost::bind(&FragmentScheduler::WorkerListener_t::handle_checkAddress, this,
+      boost::asio::placeholders::error, conn));
+  }  else {
     // An error occurred. Log it and return. Since we are not starting a new
     // accept operation the io_service will run out of work to do and the
@@ -118,4 +102,42 @@
     ELOG(0, e.message());
   }
+}
+
+/** Callback function when worker address has been received.
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::WorkerListener_t::handle_checkAddress(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    if (pool.presentInPool(address)) {
+      // check whether its priority is busy_priority
+      if (pool.isWorkerBusy(address)) {
+        conn->async_read(result,
+          boost::bind(&FragmentScheduler::WorkerListener_t::handle_ReceiveResultFromWorker, this,
+          boost::asio::placeholders::error, conn));
+      } else {
+        ELOG(1, "INFO: Idle worker "+toString(address)+" has logged in again.");
+      }
+    } else {
+      // insert as its new worker
+      pool.addWorker(address);
+      enum EnrollInPoolOperation::EnrollFlag flag = EnrollInPoolOperation::Success;
+      conn->async_write(flag,
+        boost::bind(&FragmentScheduler::WorkerListener_t::handle_enrolled, this,
+        boost::asio::placeholders::error, conn));
+    }
+  }
+  else
+  {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // accept operation the io_service will run out of work to do and the
+    // server will exit.
+    Exitflag = ErrorFlag;
+    ELOG(0, e.message());
+  }
 
   if (JobsQueue.isJobPresent()) {
@@ -126,22 +148,30 @@
 }
 
-/** Callback function when job has been sent.
- *
- * After job has been sent we start async_read() for the result.
- *
- * \sa handle_ReceiveResultFromWorker()
- *
- * \param e error code if something went wrong
- * \param conn reference with the connection
- */
-void FragmentScheduler::WorkerListener_t::handle_SendJobtoWorker(const boost::system::error_code& e, connection_ptr conn)
-{
-    Info info(__FUNCTION__);
-    LOG(1, "INFO: Job sent.");
-    // obtain result
-    LOG(1, "INFO: Receiving result for a job ...");
-    conn->async_read(result,
-      boost::bind(&FragmentScheduler::WorkerListener_t::handle_ReceiveResultFromWorker, this,
-      boost::asio::placeholders::error, conn));
+/** Callback function when new worker has enrolled.
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::WorkerListener_t::handle_enrolled(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    FragmentJob::ptr job;
+    if (JobsQueue.isJobPresent()) {
+      job = JobsQueue.popJob();
+    } else {
+      job = NoJob;
+    }
+    callback_sendJobToWorker(address, job);
+  }
+  else
+  {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // accept operation the io_service will run out of work to do and the
+    // server will exit.
+    Exitflag = ErrorFlag;
+    ELOG(0, e.message());
+  }
 }
 
@@ -155,16 +185,24 @@
   Info info(__FUNCTION__);
   LOG(1, "INFO: Received result for job #" << result->getId() << " ...");
+
   // and push into queue
   ASSERT(result->getId() != (JobId_t)JobId::NoJob,
-      "FragmentScheduler::handle_ReceiveResultFromWorker() - result received has NoJob id.");
+      "WorkerListener_t::handle_ReceiveResultFromWorker() - result received has NoJob id.");
   ASSERT(result->getId() != (JobId_t)JobId::IllegalJob,
-      "FragmentScheduler::handle_ReceiveResultFromWorker() - result received has IllegalJob id.");
+      "WorkerListener_t::handle_ReceiveResultFromWorker() - result received has IllegalJob id.");
   // place id into expected
   if ((result->getId() != (JobId_t)JobId::NoJob) && (result->getId() != (JobId_t)JobId::IllegalJob))
     JobsQueue.pushResult(result);
+
+  // mark as idle
+  pool.unmarkWorkerBusy(address);
+  // for now remove worker again from pool such that other may connect
+  pool.removeWorker(address);
+
   // erase result
   result.reset();
   LOG(1, "INFO: JobsQueue has " << JobsQueue.getDoneJobs() << " results.");
 }
+
 
 /** Handle a new controller connection.
@@ -348,2 +386,45 @@
 }
 
+
+/** Helper function to send a job to worker.
+ *
+ * @param address address of worker
+ * @param job job to send
+ */
+void FragmentScheduler::sendJobToWorker(const WorkerAddress &address, FragmentJob::ptr &job)
+{
+  ASSERT( !pool.isWorkerBusy(address),
+      "FragmentScheduler::sendJobToWorker() - Worker "+toString(address)+" is already busy.");
+  LOG(1, "INFO: Sending job " << job->getId() << " to worker " << address << ".");
+  sendJobOp.setJob(job);
+  sendJobOp(address.host, address.service);
+  // set worker as busy (assuming it has been removed from idle queue already)
+  WorkerPool::Idle_Queue_t::iterator iter = pool.getIdleWorker(address);
+  ASSERT( iter != pool.getIdleEnd(),
+      "FragmentScheduler::sendJobToWorker() - cannot find worker "
+      +toString(address)+" in idle queue.");
+  pool.markWorkerBusy(iter);
+}
+
+///** Helper function to shutdown a single worker.
+// *
+// * We send NoJob to indicate shutdown
+// *
+// * @param address of worker to shutdown
+// */
+//void FragmentScheduler::shutdownWorker(const WorkerAddress &address)
+//{
+//  sendJobToWorker(address, NoJob);
+//}
+//
+///** Sends shutdown to all current workers in the pool.
+// *
+// */
+//void FragmentScheduler::removeAllWorkers()
+//{
+//  // give all workers shutdown signal
+//  while (pool.presentIdleWorkers()) {
+//    const WorkerAddress address = pool.getNextIdleWorker();
+//    shutdownWorker(address);
+//  }
+//}
Index: src/Fragmentation/Automation/FragmentScheduler.hpp
===================================================================
--- src/Fragmentation/Automation/FragmentScheduler.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/FragmentScheduler.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -20,4 +20,5 @@
 #include "Connection.hpp"
 #include "ControllerChoices.hpp"
+#include "Controller/Commands/SendJobToWorkerOperation.hpp"
 #include "FragmentQueue.hpp"
 #include "GlobalJobId.hpp"
@@ -26,4 +27,6 @@
 #include "Results/FragmentResult.hpp"
 #include "types.hpp"
+#include "Pool/WorkerPool.hpp"
+#include "WorkerAddress.hpp"
 
 /** FragmentScheduler serves FragmentJobs to Workers and accepts commands from
@@ -39,4 +42,8 @@
 
 private:
+  void sendJobToWorker(const WorkerAddress &address, FragmentJob::ptr &job);
+//  void shutdownWorker(const WorkerAddress &address);
+//  void removeAllWorkers();
+
   class WorkerListener_t : public Listener
   {
@@ -45,8 +52,13 @@
         boost::asio::io_service& io_service,
         unsigned short port,
-        FragmentQueue &_JobsQueue) :
+        FragmentQueue &_JobsQueue,
+        WorkerPool &_pool,
+        boost::function<void (const WorkerAddress&, FragmentJob::ptr&)> _callback) :
       Listener(io_service, port),
+      address("127.0.0.1", "0"),
       JobsQueue(_JobsQueue),
-      result( new FragmentResult(JobId::NoJob) )
+      pool(_pool),
+      result( new FragmentResult(JobId::NoJob) ),
+      callback_sendJobToWorker(_callback)
     {}
     virtual ~WorkerListener_t() {}
@@ -57,14 +69,26 @@
 
     /// Worker callback function when job has been sent.
-    void handle_SendJobtoWorker(const boost::system::error_code& e, connection_ptr conn);
+    void handle_checkAddress(const boost::system::error_code& e, connection_ptr conn);
+
+    /// Worker callback function when new worker has enrolled.
+    void handle_enrolled(const boost::system::error_code& e, connection_ptr conn);
 
     /// Worker callback function when result has been received.
     void handle_ReceiveResultFromWorker(const boost::system::error_code& e, connection_ptr conn);
   private:
-    //!> reference to external FragmentQueue containing jobs to work on
-    FragmentQueue & JobsQueue;
+    //!> address of new Worker
+    WorkerAddress address;
+
+    //!> reference to Queue
+    FragmentQueue &JobsQueue;
+
+    //!> callback reference to container class
+    WorkerPool &pool;
 
     /// result that is received from the client.
     FragmentResult::ptr result;
+
+    //!> callback function to access send job function
+    boost::function<void (const WorkerAddress&, FragmentJob::ptr&)> callback_sendJobToWorker;
 
     // static entity to indicate to clients that the queue is empty.
@@ -130,4 +154,10 @@
 
 private:
+  /// Queue with data to be sent to each client.
+  FragmentQueue JobsQueue;
+
+  //!> Pool of Workers
+  WorkerPool pool;
+
   //!> Listener instance that waits for a worker
   WorkerListener_t  WorkerListener;
@@ -135,7 +165,4 @@
   //!> Listener instance that waits for a controller
   ControllerListener_t  ControllerListener;
-
-  /// Queue with data to be sent to each client.
-  FragmentQueue JobsQueue;
 
 public:
@@ -153,4 +180,10 @@
   }
 
+private:
+  //!> Connection for sending jobs to workers
+  Connection connection;
+
+  //!> internal operation to send jobs to workers
+  mutable SendJobToWorkerOperation sendJobOp;
 };
 
Index: c/Fragmentation/Automation/FragmentWorker.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentWorker.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ 	(revision )
@@ -1,62 +1,0 @@
-/*
- * 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.
- */
-
-/*
- * \file FragmentWorker.cpp
- *
- * This file strongly follows the Serialization example from the boost::asio
- * library (see client.cpp).
- *
- *  Created on: Nov 18, 2011
- *      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 <boost/bind.hpp>
-#include <iostream>
-#include <vector>
-#include "Connection.hpp" // Must come before boost/serialization headers.
-#include <boost/serialization/vector.hpp>
-#include "CodePatterns/Info.hpp"
-#include "CodePatterns/Log.hpp"
-#include "Jobs/FragmentJob.hpp"
-#include "Jobs/MPQCCommandJob.hpp"
-#include "Jobs/SystemCommandJob.hpp"
-#include "Results/FragmentResult.hpp"
-#include "FragmentWorker.hpp"
-
-/** Helper function to enforce binding of FragmentWorker to possible derived
- * FragmentJob classes.
- */
-void dummyInit() {
-  SystemCommandJob("/bin/false", "something", JobId::IllegalJob);
-  MPQCCommandJob("nofile", JobId::IllegalJob);
-}
-
-/// Constructor starts the asynchronous connect operation.
-FragmentWorker::FragmentWorker(
-    boost::asio::io_service& io_service,
-    const std::string& host,
-    const std::string& service) :
-  connection_(io_service),
-  operation(connection_)
-{
-    Info info(__FUNCTION__);
-
-    // launch operation
-    operation(host, service);
-}
-
Index: c/Fragmentation/Automation/FragmentWorker.hpp
===================================================================
--- src/Fragmentation/Automation/FragmentWorker.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ 	(revision )
@@ -1,48 +1,0 @@
-/*
- * \file FragmentWorker.hpp
- *
- *  Created on: Nov 18, 2011
- *      Author: heber
- */
-
-#ifndef FRAGMENTWORKER_HPP_
-#define FRAGMENTWORKER_HPP_
-
-// include config.h
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <boost/asio.hpp>
-#include <vector>
-#include "Connection.hpp"
-#include "Jobs/FragmentJob.hpp"
-#include "Controller/Commands/WorkOnJobOperation.hpp"
-
-/** Receives a job from Server to execute and return FragmentResult.
- *
- */
-class FragmentWorker
-{
-public:
-  /// Constructor starts the asynchronous connect operation.
-  FragmentWorker(boost::asio::io_service& io_service,
-      const std::string& host, const std::string& service);
-
-  /** Returns the flag of the handled operation.
-   *
-   */
-  size_t getExitflag() const
-  {
-    return operation.getExitflag();
-  }
-
-private:
-  /// The Connection to the server.
-  Connection connection_;
-
-  //!> operation that handles connection, getting, and working on job.
-  WorkOnJobOperation operation;
-};
-
-#endif /* FRAGMENTWORKER_HPP_ */
Index: src/Fragmentation/Automation/Makefile.am
===================================================================
--- src/Fragmentation/Automation/Makefile.am	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/Makefile.am	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -44,20 +44,26 @@
 FRAGMENTATIONCOMMANDSSOURCE = \
   Controller/Commands/CheckResultsOperation.cpp \
+  Controller/Commands/EnrollInPoolOperation.cpp \
   Controller/Commands/GetNextJobIdOperation.cpp \
+  Controller/Commands/ObtainJobOperation.cpp \
   Controller/Commands/Operation.cpp \
   Controller/Commands/ReceiveJobsOperation.cpp \
+  Controller/Commands/SendJobToWorkerOperation.cpp \
   Controller/Commands/SendResultsOperation.cpp \
   Controller/Commands/ShutdownOperation.cpp \
-  Controller/Commands/WorkOnJobOperation.cpp
+  Controller/Commands/SubmitResultOperation.cpp
 
 FRAGMENTATIONCOMMANDSHEADER = \
   ControllerChoices.hpp \
   Controller/Commands/CheckResultsOperation.hpp \
+  Controller/Commands/EnrollInPoolOperation.hpp \
   Controller/Commands/GetNextJobIdOperation.hpp \
+  Controller/Commands/ObtainJobOperation.hpp \
   Controller/Commands/Operation.hpp \
   Controller/Commands/ReceiveJobsOperation.hpp \
+  Controller/Commands/SendJobToWorkerOperation.hpp \
   Controller/Commands/SendResultsOperation.hpp \
   Controller/Commands/ShutdownOperation.hpp \
-  Controller/Commands/WorkOnJobOperation.hpp
+  Controller/Commands/SubmitResultOperation.hpp
 
 noinst_LTLIBRARIES += libMolecuilderFragmentationCommands.la
@@ -69,9 +75,13 @@
 FRAGMENTATIONAUTOMATIONHELPERSOURCE = \
   atexit.cpp \
-  GlobalJobId.cpp
+  GlobalJobId.cpp \
+  Listener.cpp \
+  WorkerAddress.cpp
 
 FRAGMENTATIONAUTOMATIONHELPERHEADER = \
   atexit.hpp \
-  GlobalJobId.hpp
+  GlobalJobId.hpp \
+  Listener.hpp \
+  WorkerAddress.hpp
 
 noinst_LTLIBRARIES += libMolecuilderFragmentationAutomationHelper.la
@@ -86,5 +96,5 @@
 AM_CPPFLAGS = ${BOOST_CPPFLAGS} ${CodePatterns_CFLAGS}
 
-bin_PROGRAMS += Controller Server Worker
+bin_PROGRAMS += Controller PoolWorker Server
 
 CONTROLLERSOURCE = \
@@ -97,7 +107,14 @@
   Controller/FragmentController.hpp
 
+POOLWORKERSOURCE = \
+  Pool/PoolWorker.cpp
+
+POOLWORKERHEADER = \
+  Connection.hpp \
+  Pool/PoolWorker.hpp
+
 SERVERSOURCE = \
   FragmentScheduler.cpp \
-  Listener.cpp
+  Pool/WorkerPool.cpp
 
 SERVERHEADER = \
@@ -105,13 +122,5 @@
   ControllerChoices.hpp \
   FragmentScheduler.hpp \
-  Listener.hpp
-
-WORKERSOURCE = \
-  FragmentWorker.cpp \
-  Worker.cpp
-
-WORKERHEADER = \
-  Connection.hpp \
-  FragmentWorker.hpp
+  Pool/WorkerPool.hpp
 
 Controller_SOURCES = $(CONTROLLERSOURCE) $(CONTROLLERHEADER) controller.cpp
@@ -119,4 +128,17 @@
 Controller_CXXFLAGS = $(AM_CPPFLAGS)
 Controller_LDADD = \
+  libMolecuilderFragmentationAutomationHelper.la \
+  libMolecuilderFragmentationCommands.la \
+  libMolecuilderFragmentJobs.la \
+  $(BOOST_ASIO_LIBS) \
+  $(BOOST_SERIALIZATION_LIBS) \
+  $(BOOST_THREAD_LIBS) \
+  $(BOOST_SYSTEM_LIBS) \
+  ${CodePatterns_LIBS}
+
+PoolWorker_SOURCES = $(POOLWORKERSOURCE) $(POOLWORKERHEADER) poolworker.cpp
+PoolWorker_LDFLAGS = $(AM_LDFLAGS) $(BOOST_ASIO_LDFLAGS) $(BOOST_SYSTEM_LDFLAGS) $(BOOST_THREAD_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS)
+PoolWorker_CXXFLAGS = $(AM_CPPFLAGS) $(BOOST_ASIO_DEBUG)
+PoolWorker_LDADD = \
   libMolecuilderFragmentationAutomationHelper.la \
   libMolecuilderFragmentationCommands.la \
@@ -141,15 +163,2 @@
   ${CodePatterns_LIBS}
 
-Worker_SOURCES = $(WORKERSOURCE) $(WORKERHEADER)
-Worker_LDFLAGS = $(AM_LDFLAGS) $(BOOST_ASIO_LDFLAGS) $(BOOST_SYSTEM_LDFLAGS) $(BOOST_THREAD_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS)
-Worker_CXXFLAGS = $(AM_CPPFLAGS)
-Worker_LDADD = \
-  libMolecuilderFragmentationAutomationHelper.la \
-  libMolecuilderFragmentationCommands.la \
-  libMolecuilderFragmentJobs.la \
-  $(BOOST_ASIO_LIBS) \
-  $(BOOST_SERIALIZATION_LIBS) \
-  $(BOOST_THREAD_LIBS) \
-  $(BOOST_SYSTEM_LIBS) \
-  ${CodePatterns_LIBS}
-
Index: src/Fragmentation/Automation/Pool/PoolWorker.cpp
===================================================================
--- src/Fragmentation/Automation/Pool/PoolWorker.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Pool/PoolWorker.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,139 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C) 2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * \file PoolWorker.cpp
+ *
+ * This file strongly follows the Serialization example from the boost::asio
+ * library (see client.cpp).
+ *
+ *  Created on: Feb 28, 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 <boost/bind.hpp>
+#include <boost/lexical_cast.hpp>
+#include <iostream>
+#include <vector>
+#include "Connection.hpp" // Must come before boost/serialization headers.
+#include <boost/serialization/vector.hpp>
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "Jobs/MPQCCommandJob.hpp"
+#include "Jobs/SystemCommandJob.hpp"
+#include "Results/FragmentResult.hpp"
+#include "PoolWorker.hpp"
+
+/** Helper function to enforce binding of PoolWorker to possible derived
+ * FragmentJob classes.
+ */
+void dummyInit() {
+  SystemCommandJob("/bin/false", "something", JobId::IllegalJob);
+  MPQCCommandJob("nofile", JobId::IllegalJob);
+}
+
+/** Constructor for class PoolWorker.
+ *
+ * We automatically connect to the given pool and enroll.
+ *
+ * @param io_service io service for creating connections
+ * @param _host host part of address of pool to connect to
+ * @param _service service part of address of pool to connect to
+ * @param listenhost host part of address of this instance for listening to pool connections
+ * @param listenservice seervice part of address of this instance for listening to pool connections
+ */
+PoolWorker::PoolWorker(
+    boost::asio::io_service& io_service,
+    const std::string& _host,
+    const std::string& _service,
+    const std::string& listenhost,
+    const std::string& listenservice) :
+  connection_(io_service),
+  PoolListener(io_service, boost::lexical_cast<unsigned short>(listenservice), *this),
+  address(listenhost, listenservice),
+  enrollOp(connection_, address),
+  submitOp(connection_, address),
+  submitresult(boost::bind(&Operation::operator(),
+      boost::ref(submitOp),
+      _host, _service))
+{
+  Info info(__FUNCTION__);
+
+  // always enroll
+  enrollOp(_host,_service);
+
+  // initiate listening
+  PoolListener.initiateSocket();
+}
+
+/// Handle completion of a accept server operation.
+void PoolWorker::PoolListener_t::handle_Accept(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    conn->async_read(job,
+      boost::bind(&PoolWorker::PoolListener_t::handle_ReceiveJob, this,
+      boost::asio::placeholders::error, conn));
+    // and listen for following connections
+    //initiateSocket();
+  }
+  else
+  {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // accept operation the io_service will run out of work to do and the
+    // server will exit.
+    ELOG(0, e.message());
+  }
+}
+
+/// Controller callback function when job has been sent.
+void PoolWorker::PoolListener_t::handle_ReceiveJob(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+
+  if (!e)
+  {
+    LOG(1, "INFO: Received job " << job->getId() << ".");
+    callback.WorkOnJob(job);
+  }
+  else
+  {
+    // An error occurred. Log it and return. Since we are not starting a new
+    // accept operation the io_service will run out of work to do and the
+    // server will exit.
+    ELOG(0, e.message());
+  }
+}
+
+/** Works on the given job and send the results.
+ *
+ * @param job job to work on
+ */
+void PoolWorker::WorkOnJob(FragmentJob::ptr &job)
+{
+  // work on job and create result
+  LOG(2, "DEBUG: Beginning to work on " << job->getId() << ".");
+  FragmentResult::ptr result = job->Work();
+  LOG(2, "DEBUG: Setting result " << result->getId() << ".");
+  submitOp.setResult(result);
+
+  // submit result
+  LOG(2, "DEBUG: Sending result ...");
+  submitresult();
+}
Index: src/Fragmentation/Automation/Pool/PoolWorker.hpp
===================================================================
--- src/Fragmentation/Automation/Pool/PoolWorker.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/Pool/PoolWorker.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,100 @@
+/*
+ * \file PoolWorker.hpp
+ *
+ * This file strongly follows the Serialization example from the boost::asio
+ * library (see client.cpp).
+ *
+ *  Created on: Feb 28, 2012
+ *      Author: heber
+ */
+
+#ifndef POOLWORKER_HPP_
+#define POOLWORKER_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/asio.hpp>
+#include <boost/function.hpp>
+#include <vector>
+#include "Connection.hpp"
+#include "Jobs/FragmentJob.hpp"
+#include "Controller/Commands/EnrollInPoolOperation.hpp"
+#include "Controller/Commands/SubmitResultOperation.hpp"
+#include "Listener.hpp"
+#include "WorkerAddress.hpp"
+
+/** Receives a job from Server to execute and return FragmentResult.
+ *
+ */
+class PoolWorker
+{
+public:
+  /// Constructor starts the asynchronous connect operation.
+  PoolWorker(
+      boost::asio::io_service& io_service,
+      const std::string& host,
+      const std::string& service,
+      const std::string& listenhost,
+      const std::string& listenservice);
+
+  /** Returns the flag of the handled operation.
+   *
+   */
+  size_t getFlag() const
+  {
+    return submitOp.getFlag();
+  }
+
+  void WorkOnJob(FragmentJob::ptr &job);
+
+  class PoolListener_t : public Listener
+  {
+  public:
+    PoolListener_t(
+        boost::asio::io_service& io_service,
+        unsigned short port,
+        PoolWorker &_callback) :
+      Listener(io_service, port),
+      callback(_callback)
+    {}
+    virtual ~PoolListener_t() {}
+
+  protected:
+    /// Handle completion of a accept controller operation.
+    void handle_Accept(const boost::system::error_code& e, connection_ptr conn);
+
+    /// Controller callback function when job has been sent.
+    void handle_ReceiveJob(const boost::system::error_code& e, connection_ptr conn);
+
+  private:
+    //!> callback reference to PoolWorker for handling the job
+    PoolWorker &callback;
+
+    //!> current job
+    FragmentJob::ptr job;
+  };
+
+private:
+  //!> The Connection to the server.
+  Connection connection_;
+
+  //!> The listener for the WorkerPool
+  PoolListener_t PoolListener;
+
+  //!> address of this worker
+  const WorkerAddress address;
+
+  //!> operation that handles obtaining a job
+  EnrollInPoolOperation enrollOp;
+
+  //!> operation that handles submitting job's result
+  SubmitResultOperation submitOp;
+
+  //!> internally bound function such that host and service don't have to be stored, submits result
+  boost::function<void ()> submitresult;
+};
+
+#endif /* POOLWORKER_HPP_ */
Index: src/Fragmentation/Automation/Pool/WorkerPool.cpp
===================================================================
--- src/Fragmentation/Automation/Pool/WorkerPool.cpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/Pool/WorkerPool.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -76,4 +76,16 @@
   // return address
   return returnaddress;
+}
+
+WorkerPool::Idle_Queue_t::iterator WorkerPool::getIdleWorker(const WorkerAddress &address)
+{
+  Idle_Queue_t::iterator idleiter = idle_queue.begin();
+  while (idleiter != idle_queue.end()) {
+    if (idleiter->second == address) {
+      break;
+    }
+    ++idleiter;
+  }
+  return idleiter;
 }
 
@@ -130,11 +142,7 @@
   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;
-      }
-    }
+    Idle_Queue_t::iterator idleiter = getIdleWorker(address);
+    if (idleiter != idle_queue.end())
+      idle_queue.erase(idleiter);
     Busy_Queue_t::iterator busyiter = busy_queue.find(address);
     if (busyiter != busy_queue.end())
@@ -147,4 +155,5 @@
         +" is in pool and both idle and busy!");
     pool.erase(iter);
+    LOG(1, "INFO: Removed worker " << address << " from pool.");
     return true;
   } else {
@@ -174,7 +183,7 @@
 void WorkerPool::markWorkerBusy(Idle_Queue_t::iterator &iter)
 {
-  if (isWorkerBusy(iter->second))
+  const WorkerAddress returnaddress = iter->second;
+  if (isWorkerBusy(returnaddress))
     return;
-  const WorkerAddress returnaddress = iter->second;
   const priority_t priority = iter->first;
 
@@ -206,4 +215,6 @@
     busy_queue.erase(address);
     idle_queue.insert( make_pair( priority, address) );
-  }
-}
+
+    LOG(1, "INFO: Worker " << address << " is now marked idle.");
+  }
+}
Index: src/Fragmentation/Automation/Pool/WorkerPool.hpp
===================================================================
--- src/Fragmentation/Automation/Pool/WorkerPool.hpp	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ src/Fragmentation/Automation/Pool/WorkerPool.hpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -46,5 +46,6 @@
   void unmarkWorkerBusy(const WorkerAddress &address);
 
-private:
+  // this is currently for the passing time until Worker pool is fully operable
+
   //!> typedef of the priority in the idle queue of a worker
   typedef size_t priority_t;
@@ -53,4 +54,12 @@
   typedef std::multimap<priority_t, WorkerAddress> Idle_Queue_t;
 
+  Idle_Queue_t::iterator getIdleWorker(const WorkerAddress &address);
+  Idle_Queue_t::iterator getIdleEnd()
+  {
+    return idle_queue.end();
+  }
+  void markWorkerBusy(Idle_Queue_t::iterator &iter);
+
+private:
   //!> typedef for the worker queue being a map with priority and address of worker
   typedef std::map<WorkerAddress, priority_t> Busy_Queue_t;
@@ -60,5 +69,4 @@
 
 private:
-  void markWorkerBusy(Idle_Queue_t::iterator &iter);
   void removeAllWorkers();
 
Index: src/Fragmentation/Automation/poolworker.cpp
===================================================================
--- src/Fragmentation/Automation/poolworker.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
+++ src/Fragmentation/Automation/poolworker.cpp	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -0,0 +1,71 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2012 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * \file poolworker.cpp
+ *
+ * This file strongly follows the Serialization example from the boost::asio
+ * library (see client.cpp)
+ *
+ *  Created on: Feb 28, 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 <iostream>
+#include <boost/lexical_cast.hpp>
+
+#include "atexit.hpp"
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "Pool/PoolWorker.hpp"
+
+
+int main(int argc, char* argv[])
+{
+  // from this moment on, we need to be sure to deeinitialize in the correct order
+  // this is handled by the cleanup function
+  atexit(cleanUp);
+
+  setVerbosity(3);
+
+  size_t exitflag = 0;
+  try
+  {
+    // Check command line arguments.
+    if (argc != 5)
+    {
+      std::cerr << "Usage: " << argv[0] << " <host> <port> <listenhost> <listenport>" << std::endl;
+      return 1;
+    }
+
+    boost::asio::io_service io_service;
+    PoolWorker client(io_service, argv[1], argv[2], argv[3], argv[4]);
+    {
+      Info info("io_service");
+      io_service.run();
+    }
+    exitflag = client.getFlag();
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+
+
+  return exitflag;
+}
Index: tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-addingjobs.at
===================================================================
--- tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-addingjobs.at	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-addingjobs.at	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -7,4 +7,5 @@
 WORKERPORT=1035
 CONTROLLERPORT=1036
+LISTENPORT=1037
 
 # start service in background
@@ -18,5 +19,5 @@
 
 # work on jobs
-AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $WORKERPORT], 0, [ignore], [ignore], [kill $server_pid])
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/PoolWorker 127.0.0.1 $WORKERPORT 127.0.0.1 $LISTENPORT], 0, [ignore], [ignore], [kill $server_pid])
 
 # shutdown
Index: tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-completerun.at
===================================================================
--- tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-completerun.at	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-completerun.at	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -7,4 +7,5 @@
 WORKERPORT=1050
 CONTROLLERPORT=1051
+LISTENPORT=1052
 
 # start service in background
@@ -22,6 +23,6 @@
 AT_CHECK([fgrep "0 jobs are calculated so far." stdout], 0, [ignore], [ignore], [kill $server_pid])
 # start working
-AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $WORKERPORT], 0, [stdout], [ignore], [kill $server_pid])
-AT_CHECK([fgrep "Calculating job #1" stdout], 0, [ignore], [ignore], [kill $server_pid])
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/PoolWorker 127.0.0.1 $WORKERPORT 127.0.0.1 $LISTENPORT], 0, [stdout], [ignore], [kill $server_pid])
+AT_CHECK([fgrep "result #1 sent" stdout], 0, [ignore], [ignore], [kill $server_pid])
 # Checking results 
 AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Controller 127.0.0.1 $CONTROLLERPORT checkresults], 0, [stdout], [ignore], [kill $server_pid])
@@ -33,6 +34,6 @@
 AT_CHECK([grep "1" stdout], 0, [ignore], [ignore], [kill $server_pid])
 # work some more
-AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $WORKERPORT], 0, [stdout], [ignore], [kill $server_pid])
-AT_CHECK([fgrep "Calculating job #2" stdout], 0, [ignore], [ignore], [kill $server_pid])
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/PoolWorker 127.0.0.1 $WORKERPORT 127.0.0.1 $LISTENPORT], 0, [stdout], [ignore], [kill $server_pid])
+AT_CHECK([fgrep "result #2 sent" stdout], 0, [ignore], [ignore], [kill $server_pid])
 # Checking results 
 AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Controller 127.0.0.1 $CONTROLLERPORT checkresults], 0, [stdout], [ignore], [kill $server_pid])
Index: tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-server-worker.at
===================================================================
--- tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-server-worker.at	(revision 5d8c0f3e6cd2a623237358cf3c11d644a2aaf86c)
+++ tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation-server-worker.at	(revision 41c1b778849fcd8e13f030bc1e1012ac80cd8881)
@@ -7,4 +7,5 @@
 WORKERPORT=1025
 CONTROLLERPORT=1026
+LISTENPORT=1027
 
 # start service in background
@@ -17,6 +18,6 @@
 
 # first worker has a job
-AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $WORKERPORT], 0, [stdout], [ignore], [kill $server_pid])
-AT_CHECK([fgrep "Job id: 1" stdout], 0, [ignore], [ignore], [kill $server_pid])
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/PoolWorker 127.0.0.1 $WORKERPORT 127.0.0.1 $LISTENPORT], 0, [stdout], [ignore], [kill $server_pid])
+AT_CHECK([fgrep "result #1 sent" stdout], 0, [ignore], [ignore], [kill $server_pid])
 
 # check number of done jobs 
