Index: configure.ac
===================================================================
--- configure.ac	(revision 7670865494307829aa075e60d6056fe423885484)
+++ configure.ac	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -164,4 +164,5 @@
 BOOST_ASIO
 BOOST_FILESYSTEM
+BOOST_IOSTREAMS
 BOOST_PROGRAM_OPTIONS
 AS_IF([test x"$enable_python" != x"no"], [BOOST_PYTHON])
Index: src/Fragmentation/Automation/Controller/Commands/ReceiveJobsOperation.cpp
===================================================================
--- src/Fragmentation/Automation/Controller/Commands/ReceiveJobsOperation.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/Controller/Commands/ReceiveJobsOperation.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -120,4 +120,5 @@
     jobs.push_back(job);
   }
+  LOG(1, "INFO: ReceiveJobsOperation now contains " << jobs.size() << " job(s).");
 }
 
Index: src/Fragmentation/Automation/FragmentScheduler.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentScheduler.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/FragmentScheduler.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -34,10 +34,10 @@
 #include "CodePatterns/Info.hpp"
 #include "CodePatterns/Log.hpp"
-#include "Jobs/FragmentJob.hpp"
+#include "Jobs/SystemCommandJob.hpp"
 #include "JobId.hpp"
 
 #include "FragmentScheduler.hpp"
 
-FragmentJob::ptr FragmentScheduler::NoJob(new FragmentJob(std::string("/bin/false"), std::string("NoJob"), JobId::NoJob));
+FragmentJob::ptr FragmentScheduler::NoJob(new SystemCommandJob(std::string("/bin/false"), std::string("NoJob"), JobId::NoJob));
 
 /** Constructor of class FragmentScheduler.
Index: src/Fragmentation/Automation/FragmentWorker.cpp
===================================================================
--- src/Fragmentation/Automation/FragmentWorker.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/FragmentWorker.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -34,8 +34,16 @@
 #include "CodePatterns/Log.hpp"
 #include "Jobs/FragmentJob.hpp"
+#include "Jobs/SystemCommandJob.hpp"
 #include "Results/FragmentResult.hpp"
 #include "FragmentWorker.hpp"
 
 FragmentResult::ptr FragmentWorker::EmptyResult( new FragmentResult(JobId::NoJob, std::string("EmptyResult")) );
+
+/** Helper function to enforce binding of FragmentWorker to possible derived
+ * FragmentJob classes.
+ */
+void dummyInit() {
+  SystemCommandJob("/bin/false", "something", JobId::IllegalJob);
+}
 
 /// Constructor starts the asynchronous connect operation.
@@ -102,5 +110,4 @@
     if (job->getId() != JobId::NoJob) {
       // Print out the data that was received.
-      std::cout << "Job output: " << job->outputfile << "\n";
       std::cout << "Job id: " << job->getId() << "\n";
 
@@ -143,5 +150,5 @@
   LOG(1, "INFO: Job #" << job->getId() << " calculated and sent.");
   // erase job
-  job = FragmentJob::ptr(new FragmentJob());
+  job.reset();
 }
 
Index: src/Fragmentation/Automation/Jobs/FragmentJob.cpp
===================================================================
--- src/Fragmentation/Automation/Jobs/FragmentJob.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/Jobs/FragmentJob.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -20,11 +20,4 @@
 #include "CodePatterns/MemDebug.hpp"
 
-#include <cstdlib>
-#include <fstream>
-#include <string>
-
-#include "CodePatterns/Info.hpp"
-#include "CodePatterns/Log.hpp"
-#include "CodePatterns/toString.hpp"
 #include "FragmentJob.hpp"
 #include "Results/FragmentResult.hpp"
@@ -34,18 +27,13 @@
  */
 FragmentJob::FragmentJob() :
-  JobId(-1),
-  outputfile("")
+  JobId(JobId::IllegalJob)
 {}
 
 /** Constructor for class FragmentJob.
  *
- * \param _command command to execute
- * \param _outputfile configuration file for solver
  * \param _JobId unique id of this job
  */
-FragmentJob::FragmentJob(const std::string &_command, const std::string &_outputfile, const JobId_t _JobId) :
-  JobId(_JobId),
-  command(_command),
-  outputfile(_outputfile)
+FragmentJob::FragmentJob(const JobId_t _JobId) :
+  JobId(_JobId)
 {}
 
@@ -56,42 +44,4 @@
 {}
 
-/** Work routine of this FragmentJob.
- *
- * This function encapsulates all the work that has to be done to generate
- * a FragmentResult. Hence, the FragmentWorker does not need to know anything
- * about the operation: it just receives it and executes this function.
- *
- * \return result of this job
- */
-FragmentResult::ptr FragmentJob::Work()
-{
-  Info info((std::string(__FUNCTION__)+std::string(", id #")+toString(getId())).c_str());
-  FragmentResult::ptr s( new FragmentResult(getId()) );
-
-  // write outputfile to file
-  std::string inputfilename =
-      std::string("/tmp/dummy_")
-      +toString(getId());
-  std::string outputfilename = inputfilename+std::string(".out");
-  inputfilename += std::string(".dat");
-  std::ofstream output(outputfilename.c_str());
-  output << outputfile << std::endl;
-  output.close();
-
-  // fork into subprocess and launch command
-  s->exitflag = std::system((command+std::string(" ")+inputfilename
-                        +std::string(" >")+outputfilename).c_str());
-  std::ifstream resultfile;
-  resultfile.open(outputfilename.c_str(), ifstream::in);
-  char line[1024];
-  while (resultfile.good()) {
-    resultfile.getline(line, 1023);
-    s->result += line;
-  }
-  resultfile.close();
-
-  return s;
-}
-
 /** Comparator for class FragmentJob.
  * \param other instance to compare to
@@ -100,6 +50,4 @@
 bool FragmentJob::operator==(const FragmentJob &other) const
 {
-  return (command == other.command)
-      && (outputfile == other.outputfile)
-      && (getId() == other.getId());
+  return (getId() == other.getId());
 }
Index: src/Fragmentation/Automation/Jobs/FragmentJob.hpp
===================================================================
--- src/Fragmentation/Automation/Jobs/FragmentJob.hpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/Jobs/FragmentJob.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -43,9 +43,8 @@
   typedef boost::shared_ptr<FragmentJob> ptr;
 
-  FragmentJob();
-  FragmentJob(const std::string &_command, const std::string &_outputfile, const JobId_t _JobId);
+  FragmentJob(const JobId_t _JobId);
   ~FragmentJob();
 
-  FragmentResult::ptr Work();
+  virtual FragmentResult::ptr Work() = 0;
 
   bool operator==(const FragmentJob &other) const;
@@ -55,11 +54,12 @@
   }
 
-  //!> string containing the command to launch the solver
-  std::string command;
+private:
+  /** private default cstor for serialization only
+   *
+   * Use normal cstor with JobId::IllegalJob if you want to instantiate
+   * a job without id.
+   */
+  FragmentJob();
 
-  //!> string containing the configuration file for the solver
-  std::string outputfile;
-
-private:
   friend class boost::serialization::access;
   // serialization
@@ -68,6 +68,4 @@
   {
     ar & boost::serialization::base_object<JobId>(*this);
-    ar & command;
-    ar & outputfile;
   }
 };
Index: src/Fragmentation/Automation/Jobs/SystemCommandJob.cpp
===================================================================
--- src/Fragmentation/Automation/Jobs/SystemCommandJob.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
+++ src/Fragmentation/Automation/Jobs/SystemCommandJob.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+
+/*
+ * SystemCommandJob.cpp
+ *
+ *  Created on: Feb 5, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/iostreams/device/file_descriptor.hpp>
+#include <boost/iostreams/stream.hpp>
+
+#include "CodePatterns/MemDebug.hpp"
+
+// include headers that implement a archive in simple text format
+// otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "SystemCommandJob.hpp"
+
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <streambuf>
+#include <boost/filesystem.hpp>
+
+
+#include "CodePatterns/Info.hpp"
+#include "CodePatterns/Log.hpp"
+#include "CodePatterns/toString.hpp"
+
+/** Constructor for class SystemCommandJob.
+ *
+ */
+SystemCommandJob::SystemCommandJob() :
+  FragmentJob(JobId::IllegalJob)
+{}
+
+/** Constructor for class SystemCommandJob.
+ *
+ * \param _command command to execute
+ * \param _outputfile configuration file for solver
+ * \param _JobId unique id of this job
+ */
+SystemCommandJob::SystemCommandJob(const std::string &_command, const std::string &_outputfile, const JobId_t _JobId) :
+  FragmentJob(_JobId),
+  command(_command),
+  outputfile(_outputfile)
+{}
+
+/** Destructor for class SystemCommandJob.
+ *
+ */
+SystemCommandJob::~SystemCommandJob()
+{}
+
+/** Work routine of this SystemCommandJob.
+ *
+ * This function encapsulates all the work that has to be done to generate
+ * a FragmentResult. Hence, the FragmentWorker does not need to know anything
+ * about the operation: it just receives it and executes this function.
+ *
+ * We obtain FragmentResult::exitflag from std::system's return value and
+ * FragmentResult::result from the contents of the piped output file.
+ *
+ * \return result of this job
+ */
+FragmentResult::ptr SystemCommandJob::Work()
+{
+  Info info((std::string(__FUNCTION__)+std::string(", id #")+toString(getId())).c_str());
+
+  // the following is taken from http://stackoverflow.com/questions/2746168/how-to-construct-a-c-fstream-from-a-posix-file-descriptor
+  char tmpTemplate[24];
+  strncpy(tmpTemplate, "/tmp/XXXXXX_", 14);
+  const std::string idstring(toString(getId()));
+  const size_t idlength = idstring.length();
+  ASSERT(idlength <= 8,
+    "SystemCommandJob::Work() - the id contains more than 8 digits.");
+  strcat(tmpTemplate, toString(getId()).c_str());
+  mkstemps(tmpTemplate, idlength+1);
+
+  // write outputfile to temporary file
+  LOG(2, "DEBUG: Temporary file is " << tmpTemplate << ".");
+  std::ofstream output(tmpTemplate);
+  ASSERT(output.is_open(),
+    "SystemCommandJob::Work() - the temporary file could not be opened.");
+  output << outputfile << std::endl;
+
+  // fork into subprocess and launch command
+  std::string command_args = command+std::string(" ")+tmpTemplate;
+  LOG(1, "INFO: Executing '" << command_args << "'.");
+  FILE *stdoutstream = popen(command_args.c_str(), "r");
+  FragmentResult::ptr s;
+  {
+    boost::iostreams::stream<boost::iostreams::file_descriptor_source> stdoutfile(fileno(stdoutstream), boost::iostreams::never_close_handle);
+    stdoutfile.set_auto_close(false); // https://svn.boost.org/trac/boost/ticket/3517
+    std::istreambuf_iterator<char> beginiter = (std::istreambuf_iterator<char>(stdoutfile));
+    std::string resultstring( beginiter, std::istreambuf_iterator<char>());
+    // construct result
+    LOG(2, "DEBUG: First 50 characters of output: " << resultstring.substr(0,50));
+    s = extractResult(resultstring);
+  }
+  const int exitflag = pclose(stdoutstream);
+  if (exitflag != 0)
+    ELOG(1, "Job " << getId() << " failed on executing: " << command_args);
+  s->exitflag = exitflag;
+
+  // close temporary file and remove it
+  output.close();
+  boost::filesystem::path tmpPath(tmpTemplate);
+  if (boost::filesystem::exists(boost::filesystem::status(tmpPath))) {
+    LOG(2, "DEBUG: Removing " << tmpPath.string());
+    boost::filesystem::remove(tmpPath);
+  }
+
+  // return result
+  return s;
+}
+
+/** Default function for result extraction is just copy.
+ *
+ * @param resultstring output of system command
+ * @return copy of \a resultstring
+ */
+FragmentResult::ptr SystemCommandJob::extractResult(const std::string &resultstring)
+{
+  return FragmentResult::ptr (new FragmentResult(getId(), resultstring) );
+}
+
+
+/** Comparator for class SystemCommandJob.
+ * \param other instance to compare to
+ * \return every member variable is the same, else - is not
+ */
+bool SystemCommandJob::operator==(const SystemCommandJob &other) const
+{
+  if (command != other.command) {
+    LOG(1, "INFO: command's of two SystemCommandJobs differ: " << command << " != " << other.command << ".");
+    return false;
+  }
+  if (outputfile != other.outputfile) {
+    LOG(1, "INFO: outputfile's of two SystemCommandJobs differ: " << outputfile << " != " << other.outputfile << ".");
+    return false;
+  }
+  return (dynamic_cast<const FragmentJob &>(*this) == dynamic_cast<const FragmentJob &>(other));
+}
+
+// we need to explicitly instantiate the serialization functions as
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_IMPLEMENT(SystemCommandJob)
Index: src/Fragmentation/Automation/Jobs/SystemCommandJob.hpp
===================================================================
--- src/Fragmentation/Automation/Jobs/SystemCommandJob.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
+++ src/Fragmentation/Automation/Jobs/SystemCommandJob.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -0,0 +1,78 @@
+/*
+ * SystemCommandJob.hpp
+ *
+ *  Created on: Feb 5, 2011
+ *      Author: heber
+ */
+
+#ifndef SYSTEMCOMMANDJOB_HPP_
+#define SYSTEMCOMMANDJOB_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/serialization/export.hpp>
+
+#include <string>
+
+#include "Jobs/FragmentJob.hpp"
+
+class SystemCommandJobTest;
+
+/** SystemCommandJob is an extension of FragmentJob that executes a system
+ * command operating onto a specific outputfile.
+ *
+ * Implement extractResult() to get the desired result from the captured
+ * output of the system command.
+ *
+ * Important is that this class is fully serializable such that it can be
+ * transfered to a scheduler (server) and be deserialized by the Worker.
+ */
+class SystemCommandJob : public FragmentJob
+{
+  //!> grant unit test access
+  friend class SystemCommandJobTest;
+public:
+  SystemCommandJob(const std::string &_command, const std::string &_outputfile, const JobId_t _JobId);
+  ~SystemCommandJob();
+
+  FragmentResult::ptr Work();
+
+  bool operator==(const SystemCommandJob &other) const;
+
+  bool operator!=(const SystemCommandJob &other) const {
+    return !(*this == other);
+  }
+
+private:
+  virtual FragmentResult::ptr extractResult(const std::string &resultstring);
+
+  //!> string containing the command to launch the solver
+  std::string command;
+
+  //!> string containing the configuration file for the solver
+  std::string outputfile;
+
+protected:
+  //!> private default cstor for serialization only
+  SystemCommandJob();
+
+private:
+  friend class boost::serialization::access;
+  // serialization
+  template <typename Archive>
+  void serialize(Archive& ar, const unsigned int version)
+  {
+    ar & boost::serialization::base_object<FragmentJob>(*this);
+    ar & command;
+    ar & outputfile;
+  }
+};
+
+// we need to give this class a unique key for serialization
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_KEY(SystemCommandJob)
+
+#endif /* SYSTEMCOMMANDJOB_HPP_ */
Index: src/Fragmentation/Automation/Makefile.am
===================================================================
--- src/Fragmentation/Automation/Makefile.am	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/Makefile.am	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -16,4 +16,5 @@
   JobId.cpp \
   Jobs/FragmentJob.cpp \
+  Jobs/SystemCommandJob.cpp \
   Results/FragmentResult.cpp
           
@@ -22,4 +23,5 @@
   JobId.hpp \
   Jobs/FragmentJob.hpp \
+  Jobs/SystemCommandJob.hpp \
   Results/FragmentResult.hpp
 
@@ -28,4 +30,7 @@
 nobase_libMolecuilderFragmentJobs_la_include_HEADERS = $(FRAGMENTJOBSHEADER)
 libMolecuilderFragmentJobs_la_SOURCES = $(FRAGMENTJOBSSOURCE)
+libMolecuilderFragmentJobs_la_LIBADD = \
+  $(BOOST_FILESYSTEM_LDFLAGS) $(BOOST_FILESYSTEM_LIBS) \
+  $(BOOST_IOSTREAMS_LDFLAGS) $(BOOST_IOSTREAMS_LIBS)
 
 FRAGMENTATIONAUTOMATIONSOURCE = \
Index: src/Fragmentation/Automation/Worker.cpp
===================================================================
--- src/Fragmentation/Automation/Worker.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/Worker.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -41,5 +41,5 @@
   atexit(cleanUp);
 
-  setVerbosity(3);
+  setVerbosity(5);
 
   size_t Exitflag = 0;
Index: src/Fragmentation/Automation/controller.cpp
===================================================================
--- src/Fragmentation/Automation/controller.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/controller.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -39,5 +39,5 @@
 #include "Controller/Commands/SendResultsOperation.hpp"
 #include "Controller/Commands/ShutdownOperation.hpp"
-#include "Jobs/FragmentJob.hpp"
+#include "Jobs/SystemCommandJob.hpp"
 #include "Results/FragmentResult.hpp"
 
@@ -52,6 +52,6 @@
 void createjobs(std::vector<FragmentJob::ptr> &jobs)
 {
-  FragmentJob::ptr testJob( new FragmentJob( std::string("cat"), std::string("Nothing"), 1) );
-  FragmentJob::ptr othertestJob( new FragmentJob( std::string("cat"), std::string("Nothing"), 2) );
+  FragmentJob::ptr testJob( new SystemCommandJob( std::string("cat"), std::string("Nothing"), 1) );
+  FragmentJob::ptr othertestJob( new SystemCommandJob( std::string("cat"), std::string("Nothing"), 2) );
   jobs.push_back(testJob);
   jobs.push_back(othertestJob);
Index: src/Fragmentation/Automation/unittests/FragmentJobUnitTest.cpp
===================================================================
--- src/Fragmentation/Automation/unittests/FragmentJobUnitTest.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/unittests/FragmentJobUnitTest.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -40,4 +40,6 @@
 /********************************************** Test classes **************************************/
 
+#include "stubs/FragmentJobStub.hpp"
+
 // Registers the fixture into the 'registry'
 CPPUNIT_TEST_SUITE_REGISTRATION( FragmentJobTest );
@@ -48,7 +50,4 @@
   // Throw assertions
   ASSERT_DO(Assert::Throw);
-
-  command = std::string("/bin/true");
-  outputfile = std::string("do something");
 }
 
@@ -62,15 +61,10 @@
 void FragmentJobTest::equalityTest()
 {
-  FragmentJob::ptr testJob(new FragmentJob(command, outputfile, 1));
-  FragmentJob::ptr sameIdJob(new FragmentJob(command, outputfile, 1));
-  FragmentJob::ptr otherIdJob(new FragmentJob(command, outputfile, 2));
-  FragmentJob::ptr copiedJob(new FragmentJob(*testJob));
-  FragmentJob::ptr copiedchangedJob(new FragmentJob(*testJob));
-  copiedchangedJob->setId(3);
+  FragmentJob::ptr testJob( new FragmentJobStub(1) );
+  FragmentJob::ptr sameIdJob( new FragmentJobStub(1) );
+  FragmentJob::ptr otherIdJob( new FragmentJobStub(2) );
 
   CPPUNIT_ASSERT( *testJob == *sameIdJob );
   CPPUNIT_ASSERT( *testJob != *otherIdJob );
-  CPPUNIT_ASSERT( *testJob == *copiedJob );
-  CPPUNIT_ASSERT( *testJob != *copiedchangedJob );
 }
 
@@ -79,6 +73,6 @@
 void FragmentJobTest::WorkTest()
 {
-  FragmentJob::ptr testJob(new FragmentJob(command, outputfile, 1));
-  FragmentJob::ptr othertestJob(new FragmentJob(command, outputfile, 2));
+  FragmentJob::ptr testJob( new FragmentJobStub(1) );
+  FragmentJob::ptr othertestJob( new FragmentJobStub(2) );
 
   FragmentResult::ptr testResult(testJob->Work());
@@ -93,5 +87,5 @@
 void FragmentJobTest::serializationTest()
 {
-  FragmentJob::ptr testJob(new FragmentJob(command, outputfile, 1));
+  FragmentJob::ptr testJob( new FragmentJobStub(1) );
   // write element to stream
   std::stringstream stream;
@@ -108,4 +102,5 @@
   ia >> otherJob;
 
+  // FragmentJobStub is same as FragmentJob contentwise, hence no casting required
   CPPUNIT_ASSERT (*testJob == *otherJob);
 }
Index: src/Fragmentation/Automation/unittests/FragmentQueueUnitTest.cpp
===================================================================
--- src/Fragmentation/Automation/unittests/FragmentQueueUnitTest.cpp	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/unittests/FragmentQueueUnitTest.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -36,4 +36,6 @@
 /********************************************** Test classes **************************************/
 
+#include "stubs/FragmentJobStub.hpp"
+
 // Registers the fixture into the 'registry'
 CPPUNIT_TEST_SUITE_REGISTRATION( FragmentQueueTest );
@@ -58,5 +60,5 @@
 void FragmentQueueTest::JobTest()
 {
-  FragmentJob::ptr testJob(new FragmentJob);
+  FragmentJob::ptr testJob(new FragmentJobStub(JobId::IllegalJob));
   /// check for illegal id
 #ifndef NDEBUG
@@ -66,5 +68,4 @@
   // set to valid id
   testJob->setId(1);
-  testJob->outputfile = std::string("do something");
 
   CPPUNIT_ASSERT_EQUAL(false, queue->isJobPresent() );
@@ -122,10 +123,8 @@
 {
   // prepare some jobs
-  FragmentJob::ptr testJob(new FragmentJob);
+  FragmentJob::ptr testJob(new FragmentJobStub(JobId::IllegalJob));
   testJob->setId((JobId_t)1);
-  testJob->outputfile = std::string("do something");
-  FragmentJob::ptr anothertestJob(new FragmentJob);
+  FragmentJob::ptr anothertestJob(new FragmentJobStub(JobId::IllegalJob));
   anothertestJob->setId((JobId_t)2);
-  anothertestJob->outputfile = std::string("do something else");
 
   // prepare a vector of them
@@ -173,7 +172,6 @@
 {
   // prepare a job
-  FragmentJob::ptr testJob(new FragmentJob);
+  FragmentJob::ptr testJob(new FragmentJobStub(JobId::IllegalJob));
   testJob->setId(1);
-  testJob->outputfile = std::string("do something");
 #ifndef NDEBUG
   CPPUNIT_ASSERT_NO_THROW( queue->pushJob(testJob) );
@@ -240,10 +238,8 @@
 {
   // prepare a job
-  FragmentJob::ptr testJob( new FragmentJob );
-  testJob->setId(1);
-  testJob->outputfile = std::string("do something");
-  FragmentJob::ptr anothertestJob( new FragmentJob );
-  anothertestJob->setId(2);
-  anothertestJob->outputfile = std::string("do something else");
+  FragmentJob::ptr testJob( new FragmentJobStub(JobId::IllegalJob) );
+  testJob->setId((JobId_t)1);
+  FragmentJob::ptr anothertestJob( new FragmentJobStub(JobId::IllegalJob) );
+  anothertestJob->setId((JobId_t)2);
 
 #ifndef NDEBUG
Index: src/Fragmentation/Automation/unittests/Makefile.am
===================================================================
--- src/Fragmentation/Automation/unittests/Makefile.am	(revision 7670865494307829aa075e60d6056fe423885484)
+++ src/Fragmentation/Automation/unittests/Makefile.am	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -5,15 +5,18 @@
   unittests/FragmentJobUnitTest.cpp \
   unittests/FragmentResultUnitTest.cpp \
-  unittests/FragmentQueueUnitTest.cpp
+  unittests/FragmentQueueUnitTest.cpp \
+  unittests/SystemCommandJobUnitTest.cpp
 
 FRAGMENTATIONAUTOMATIONTESTSHEADERS = \
   unittests/FragmentJobUnitTest.hpp \
   unittests/FragmentResultUnitTest.hpp \
-  unittests/FragmentQueueUnitTest.hpp
+  unittests/FragmentQueueUnitTest.hpp \
+  unittests/SystemCommandJobUnitTest.hpp
 
 FRAGMENTATIONAUTOMATIONTESTS = \
   FragmentJobUnitTest \
   FragmentResultUnitTest \
-  FragmentQueueUnitTest
+  FragmentQueueUnitTest \
+  SystemCommandJobUnitTest
 
 
@@ -35,4 +38,6 @@
   unittests/FragmentJobUnitTest.hpp \
   unittests/stubs/FragmentResultStub.cpp \
+  unittests/stubs/FragmentJobStub.cpp \
+  unittests/stubs/FragmentJobStub.hpp \
   JobId.cpp \
   JobId.hpp \
@@ -49,5 +54,7 @@
 FragmentQueueUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
   unittests/FragmentQueueUnitTest.cpp \
-  unittests/FragmentQueueUnitTest.hpp 
+  unittests/FragmentQueueUnitTest.hpp \
+  unittests/stubs/FragmentJobStub.cpp \
+  unittests/stubs/FragmentJobStub.hpp
 FragmentQueueUnitTest_LDADD = \
   libMolecuilderFragmentJobs.la \
@@ -67,4 +74,23 @@
   ${CodePatterns_LIBS}
 
+SystemCommandJobUnitTest_LDFLAGS = ${CodePatterns_LIBS} $(CPPUNIT_LIBS) -ldl
+SystemCommandJobUnitTest_CPPFLAGS = ${BOOST_CPPFLAGS} $(CPPUNIT_CFLAGS) ${CodePatterns_CFLAGS}
+SystemCommandJobUnitTest_SOURCES = $(top_srcdir)/src/unittests/UnitTestMain.cpp \
+  unittests/SystemCommandJobUnitTest.cpp \
+  unittests/SystemCommandJobUnitTest.hpp \
+  Results/FragmentResult.cpp \
+  Results/FragmentResult.hpp \
+  Jobs/FragmentJob.cpp \
+  Jobs/FragmentJob.hpp \
+  Jobs/SystemCommandJob.cpp \
+  Jobs/SystemCommandJob.hpp \
+  JobId.cpp \
+  JobId.hpp
+SystemCommandJobUnitTest_LDADD = \
+  $(BOOST_FILESYSTEM_LDFLAGS) $(BOOST_FILESYSTEM_LIBS) \
+  $(BOOST_IOSTREAMS_LDFLAGS) $(BOOST_IOSTREAMS_LIBS) \
+  $(BOOST_SERIALIZATION_LDFLAGS) $(BOOST_SERIALIZATION_LIBS) \
+  $(BOOST_SYSTEM_LDFLAGS) $(BOOST_SYSTEM_LIBS) \
+  ${CodePatterns_LIBS}
 
 #AUTOMAKE_OPTIONS = parallel-tests
Index: src/Fragmentation/Automation/unittests/SystemCommandJobUnitTest.cpp
===================================================================
--- src/Fragmentation/Automation/unittests/SystemCommandJobUnitTest.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
+++ src/Fragmentation/Automation/unittests/SystemCommandJobUnitTest.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+/*
+ * SystemCommandJobUnitTest.cpp
+ *
+ *  Created on: Oct 23, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+// include headers that implement a archive in simple text format
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "SystemCommandJobUnitTest.hpp"
+
+#include "Jobs/SystemCommandJob.hpp"
+#include "Results/FragmentResult.hpp"
+#include "JobId.hpp"
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+
+#ifdef HAVE_TESTRUNNER
+#include "UnitTestMain.hpp"
+#endif /*HAVE_TESTRUNNER*/
+
+/********************************************** Test classes **************************************/
+
+const std::string resultstring="nothing";
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( SystemCommandJobTest );
+
+
+void SystemCommandJobTest::setUp()
+{
+  // Throw assertions
+  ASSERT_DO(Assert::Throw);
+
+  setVerbosity(3);
+
+  command = std::string("/bin/true");
+  outputfile = std::string("do something");
+}
+
+
+void SystemCommandJobTest::tearDown()
+{
+}
+
+/** UnitTest for operator==
+ */
+void SystemCommandJobTest::equalityTest()
+{
+  FragmentJob::ptr testJob( new SystemCommandJob(command, outputfile, 1) );
+  FragmentJob::ptr sameIdJob( new SystemCommandJob(command, outputfile, 1) );
+  FragmentJob::ptr otherIdJob( new SystemCommandJob(command, outputfile, 2) );
+
+  CPPUNIT_ASSERT( *testJob == *sameIdJob );
+  CPPUNIT_ASSERT( *testJob != *otherIdJob );
+}
+
+/** UnitTest for Work()
+ */
+void SystemCommandJobTest::WorkTest()
+{
+  FragmentJob::ptr testJob( new SystemCommandJob(command, outputfile, 1) );
+  FragmentJob::ptr othertestJob( new SystemCommandJob(command, outputfile, 2) );
+
+  FragmentResult::ptr testResult(testJob->Work());
+  FragmentResult::ptr othertestResult(othertestJob->Work());
+
+  CPPUNIT_ASSERT_EQUAL( (JobId_t)1, testResult->getId() );
+  CPPUNIT_ASSERT_EQUAL( (JobId_t)2, othertestResult->getId() );
+}
+
+/** UnitTest for serialization
+ */
+void SystemCommandJobTest::serializationTest()
+{
+  FragmentJob::ptr testJob( new SystemCommandJob(command, outputfile, 1) );
+  // write element to stream
+  std::stringstream stream;
+  boost::archive::text_oarchive oa(stream);
+  oa << testJob;
+
+  //std::cout << "Contents of archive is " << stream.str() << std::endl;
+
+  // create and open an archive for input
+  boost::archive::text_iarchive ia(stream);
+  // read class state from archive
+  FragmentJob::ptr otherJob;
+
+  ia >> otherJob;
+
+  const FragmentJob * const testJobptr = testJob.get();
+  const FragmentJob * const otherJobptr = otherJob.get();
+  const SystemCommandJob * const testSystemJobptr =
+      dynamic_cast<const SystemCommandJob *>(testJobptr);
+  const SystemCommandJob * const otherSystemJobptr =
+      dynamic_cast<const SystemCommandJob *>(otherJobptr);
+  CPPUNIT_ASSERT( testSystemJobptr != NULL );
+  CPPUNIT_ASSERT( otherSystemJobptr != NULL );
+  CPPUNIT_ASSERT( *testSystemJobptr == *otherSystemJobptr);
+  // short is the following
+  CPPUNIT_ASSERT( *dynamic_cast<const SystemCommandJob *>(testJob.get())
+      == *dynamic_cast<const SystemCommandJob *>(otherJob.get()) );
+}
+
+/** UnitTest for extractString()
+ */
+void SystemCommandJobTest::extractStringTest()
+{
+  SystemCommandJob testJob(command, outputfile, 1);
+  // extract and check that it just returns the string
+  FragmentResult::ptr result = testJob.extractResult(resultstring);
+
+  CPPUNIT_ASSERT( result->result == resultstring );
+}
Index: src/Fragmentation/Automation/unittests/SystemCommandJobUnitTest.hpp
===================================================================
--- src/Fragmentation/Automation/unittests/SystemCommandJobUnitTest.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
+++ src/Fragmentation/Automation/unittests/SystemCommandJobUnitTest.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -0,0 +1,45 @@
+/*
+ * SystemCommandJobUnitTest.hpp
+ *
+ *  Created on: Oct 23, 2011
+ *      Author: heber
+ */
+
+#ifndef SYSTEMCOMMANDJOBUNITTEST_HPP_
+#define SYSTEMCOMMANDJOBUNITTEST_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <cppunit/extensions/HelperMacros.h>
+
+/********************************************** Test classes **************************************/
+
+class SystemCommandJobTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( SystemCommandJobTest) ;
+    CPPUNIT_TEST ( equalityTest );
+    CPPUNIT_TEST ( serializationTest );
+    CPPUNIT_TEST ( WorkTest );
+    CPPUNIT_TEST ( extractStringTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void equalityTest();
+      void serializationTest();
+      void WorkTest();
+      void extractStringTest();
+
+private:
+      std::string command;
+      std::string outputfile;
+
+};
+
+#endif /* SYSTEMCOMMANDJOBUNITTEST_HPP_ */
Index: src/Fragmentation/Automation/unittests/stubs/FragmentJobStub.cpp
===================================================================
--- src/Fragmentation/Automation/unittests/stubs/FragmentJobStub.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
+++ src/Fragmentation/Automation/unittests/stubs/FragmentJobStub.cpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/*
+ * FragmentJobStub.cpp
+ *
+ *  Created on: Feb 06, 2012
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+// include headers that implement a archive in simple text format
+// otherwise BOOST_CLASS_EXPORT_IMPLEMENT has no effect
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "FragmentJobStub.hpp"
+
+#include "Results/FragmentResult.hpp"
+#include "JobId.hpp"
+
+FragmentJobStub::FragmentJobStub(const JobId_t _JobId) :
+  FragmentJob(_JobId)
+{}
+
+FragmentResult::ptr FragmentJobStub::Work() {
+  return FragmentResult::ptr( new FragmentResult(getId()) );
+}
+
+//!> private default cstor for serialization only
+FragmentJobStub::FragmentJobStub() :
+  FragmentJob(JobId::IllegalJob)
+{}
+
+// we need to explicitly instantiate the serialization functions as
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_IMPLEMENT(FragmentJobStub)
+
Index: src/Fragmentation/Automation/unittests/stubs/FragmentJobStub.hpp
===================================================================
--- src/Fragmentation/Automation/unittests/stubs/FragmentJobStub.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
+++ src/Fragmentation/Automation/unittests/stubs/FragmentJobStub.hpp	(revision d920b9e35d1332c01a14e561aa60b85bbe881b3b)
@@ -0,0 +1,43 @@
+/*
+ * FragmentJobStub.hpp
+ *
+ *  Created on: Feb 06, 2012
+ *      Author: heber
+ */
+
+#ifndef FRAGMENTJOBSTUB_HPP_
+#define FRAGMENTJOBSTUB_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "boost/serialization/export.hpp"
+
+#include "Jobs/FragmentJob.hpp"
+
+struct FragmentJobStub : public FragmentJob
+{
+  FragmentJobStub(const JobId_t _JobId);
+
+  FragmentResult::ptr Work();
+
+private:
+  //!> private default cstor for serialization only
+  FragmentJobStub();
+
+  friend class boost::serialization::access;
+  // serialization
+  template <typename Archive>
+  void serialize(Archive& ar, const unsigned int version)
+  {
+    ar & boost::serialization::base_object<FragmentJob>(*this);
+  }
+};
+
+// we need to give this class a unique key for serialization
+// its is only serialized through its base class FragmentJob
+BOOST_CLASS_EXPORT_KEY(FragmentJobStub)
+
+#endif /* FRAGMENTJOBSTUB_HPP_ */
