Index: src/unittests/Makefile.am
===================================================================
--- src/unittests/Makefile.am	(revision afb47f9975466cee3a9f4f362aa7bf8f6944ffd4)
+++ src/unittests/Makefile.am	(revision b54ac804770af8e83f6b370746a4c0eba37f99f5)
@@ -31,4 +31,5 @@
   DescriptorUnittest \
   manipulateAtomsTest \
+  atomsCalculationTest \
   ${MENUTESTS}  
     
@@ -115,4 +116,7 @@
 manipulateAtomsTest_LDADD = ${ALLLIBS}
 
+atomsCalculationTest_SOURCES = atomsCalculationTest.cpp atomsCalculationTest.hpp
+atomsCalculationTest_LDADD = ${ALLLIBS}
+
 #AUTOMAKE_OPTIONS = parallel-tests
 
Index: src/unittests/atomsCalculationTest.cpp
===================================================================
--- src/unittests/atomsCalculationTest.cpp	(revision b54ac804770af8e83f6b370746a4c0eba37f99f5)
+++ src/unittests/atomsCalculationTest.cpp	(revision b54ac804770af8e83f6b370746a4c0eba37f99f5)
@@ -0,0 +1,140 @@
+/*
+ * atomsCalculationTest.cpp
+ *
+ *  Created on: Feb 19, 2010
+ *      Author: crueger
+ */
+
+#include "atomsCalculationTest.hpp"
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <iostream>
+#include <boost/bind.hpp>
+
+#include "Descriptors/AtomDescriptor.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "Actions/AtomsCalculation.hpp"
+#include "Actions/AtomsCalculation_impl.hpp"
+#include "Actions/ActionRegistry.hpp"
+
+#include "World.hpp"
+#include "World_calculations.hpp"
+#include "atom.hpp"
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( atomsCalculationTest );
+
+// some stubs
+class AtomStub : public atom {
+public:
+  AtomStub(int _id) :
+  atom(),
+  id(_id),
+  manipulated(false)
+  {}
+
+  virtual int getId(){
+    return id;
+  }
+
+  virtual void doSomething(){
+    manipulated = true;
+  }
+
+  bool manipulated;
+private:
+  int id;
+};
+
+// set up and tear down
+void atomsCalculationTest::setUp(){
+  World::get();
+  for(int i=0;i<ATOM_COUNT;++i){
+    atoms[i]= new AtomStub(i);
+  }
+}
+void atomsCalculationTest::tearDown(){
+  World::destroy();
+  for(int i=0;i<ATOM_COUNT;++i){
+    delete atoms[i];
+  }
+  ActionRegistry::purgeRegistry();
+}
+
+// some helper functions
+bool hasAll(std::vector<int> ids,int min, int max, std::set<int> excluded = std::set<int>()){
+  for(int i=min;i<max;++i){
+    if(!excluded.count(i)){
+      std::vector<int>::iterator iter;
+      bool res=false;
+      for(iter=ids.begin();iter!=ids.end();++iter){
+        res |= (*iter) == i;
+      }
+      if(!res) {
+        cout << "Atom " << i << " missing in returned list" << endl;
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool hasNoDuplicates(std::vector<int> ids){
+  std::set<int> found;
+  std::vector<int>::iterator iter;
+  for(iter=ids.begin();iter!=ids.end();++iter){
+    int id = (*iter);
+    if(found.count(id))
+      return false;
+    found.insert(id);
+  }
+  return true;
+}
+
+void operation(atom* _atom){
+  AtomStub *atom = dynamic_cast<AtomStub*>(_atom);
+  assert(atom);
+  atom->doSomething();
+}
+
+
+void atomsCalculationTest::testCalculateSimple(){
+  AtomsCalculation<int> *calc = World::get()->calcOnAtoms<int>(boost::bind(&atom::getId,_1),"FOO",AllAtoms());
+  std::vector<int> allIds = (*calc)();
+  CPPUNIT_ASSERT(hasAll(allIds,0,ATOM_COUNT));
+  CPPUNIT_ASSERT(hasNoDuplicates(allIds));
+}
+
+void atomsCalculationTest::testCalculateExcluded(){
+  int excluded = ATOM_COUNT/2;
+  AtomsCalculation<int> *calc = World::get()->calcOnAtoms<int>(boost::bind(&atom::getId,_1),"FOO",AllAtoms() && !AtomById(excluded));
+  std::vector<int> allIds = (*calc)();
+  std::set<int> excluded_set;
+  excluded_set.insert(excluded);
+  CPPUNIT_ASSERT(hasAll(allIds,0,ATOM_COUNT,excluded_set));
+  CPPUNIT_ASSERT(hasNoDuplicates(allIds));
+  CPPUNIT_ASSERT_EQUAL((size_t)(ATOM_COUNT-1),allIds.size());
+}
+
+/********************************************** Main routine **************************************/
+
+int main(int argc, char **argv)
+{
+  // Get the top level suite from the registry
+  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+  // Adds the test to the list of test to run
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( suite );
+
+  // Change the default outputter to a compiler error format outputter
+  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+                                                       std::cerr ) );
+  // Run the tests.
+  bool wasSucessful = runner.run();
+
+  // Return error code 1 if the one of test failed.
+  return wasSucessful ? 0 : 1;
+};
Index: src/unittests/atomsCalculationTest.hpp
===================================================================
--- src/unittests/atomsCalculationTest.hpp	(revision b54ac804770af8e83f6b370746a4c0eba37f99f5)
+++ src/unittests/atomsCalculationTest.hpp	(revision b54ac804770af8e83f6b370746a4c0eba37f99f5)
@@ -0,0 +1,35 @@
+/*
+ * atomsCalculationTest.hpp
+ *
+ *  Created on: Feb 19, 2010
+ *      Author: crueger
+ */
+
+#ifndef ATOMSCALCULATIONTEST_HPP_
+#define ATOMSCALCULATIONTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#define ATOM_COUNT (10)
+
+class atom;
+
+class atomsCalculationTest :  public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( atomsCalculationTest );
+  CPPUNIT_TEST ( testCalculateSimple );
+  CPPUNIT_TEST ( testCalculateExcluded );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void testCalculateSimple();
+  void testCalculateExcluded();
+
+private:
+  atom *atoms [ATOM_COUNT];
+};
+
+#endif /* ATOMSCALCULATIONTEST_HPP_ */
Index: src/unittests/manipulateAtomsTest.cpp
===================================================================
--- src/unittests/manipulateAtomsTest.cpp	(revision afb47f9975466cee3a9f4f362aa7bf8f6944ffd4)
+++ src/unittests/manipulateAtomsTest.cpp	(revision b54ac804770af8e83f6b370746a4c0eba37f99f5)
@@ -7,6 +7,4 @@
 
 #include "manipulateAtomsTest.hpp"
-
-#include "DescriptorUnittest.hpp"
 
 #include <cppunit/CompilerOutputter.h>
