Index: src/Actions/SelectionAction/Atoms/AtomByIdAction.cpp
===================================================================
--- src/Actions/SelectionAction/Atoms/AtomByIdAction.cpp	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ src/Actions/SelectionAction/Atoms/AtomByIdAction.cpp	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -52,17 +52,48 @@
 #include "Action_impl_pre.hpp"
 /** =========== define the function ====================== */
-Action::state_ptr SelectionAtomByIdAction::performCall() {
-  const atom *Walker = World::getInstance().getAtom(AtomById(params.WalkerId.get()));
-  if (Walker != NULL) {
-    if (!World::getInstance().isSelected(Walker)) {
-      LOG(1, "Selecting atom " << *Walker);
-      World::getInstance().selectAtom(Walker);
-      LOG(0, World::getInstance().countSelectedAtoms() << " atoms selected.");
-      return Action::state_ptr(new SelectionAtomByIdState(params));
+Action::state_ptr SelectionAtomByIdAction::performCall()
+{
+  enum Sucess {
+    NoStatus,
+    AllAtomsUnselected,
+    AtomsSelected,
+    AtomMissing
+  } status = NoStatus;
+  const atomids_t atomids = params.atomids.get();
+  atomids_t undoatomids;
+  undoatomids.reserve(atomids.size());
+  for (atomids_t::const_iterator iter = atomids.begin(); iter != atomids.end(); ++iter) {
+    const atom *Walker = World::getInstance().getAtom(AtomById(*iter));
+    if (Walker != NULL) {
+      if (!World::getInstance().isSelected(Walker)) {
+        LOG(1, "Selecting atom " << *Walker);
+        World::getInstance().selectAtom(Walker);
+        undoatomids.push_back(*iter);
+        if (status < AtomMissing)
+          status = AtomsSelected;
+      } else {
+        if (status == NoStatus)
+          status = AllAtomsUnselected;
+      }
     } else {
+      status = AtomMissing;
+    }
+  }
+  LOG(0, World::getInstance().countSelectedAtoms() << " atoms selected.");
+
+  switch (status) {
+    case AtomMissing:
+      return Action::failure;
+      break;
+    case AllAtomsUnselected:
       return Action::success;
-    }
-  } else {
-    return Action::failure;
+      break;
+    case AtomsSelected:
+      return Action::state_ptr(new SelectionAtomByIdState(undoatomids, params));
+      break;
+    default:
+      ASSERT(0, "SelectionAtomByIdAction::performCall() - this must not happen.");
+      return Action::failure;
+      break;
   }
 }
@@ -71,6 +102,9 @@
   SelectionAtomByIdState *state = assert_cast<SelectionAtomByIdState*>(_state.get());
 
-  const atom *Walker = World::getInstance().getAtom(AtomById(state->params.WalkerId.get()));
-  World::getInstance().unselectAtom(Walker);
+  for (atomids_t::const_iterator iter = state->undoatomids.begin();
+      iter != state->undoatomids.end(); ++iter) {
+    const atom *Walker = World::getInstance().getAtom(AtomById(*iter));
+    World::getInstance().unselectAtom(Walker);
+  }
 
   return Action::state_ptr(_state);
@@ -80,6 +114,9 @@
   SelectionAtomByIdState *state = assert_cast<SelectionAtomByIdState*>(_state.get());
 
-  const atom *Walker = World::getInstance().getAtom(AtomById(state->params.WalkerId.get()));
-  World::getInstance().selectAtom(Walker);
+  for (atomids_t::const_iterator iter = state->undoatomids.begin();
+      iter != state->undoatomids.end(); ++iter) {
+    const atom *Walker = World::getInstance().getAtom(AtomById(*iter));
+    World::getInstance().selectAtom(Walker);
+  }
 
   return Action::state_ptr(_state);
Index: src/Actions/SelectionAction/Atoms/AtomByIdAction.def
===================================================================
--- src/Actions/SelectionAction/Atoms/AtomByIdAction.def	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ src/Actions/SelectionAction/Atoms/AtomByIdAction.def	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -7,6 +7,10 @@
 
 // all includes and forward declarations necessary for non-integral types below
-class atom;
+#include <vector>
+#include "types.hpp"
 
+typedef std::vector<atomId_t> atomids_t;
+
+#include "Parameters/Validators/STLVectorValidator.hpp"
 #include "Parameters/Validators/Specific/AtomIdValidator.hpp"
 
@@ -14,14 +18,15 @@
 // ValueStorage by the token "Z" -> first column: int, Z, "Z"
 // "undefine" if no parameters are required, use (NOPARAM_DEFAULT) for each (undefined) default value
-#define paramtypes (atomId_t)
+#define paramtypes (atomids_t)
 #define paramtokens ("select-atom-by-id")
-#define paramdescriptions ("atom index")
+#define paramdescriptions ("atom indices to select")
 #undef paramdefaults
-#define paramreferences (WalkerId)
+#define paramreferences (atomids)
 #define paramvalids \
-(AtomIdValidator())
+(STLVectorValidator< std::vector<atomId_t> >(AtomIdValidator()))
 
-#undef statetypes
-#undef statereferences
+
+#define statetypes (atomids_t)
+#define statereferences (undoatomids)
 
 // some defines for all the names, you may use ACTION, STATE and PARAMS
@@ -34,4 +39,4 @@
 
 // finally the information stored in the ActionTrait specialization
-#define DESCRIPTION "select an atom by index"
+#define DESCRIPTION "select atom(s) by index"
 #undef SHORTFORM
Index: src/Actions/SelectionAction/Atoms/NotAtomByIdAction.cpp
===================================================================
--- src/Actions/SelectionAction/Atoms/NotAtomByIdAction.cpp	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ src/Actions/SelectionAction/Atoms/NotAtomByIdAction.cpp	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -52,17 +52,48 @@
 #include "Action_impl_pre.hpp"
 /** =========== define the function ====================== */
-Action::state_ptr SelectionNotAtomByIdAction::performCall() {
-  const atom * Walker = World::getInstance().getAtom(AtomById(params.WalkerId.get()));
-  if (Walker != NULL) {
-    if (World::getInstance().isSelected(Walker)) {
-      LOG(1, "Unselecting atom " << *Walker);
-      World::getInstance().unselectAtom(Walker);
-      LOG(0, World::getInstance().countSelectedAtoms() << " atoms remain selected.");
-      return Action::state_ptr(new SelectionNotAtomByIdState(params));
+Action::state_ptr SelectionNotAtomByIdAction::performCall()
+{
+  enum Sucess {
+    NoStatus,
+    AllAtomsSelected,
+    AtomsUnselected,
+    AtomMissing
+  } status = NoStatus;
+  const atomids_t atomids = params.atomids.get();
+  atomids_t undoatomids;
+  undoatomids.reserve(atomids.size());
+  for (atomids_t::const_iterator iter = atomids.begin(); iter != atomids.end(); ++iter) {
+    const atom *Walker = World::getInstance().getAtom(AtomById(*iter));
+    if (Walker != NULL) {
+      if (World::getInstance().isSelected(Walker)) {
+        LOG(1, "Unselecting atom " << *Walker);
+        World::getInstance().unselectAtom(Walker);
+        undoatomids.push_back(*iter);
+        if (status < AtomMissing)
+          status = AtomsUnselected;
+      } else {
+        if (status == NoStatus)
+          status = AllAtomsSelected;
+      }
     } else {
+      status = AtomMissing;
+    }
+  }
+  LOG(0, World::getInstance().countSelectedAtoms() << " atoms remain selected.");
+
+  switch (status) {
+    case AtomMissing:
+      return Action::failure;
+      break;
+    case AllAtomsSelected:
       return Action::success;
-    }
-  } else {
-    return Action::failure;
+      break;
+    case AtomsUnselected:
+      return Action::state_ptr(new SelectionNotAtomByIdState(undoatomids, params));
+      break;
+    default:
+      ASSERT(0, "SelectionAtomByIdAction::performCall() - this must not happen.");
+      return Action::failure;
+      break;
   }
 }
@@ -71,6 +102,9 @@
   SelectionNotAtomByIdState *state = assert_cast<SelectionNotAtomByIdState*>(_state.get());
 
-  const atom * Walker = World::getInstance().getAtom(AtomById(state->params.WalkerId.get()));
-  World::getInstance().selectAtom(Walker);
+  for (atomids_t::const_iterator iter = state->undoatomids.begin();
+      iter != state->undoatomids.end(); ++iter) {
+    const atom *Walker = World::getInstance().getAtom(AtomById(*iter));
+    World::getInstance().selectAtom(Walker);
+  }
 
   return Action::state_ptr(_state);
@@ -80,6 +114,9 @@
   SelectionNotAtomByIdState *state = assert_cast<SelectionNotAtomByIdState*>(_state.get());
 
-  const atom * Walker = World::getInstance().getAtom(AtomById(state->params.WalkerId.get()));
-  World::getInstance().unselectAtom(Walker);
+  for (atomids_t::const_iterator iter = state->undoatomids.begin();
+      iter != state->undoatomids.end(); ++iter) {
+    const atom *Walker = World::getInstance().getAtom(AtomById(*iter));
+    World::getInstance().unselectAtom(Walker);
+  }
 
   return Action::state_ptr(_state);
Index: src/Actions/SelectionAction/Atoms/NotAtomByIdAction.def
===================================================================
--- src/Actions/SelectionAction/Atoms/NotAtomByIdAction.def	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ src/Actions/SelectionAction/Atoms/NotAtomByIdAction.def	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -7,6 +7,10 @@
 
 // all includes and forward declarations necessary for non-integral types below
-class atom;
+#include <vector>
+#include "types.hpp"
 
+typedef std::vector<atomId_t> atomids_t;
+
+#include "Parameters/Validators/STLVectorValidator.hpp"
 #include "Parameters/Validators/Specific/AtomIdValidator.hpp"
 
@@ -14,14 +18,15 @@
 // ValueStorage by the token "Z" -> first column: int, Z, "Z"
 // "undefine" if no parameters are required, use (NOPARAM_DEFAULT) for each (undefined) default value
-#define paramtypes (atomId_t)
+#define paramtypes (atomids_t)
 #define paramtokens ("unselect-atom-by-id")
-#define paramdescriptions ("atom index")
+#define paramdescriptions ("atom indices to unselect")
 #undef paramdefaults
-#define paramreferences (WalkerId)
+#define paramreferences (atomids)
 #define paramvalids \
-(AtomIdValidator())
+(STLVectorValidator< std::vector<atomId_t> >(AtomIdValidator()))
 
-#undef statetypes
-#undef statereferences
+
+#define statetypes (atomids_t)
+#define statereferences (undoatomids)
 
 // some defines for all the names, you may use ACTION, STATE and PARAMS
Index: src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp
===================================================================
--- src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -321,7 +321,7 @@
    if (selectionMode == SelectAtom){
      if (!World::getInstance().isSelected(Walker))
-       SelectionAtomById(no);
+       SelectionAtomById(std::vector<atomId_t>(1,no));
      else
-       SelectionNotAtomById(no);
+       SelectionNotAtomById(std::vector<atomId_t>(1,no));
    }else if (selectionMode == SelectMolecule){
      const molecule *mol = Walker->getMolecule();
Index: tests/regression/Makefile.am
===================================================================
--- tests/regression/Makefile.am	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ tests/regression/Makefile.am	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -161,5 +161,7 @@
 	$(srcdir)/Selection/Atoms/AtomByElement/testsuite-selection-unselect-atoms-by-element.at \
 	$(srcdir)/Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id.at \
+	$(srcdir)/Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id-multiple.at \
 	$(srcdir)/Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id.at \
+	$(srcdir)/Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id-multiple.at \
 	$(srcdir)/Selection/Atoms/AtomByOrder/testsuite-selection-select-atom-by-order.at \
 	$(srcdir)/Selection/Atoms/AtomByOrder/testsuite-selection-unselect-atom-by-order.at \
Index: tests/regression/Selection/Atoms/AtomById/post/id01_missing.xyz
===================================================================
--- tests/regression/Selection/Atoms/AtomById/post/id01_missing.xyz	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
+++ tests/regression/Selection/Atoms/AtomById/post/id01_missing.xyz	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -0,0 +1,8 @@
+6
+	Created by molecuilder for select-atom-by-id
+H	0	1	0
+H	0	1	1
+H	1	0	0
+H	1	0	1
+H	1	1	0
+H	1	1	1
Index: tests/regression/Selection/Atoms/AtomById/post/id01_present.xyz
===================================================================
--- tests/regression/Selection/Atoms/AtomById/post/id01_present.xyz	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
+++ tests/regression/Selection/Atoms/AtomById/post/id01_present.xyz	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -0,0 +1,4 @@
+2
+	Created by molecuilder for unselect-atom-by-id
+H	0	0	0
+H	0	0	1
Index: tests/regression/Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id-multiple.at
===================================================================
--- tests/regression/Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id-multiple.at	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
+++ tests/regression/Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id-multiple.at	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -0,0 +1,64 @@
+#
+#    MoleCuilder - creates and alters molecular systems
+#    Copyright (C) 2008-2012 University of Bonn
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+#    MoleCuilder - creates and alters molecular systems
+#    Copyright (C) 2008-2012 University of Bonn
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+### 6. (un)select atom by id
+
+AT_SETUP([Selection - atoms with specific id])
+AT_KEYWORDS([selection id atom select-atom-by-id])
+file=id01_missing.xyz
+AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/pre/test.xyz $file])
+AT_CHECK([chmod u+w $file], 0)
+AT_CHECK([../../molecuilder -i $file -v 3 --select-atom-by-id 0 1 -r], [], [ignore], [ignore])
+AT_CHECK([diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/post/$file])
+AT_CLEANUP
+
+
+AT_SETUP([Selection - atoms with specific id with Undo])
+AT_KEYWORDS([selection id atom select-atom-by-id undo])
+file=all.xyz
+AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/pre/test.xyz $file])
+AT_CHECK([chmod u+w $file], 0)
+AT_CHECK([../../molecuilder -i $file -v 3 --select-atom-by-id 0 1 --undo -r], [], [ignore], [ignore])
+AT_CHECK([diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/post/test-undo.xyz])
+AT_CLEANUP
+
+
+AT_SETUP([Selection - atoms with specific id with Redo])
+AT_KEYWORDS([selection id atom select-atom-by-id redo])
+file=id01_missing.xyz
+AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/pre/test.xyz $file])
+AT_CHECK([chmod u+w $file], 0)
+AT_CHECK([../../molecuilder -i $file -v 3 --select-atom-by-id 0 1 --undo --redo -r], [], [ignore], [ignore])
+AT_CHECK([diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/post/$file])
+AT_CLEANUP
Index: tests/regression/Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id-multiple.at
===================================================================
--- tests/regression/Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id-multiple.at	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
+++ tests/regression/Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id-multiple.at	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -0,0 +1,65 @@
+#
+#    MoleCuilder - creates and alters molecular systems
+#    Copyright (C) 2008-2012 University of Bonn
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+#    MoleCuilder - creates and alters molecular systems
+#    Copyright (C) 2008-2012 University of Bonn
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+### 6. (un)select atom by id
+
+
+AT_SETUP([Unselection - atoms with specific id])
+AT_KEYWORDS([unselection id atom unselect-atom-by-id])
+file=id01_present.xyz
+AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/pre/test.xyz $file])
+AT_CHECK([chmod u+w $file], 0)
+AT_CHECK([../../molecuilder -i $file -v 3 --select-all-atoms --unselect-atom-by-id 0 1 -r], [], [ignore], [ignore])
+AT_CHECK([diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/post/$file])
+AT_CLEANUP
+
+
+AT_SETUP([Unselection - atoms with specific id with Undo])
+AT_KEYWORDS([unselection id atom unselect-atom-by-id undo])
+file=all.xyz
+AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/pre/test.xyz $file])
+AT_CHECK([chmod u+w $file], 0)
+AT_CHECK([../../molecuilder -i $file -v 3 --select-all-atoms --unselect-atom-by-id 0 1 --undo -r], [], [ignore], [ignore])
+AT_CHECK([diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/post/empty.xyz])
+AT_CLEANUP
+
+
+AT_SETUP([Unselection - atoms with specific id with Redo])
+AT_KEYWORDS([unselection id atom unselect-atom-by-id redo])
+file=id01_present.xyz
+AT_CHECK([/bin/cp -f ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/pre/test.xyz $file])
+AT_CHECK([chmod u+w $file], 0)
+AT_CHECK([../../molecuilder -i $file -v 3 --select-all-atoms --unselect-atom-by-id 0 1 --undo --redo -r], [], [ignore], [ignore])
+AT_CHECK([diff -I '.*Created by molecuilder.*' $file ${abs_top_srcdir}/tests/regression/Selection/Atoms/AtomById/post/$file])
+AT_CLEANUP
Index: tests/regression/Selection/Atoms/testsuite-selection-atoms.at
===================================================================
--- tests/regression/Selection/Atoms/testsuite-selection-atoms.at	(revision 3a51bd61d13a71ec61cf8dd25196d15612bdfe3e)
+++ tests/regression/Selection/Atoms/testsuite-selection-atoms.at	(revision f7c7cf132d69c7077ffd2cc11e7348c672217c01)
@@ -51,5 +51,7 @@
 # (un)select atom by id
 m4_include(Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id.at)
+m4_include(Selection/Atoms/AtomById/testsuite-selection-select-atom-by-id-multiple.at)
 m4_include(Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id.at)
+m4_include(Selection/Atoms/AtomById/testsuite-selection-unselect-atom-by-id-multiple.at)
 
 # (un)select atom by order
