Index: src/Fragmentation/Automation/FragmentController.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentController.cpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
+++ src/Fragmentation/Automation/FragmentController.cpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ */
+
+/*
+ * FragmentController.cpp
+ *
+ *  Created on: Nov 27, 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 "FragmentJob.hpp"
+#include "FragmentResult.hpp"
+
+#include "FragmentController.hpp"
+
+/** Constructor of class FragmentController.
+ *
+ * \param io_service io_service for the asynchronous operations
+ * \param _host hostname of server that accepts jobs
+ * \param _service of server
+ */
+FragmentController::FragmentController(
+    boost::asio::io_service& io_service,
+    const std::string& _host,
+    const std::string& _service) :
+    connection_(io_service),
+    host(_host),
+    service(_service),
+    Exitflag(OkFlag)
+{
+  Info info(__FUNCTION__);
+}
+
+/** Destructor of class FragmentController.
+ *
+ */
+FragmentController::~FragmentController()
+{}
+
+/** Handle completion of a connect operation.
+ *
+ * \param e error code if something went wrong
+ * \param endpoint_iterator endpoint of the connection
+ */
+void FragmentController::handle_connect_calc(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 vector
+    // of jobs. The connection::async_write() function will automatically
+    // encode the data that is written to the underlying socket.
+    LOG(1, "INFO: Sending "+toString(jobs.size())+" jobs ...");
+    connection_.async_write(jobs,
+      boost::bind(&FragmentController::handle_SendJobs, 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(&FragmentController::handle_connect_calc, 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 jobs have been sent.
+ *
+ * \param e error code if something went wrong
+ */
+void FragmentController::handle_SendJobs(const boost::system::error_code& e)
+{
+  Info info(__FUNCTION__);
+  // do nothing
+  LOG(1, "INFO: Jobs sent.");
+}
+
+/** Internal function to resolve all possible connection endpoints.
+ *
+ * \return endpoint iterator of connection
+ */
+boost::asio::ip::tcp::resolver::iterator FragmentController::getEndpointIterator()
+{
+  // Resolve the host name into an IP address.
+  boost::asio::ip::tcp::resolver resolver(connection_.socket().get_io_service());
+  boost::asio::ip::tcp::resolver::query query(host, service);
+  boost::asio::ip::tcp::resolver::iterator endpoint_iterator =
+    resolver.resolve(query);
+
+  return endpoint_iterator;
+}
+
+/** Internal function to connect to the endpoint of the server asynchronuously.
+ *
+ * We require internal connetion_ and host and service to be set up for this.
+ */
+void FragmentController::connect_calc()
+{
+  Info info(__FUNCTION__);
+  // Resolve the host name into an IP address.
+  boost::asio::ip::tcp::resolver::iterator endpoint_iterator = getEndpointIterator();
+  boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
+
+  // Start an asynchronous connect operation.
+  std::cout << "Connecting to endpoint " << endpoint << " to calc " << std::endl;
+  connection_.socket().async_connect(endpoint,
+    boost::bind(&FragmentController::handle_connect_calc, this,
+      boost::asio::placeholders::error, ++endpoint_iterator));
+}
+
+/** Internal function to disconnect connection_ correctly.
+ *
+ */
+void FragmentController::disconnect()
+{
+  //connection_.socket().close();
+}
+
+/** Place number of jobs into this controller.
+ *
+ * \param _jobs jobs to add
+ */
+void FragmentController::addJobs(const std::vector<FragmentJob> &_jobs)
+{
+  jobs = _jobs;
+}
+
+/** Prepares the calculation of the results for the current jobs.
+ */
+void FragmentController::calculateResults()
+{
+  Info info(__FUNCTION__);
+  // connect
+  connect_calc();
+  //disconnect
+  disconnect();
+}
+
Index: src/Fragmentation/Automation/FragmentController.hpp
===================================================================
--- src/Fragmentation/Automation/FragmentController.hpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
+++ src/Fragmentation/Automation/FragmentController.hpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -0,0 +1,90 @@
+/*
+ * FragmentController.hpp
+ *
+ *  Created on: Nov 27, 2011
+ *      Author: heber
+ */
+
+#ifndef FRAGMENTCONTROLLER_HPP_
+#define FRAGMENTCONTROLLER_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/asio.hpp>
+#include <string>
+#include <vector>
+
+#include "Connection.hpp"
+#include "FragmentJob.hpp"
+#include "FragmentResult.hpp"
+
+/** The FragmentController sends bunches of jobs to a FragmentScheduler,
+ *  waits for their calculation and is called when they are done. Then,
+ *  he loads the bunch of results from the Scheduler.
+ *
+ * While the FragmentScheduler and FragmentWorker rather act on their own
+ * this is the piece to implant into the user software to allow for
+ * communication with the Server/Worker duo to perform the calculation
+ * of the fragments on distant computers.
+ */
+class FragmentController
+{
+public:
+  FragmentController(boost::asio::io_service& io_service, const std::string& host, const std::string& service);
+  ~FragmentController();
+
+  /// Handle completion of a accept operation.
+  void handle_connect_calc(const boost::system::error_code& e,
+      boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
+
+  /// Callback function when bunch of jobs have been sent.
+  void handle_SendJobs(const boost::system::error_code& e);
+
+  /// place number of jobs into this controller
+  void addJobs(const std::vector<FragmentJob> &jobs);
+
+  /// prepares the calculation of the results
+  void calculateResults();
+  
+  enum Exitflag_t {
+    OkFlag = 0,
+    ErrorFlag = 255
+  };
+
+  // get the exit flag of the last operations
+  size_t getExitflag() const
+  {
+    return Exitflag;
+  }
+
+private:
+  /// internal function to resolve host name and ip address
+  boost::asio::ip::tcp::resolver::iterator getEndpointIterator();
+
+  /// internal function to connect to server and send jobs for calculating jobs
+  void connect_calc();
+
+  /// internal function to disconnect from server
+  void disconnect();
+
+private:
+  /// The Connection to the server.
+  Connection connection_;
+
+  /// host name of server
+  const std::string host;
+
+  // service to connect to to
+  const std::string service;
+
+  /// bunch of jobs
+  std::vector<FragmentJob> jobs;
+
+  /// flag to give on program exit
+  enum Exitflag_t Exitflag;
+};
+
+#endif /* FRAGMENTCONTROLLER_HPP_ */
Index: src/Fragmentation/Automation/FragmentScheduler.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentScheduler.cpp	(revision 8ee5ac067548a00b728f1a0f0c9f085fbb85cd93)
+++ src/Fragmentation/Automation/FragmentScheduler.cpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -41,23 +41,50 @@
 FragmentJob FragmentScheduler::NoJob(std::string("NoJob"), JobId::NoJob);
 
-FragmentScheduler::FragmentScheduler(boost::asio::io_service& io_service, unsigned short port) :
-  acceptor_(io_service,
-      boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)
+/** Constructor of class FragmentScheduler.
+ *
+ * We setup both acceptors to accept connections from workers and Controller.
+ *
+ * \param io_service io_service of the asynchronous communications
+ * \param workerport port to listen for worker connections
+ * \param controllerport port to listen for controller connections.
+ */
+FragmentScheduler::FragmentScheduler(boost::asio::io_service& io_service, unsigned short workerport, unsigned short controllerport) :
+  worker_acceptor_(io_service,
+      boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), workerport)
   ),
-  result(JobId::NoJob)
-{
-  Info info(__FUNCTION__);
-  FragmentJob s(std::string("test"), 1);
-  JobsQueue.pushJob(s);
-
-  // Start an accept operation for a new connection.
-  connection_ptr new_conn(new Connection(acceptor_.get_io_service()));
-  acceptor_.async_accept(new_conn->socket(),
-    boost::bind(&FragmentScheduler::handle_accept, this,
-      boost::asio::placeholders::error, new_conn));
-}
-
-/// Handle completion of a accept operation.
-void FragmentScheduler::handle_accept(const boost::system::error_code& e, connection_ptr conn)
+  controller_acceptor_(io_service,
+      boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), controllerport)
+  ),
+  result(JobId::NoJob),
+  Exitflag(OkFlag)
+{
+  Info info(__FUNCTION__);
+  {
+    // Start an accept operation for worker connections.
+    connection_ptr new_conn(new Connection(worker_acceptor_.get_io_service()));
+    worker_acceptor_.async_accept(new_conn->socket(),
+      boost::bind(&FragmentScheduler::handle_AcceptWorker, this,
+        boost::asio::placeholders::error, new_conn));
+  }
+
+  {
+    // Start an accept operation for controller connection.
+    connection_ptr new_conn(new Connection(controller_acceptor_.get_io_service()));
+    controller_acceptor_.async_accept(new_conn->socket(),
+      boost::bind(&FragmentScheduler::handle_AcceptController, this,
+        boost::asio::placeholders::error, new_conn));
+  }
+}
+
+/** Handle a new worker connection.
+ *
+ * We check whether jobs are in the JobsQueue. If present, job is sent.
+ *
+ * \sa handle_SendJobtoWorker()
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::handle_AcceptWorker(const boost::system::error_code& e, connection_ptr conn)
 {
   Info info(__FUNCTION__);
@@ -73,17 +100,17 @@
       LOG(1, "INFO: Sending job #" << job.getId() << ".");
       conn->async_write(job,
-        boost::bind(&FragmentScheduler::handle_SendJob, this,
+        boost::bind(&FragmentScheduler::handle_SendJobtoWorker, this,
         boost::asio::placeholders::error, conn));
 
       // Start an accept operation for a new Connection only when there
       // are still jobs present otherwise we quit.
-      connection_ptr new_conn(new Connection(acceptor_.get_io_service()));
-      acceptor_.async_accept(new_conn->socket(),
-        boost::bind(&FragmentScheduler::handle_accept, this,
+      connection_ptr new_conn(new Connection(worker_acceptor_.get_io_service()));
+      worker_acceptor_.async_accept(new_conn->socket(),
+        boost::bind(&FragmentScheduler::handle_AcceptWorker, this,
         boost::asio::placeholders::error, new_conn));
     } else {
       // send the static NoJob
       conn->async_write(NoJob,
-        boost::bind(&FragmentScheduler::handle_SendJob, this,
+        boost::bind(&FragmentScheduler::handle_SendJobtoWorker, this,
         boost::asio::placeholders::error, conn));
 
@@ -102,6 +129,14 @@
 }
 
-/// Callback function when job has been sent.
-void FragmentScheduler::handle_SendJob(const boost::system::error_code& e, connection_ptr conn)
+/** 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::handle_SendJobtoWorker(const boost::system::error_code& e, connection_ptr conn)
 {
     Info info(__FUNCTION__);
@@ -110,23 +145,87 @@
     LOG(1, "INFO: Receiving result for a job ...");
     conn->async_read(result,
-      boost::bind(&FragmentScheduler::handle_ReceiveResult, this,
+      boost::bind(&FragmentScheduler::handle_ReceiveResultFromWorker, this,
       boost::asio::placeholders::error, conn));
 }
 
-/// Callback function when result has been received.
-void FragmentScheduler::handle_ReceiveResult(const boost::system::error_code& e, connection_ptr conn)
-{
-    Info info(__FUNCTION__);
-    // nothing to do
-    LOG(1, "INFO: Received result for job #" << result.getId() << " ...");
-    // and push into queue
-    ASSERT(result.getId() != JobId::NoJob,
-        "FragmentScheduler::handle_write() - result received has NoJob id.");
-    ASSERT(result.getId() != JobId::IllegalJob,
-        "FragmentScheduler::handle_write() - result received has IllegalJob id.");
-    if ((result.getId() != JobId::NoJob) && (result.getId() != JobId::IllegalJob))
-      JobsQueue.pushResult(result);
-    // erase result
-    result = FragmentResult(JobId::NoJob);
-}
-
+/** Callback function when result has been received.
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::handle_ReceiveResultFromWorker(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  // nothing to do
+  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.");
+  ASSERT(result.getId() != (JobId_t)JobId::IllegalJob,
+      "FragmentScheduler::handle_ReceiveResultFromWorker() - result received has IllegalJob id.");
+  if ((result.getId() != (JobId_t)JobId::NoJob) && (result.getId() != (JobId_t)JobId::IllegalJob))
+    JobsQueue.pushResult(result);
+  // erase result
+  result = FragmentResult(JobId::NoJob);
+}
+
+/** Handle a new controller connection.
+ *
+ * \sa handle_ReceiveJobs()
+ * \sa handle_CheckResultState()
+ * \sa handle_SendResults()
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::handle_AcceptController(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  if (!e)
+  {
+    if (jobs.empty()) {
+      // The connection::async_write() function will automatically
+      // serialize the data structure for us.
+      LOG(1, "INFO: Receiving bunch of jobs from a controller ...");
+      conn->async_read(jobs,
+        boost::bind(&FragmentScheduler::handle_ReceiveJobs, 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());
+  }
+}
+
+/** Controller callback function when job has been sent.
+ *
+ * \param e error code if something went wrong
+ * \param conn reference with the connection
+ */
+void FragmentScheduler::handle_ReceiveJobs(const boost::system::error_code& e, connection_ptr conn)
+{
+  Info info(__FUNCTION__);
+  // jobs are received, hence place in JobsQueue
+  if (!jobs.empty()) {
+    LOG(1, "INFO: Pushing " << jobs.size() << " jobs into queue.");
+    JobsQueue.pushJobs(jobs);
+  }
+  // launch new acceptor of queue has been filled/is full
+  if (JobsQueue.isJobPresent()) {
+    // Start an accept operation for a new Connection.
+    connection_ptr new_conn(new Connection(controller_acceptor_.get_io_service()));
+    controller_acceptor_.async_accept(new_conn->socket(),
+      boost::bind(&FragmentScheduler::handle_AcceptController, this,
+      boost::asio::placeholders::error, new_conn));
+  } else {
+    LOG(1, "INFO: Shutting down controller socket.");
+  }
+
+  jobs.clear();
+}
+
Index: src/Fragmentation/Automation/FragmentScheduler.hpp
===================================================================
--- src/Fragmentation/Automation/FragmentScheduler.hpp	(revision 8ee5ac067548a00b728f1a0f0c9f085fbb85cd93)
+++ src/Fragmentation/Automation/FragmentScheduler.hpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -30,21 +30,48 @@
   /// Constructor opens the acceptor and starts waiting for the first incoming
   /// Connection.
-  FragmentScheduler(boost::asio::io_service& io_service, unsigned short port);
+  FragmentScheduler(boost::asio::io_service& io_service, unsigned short workerport, unsigned short controllerport);
 
-  /// Handle completion of a accept operation.
-  void handle_accept(const boost::system::error_code& e, connection_ptr conn);
+  enum Exitflag_t{
+    OkFlag = 0,
+    ErrorFlag = 255
+  };
 
-  /// Callback function when job has been sent.
-  void handle_SendJob(const boost::system::error_code& e, connection_ptr conn);
+  /** Getter for Exitflag.
+   *
+   * @return Exitflag of operations
+   */
+  size_t getExitflag() const
+  {
+    return Exitflag;
+  }
 
-  /// Callback function when result has been received.
-  void handle_ReceiveResult(const boost::system::error_code& e, connection_ptr conn);
+protected:
+  /// Handle completion of a accept worker operation.
+  void handle_AcceptWorker(const boost::system::error_code& e, connection_ptr conn);
+
+  /// Handle completion of a accept controller operation.
+  void handle_AcceptController(const boost::system::error_code& e, connection_ptr conn);
+
+  /// Worker callback function when job has been sent.
+  void handle_SendJobtoWorker(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);
+
+  /// Controller callback function when job has been sent.
+  void handle_ReceiveJobs(const boost::system::error_code& e, connection_ptr conn);
 
 private:
-  /// The acceptor object used to accept incoming socket connections.
-  boost::asio::ip::tcp::acceptor acceptor_;
+  /// The acceptor object used to accept incoming worker socket connections.
+  boost::asio::ip::tcp::acceptor worker_acceptor_;
+
+  /// The acceptor object used to accept incoming controller socket connections.
+  boost::asio::ip::tcp::acceptor controller_acceptor_;
 
   /// result that is received from the client.
   FragmentResult result;
+
+  /// bunch of jobs received from controller before placed in JobsQueue
+  std::vector<FragmentJob> jobs;
 
   /// Queue with data to be sent to each client.
@@ -53,4 +80,7 @@
   // static entity to indicate to clients that the queue is empty.
   static FragmentJob NoJob;
+
+  // Exit flag on program exit
+  enum Exitflag_t Exitflag;
 };
 
Index: src/Fragmentation/Automation/FragmentWorker.hpp
===================================================================
--- src/Fragmentation/Automation/FragmentWorker.hpp	(revision 8ee5ac067548a00b728f1a0f0c9f085fbb85cd93)
+++ src/Fragmentation/Automation/FragmentWorker.hpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -29,14 +29,4 @@
       const std::string& host, const std::string& service);
 
-  /// Handle completion of a connect operation.
-  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);
-
   enum Exitflag_t {
     OkFlag = 0,
@@ -52,4 +42,15 @@
     return Exitflag;
   }
+
+protected:
+  /// Handle completion of a connect operation.
+  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:
Index: src/Fragmentation/Automation/JobAdder.cpp
===================================================================
--- src/Fragmentation/Automation/JobAdder.cpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
+++ src/Fragmentation/Automation/JobAdder.cpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -0,0 +1,82 @@
+/*
+ * 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 JobAdder.cpp
+ *
+ * This file strongly follows the Serialization example from the boost::asio
+ * library (see client.cpp)
+ *
+ *  Created on: Nov 27, 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 <iostream>
+#include <vector>
+#include <boost/lexical_cast.hpp>
+
+#include "atexit.hpp"
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "FragmentController.hpp"
+#include "FragmentJob.hpp"
+#include "FragmentResult.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 != 4)
+    {
+      std::cerr << "Usage: " << argv[0] << " <host> <port> <number of jobs>" << std::endl;
+      return 1;
+    }
+    const int NoJobs = boost::lexical_cast<int>(argv[3]);
+    boost::asio::io_service io_service;
+    FragmentController controller(io_service, argv[1], argv[2]);
+
+    LOG(1, "INFO: Creating " << NoJobs << " jobs for the server.");
+    std::vector<FragmentJob> jobs;
+    for (JobId_t i = 1; i <= NoJobs; ++i) {
+      FragmentJob testJob(std::string("do something"), i);
+      jobs.push_back(testJob);
+    }
+    controller.addJobs(jobs);
+    controller.calculateResults();
+    {
+      Info info("io_service");
+      io_service.run();
+    }
+    Exitflag = controller.getExitflag();
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+
+  return Exitflag;
+}
Index: src/Fragmentation/Automation/Makefile.am
===================================================================
--- src/Fragmentation/Automation/Makefile.am	(revision 8ee5ac067548a00b728f1a0f0c9f085fbb85cd93)
+++ src/Fragmentation/Automation/Makefile.am	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -45,9 +45,15 @@
 AM_CPPFLAGS = ${BOOST_CPPFLAGS} ${CodePatterns_CFLAGS}
 
-bin_PROGRAMS += Server Worker
+bin_PROGRAMS += JobAdder Server Worker
+
+CONTROLLERSOURCE = \
+  FragmentController.cpp
+
+CONTROLLERHEADER = \
+  Connection.hpp \
+  FragmentController.hpp
 
 SERVERSOURCE = \
-  FragmentScheduler.cpp \
-  Server.cpp
+  FragmentScheduler.cpp
 
 SERVERHEADER = \
@@ -63,5 +69,17 @@
   FragmentWorker.hpp
 
-Server_SOURCES = $(SERVERSOURCE) $(SERVERHEADER)
+JobAdder_SOURCES = $(CONTROLLERSOURCE) $(CONTROLLERHEADER) JobAdder.cpp
+JobAdder_LDFLAGS = $(AM_LDFLAGS) $(BOOST_ASIO_LDFLAGS) $(BOOST_SYSTEM_LDFLAGS) $(BOOST_THREAD_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS)
+JobAdder_CXXFLAGS = $(AM_CPPFLAGS)
+JobAdder_LDADD = \
+  libMolecuilderFragmentJobs.la \
+  libMolecuilderFragmentationAutomation.la \
+  $(BOOST_ASIO_LIBS) \
+  $(BOOST_SERIALIZATION_LIBS) \
+  $(BOOST_THREAD_LIBS) \
+  $(BOOST_SYSTEM_LIBS) \
+  ${CodePatterns_LIBS}
+
+Server_SOURCES = $(SERVERSOURCE) $(SERVERHEADER) Server.cpp
 Server_LDFLAGS = $(AM_LDFLAGS) $(BOOST_ASIO_LDFLAGS) $(BOOST_SYSTEM_LDFLAGS) $(BOOST_THREAD_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS)
 Server_CXXFLAGS = $(AM_CPPFLAGS)
Index: src/Fragmentation/Automation/Server.cpp
===================================================================
--- src/Fragmentation/Automation/Server.cpp	(revision 8ee5ac067548a00b728f1a0f0c9f085fbb85cd93)
+++ src/Fragmentation/Automation/Server.cpp	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -43,21 +43,25 @@
   setVerbosity(3);
 
+  size_t Exitflag = 0;
   try
   {
     // Check command line arguments.
-    if (argc != 2)
+    if (argc != 3)
     {
-      std::cerr << "Usage: " << argv[0] << " <port>" << std::endl;
+      std::cerr << "Usage: " << argv[0] << " <worker port> <controller port>" << std::endl;
       return 1;
     }
-    unsigned short port = boost::lexical_cast<unsigned short>(argv[1]);
-    std::cout << "Listening on port " << port << "." << std::endl;
+    unsigned short workerport = boost::lexical_cast<unsigned short>(argv[1]);
+    std::cout << "Listening for workers on port " << workerport << "." << std::endl;
+    unsigned short controllerport = boost::lexical_cast<unsigned short>(argv[2]);
+    std::cout << "Listening for controller on port " << controllerport << "." << std::endl;
 
     boost::asio::io_service io_service;
-    FragmentScheduler Server(io_service, port);
+    FragmentScheduler Server(io_service, workerport, controllerport);
     {
       Info info("io_service");
       io_service.run();
     }
+    Exitflag = Server.getExitflag();
   }
   catch (std::exception& e)
@@ -66,4 +70,4 @@
   }
 
-  return 0;
+  return Exitflag;
 }
Index: tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation.at
===================================================================
--- tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation.at	(revision 8ee5ac067548a00b728f1a0f0c9f085fbb85cd93)
+++ tests/regression/Fragmentation/Automation/testsuite-fragmentation-automation.at	(revision db03d94db34e97b2e16df2332a1953abdf66be98)
@@ -4,15 +4,22 @@
 AT_KEYWORDS([fragmentation automation worker])
 
-TESTPORT=1025
+WORKERPORT=1025
+CONTROLLERPORT=1026
 
 # start service in background
-${AUTOTEST_PATH}/Fragmentation/Automation/Server $TESTPORT &
+${AUTOTEST_PATH}/Fragmentation/Automation/Server $WORKERPORT $CONTROLLERPORT &
 AT_CHECK([sleep 1], 0, [ignore], [ignore], [pkill Server])
 
-# first worker has a job (check that job #1 is reference twice in output)
-AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $TESTPORT], 0, [stdout], [ignore], [pkill Server])
+# add a job
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/JobAdder 127.0.0.1 $CONTROLLERPORT 1], 0, [stdout], [ignore], [pkill Server])
+# first worker has a job
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $WORKERPORT], 0, [stdout], [ignore], [pkill Server])
 AT_CHECK([fgrep "Job id: 1" stdout], 0, [ignore], [ignore], [pkill Server])
-# second job has none
-AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $TESTPORT], 1, [ignore], [ignore], [pkill Server])
+
+# add no job to shutdown socket
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/JobAdder 127.0.0.1 $CONTROLLERPORT 0], 0, [stdout], [ignore], [pkill Server])
+# third job has none
+AT_CHECK([${AUTOTEST_PATH}/Fragmentation/Automation/Worker 127.0.0.1 $WORKERPORT], 1, [stdout], [ignore], [pkill Server])
+AT_CHECK([fgrep "The server has no job for me" stdout], 0, [ignore], [ignore], [pkill Server])
 
 # check that server is truely down
