Index: src/Actions/BondAction/BondSetDegreeAction.cpp
===================================================================
--- src/Actions/BondAction/BondSetDegreeAction.cpp	(revision 596aacf191b75128e8e86114dda85fb17b792e44)
+++ src/Actions/BondAction/BondSetDegreeAction.cpp	(revision 596aacf191b75128e8e86114dda85fb17b792e44)
@@ -0,0 +1,174 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2016 Frederik Heber. All rights reserved.
+ * 
+ *
+ *   This file is part of MoleCuilder.
+ *
+ *    MoleCuilder 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 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    MoleCuilder 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 MoleCuilder.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * BondSetDegreeAction.cpp
+ *
+ *  Created on: Oct 01, 2016
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "Atom/atom.hpp"
+#include "Bond/bond.hpp"
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+#include "CodePatterns/Verbose.hpp"
+#include "Descriptors/AtomIdDescriptor.hpp"
+#include "World.hpp"
+#include "WorldTime.hpp"
+
+#include <iostream>
+#include <string>
+
+#include "Actions/BondAction/BondSetDegreeAction.hpp"
+
+using namespace MoleCuilder;
+
+// and construct the stuff
+#include "BondSetDegreeAction.def"
+#include "Action_impl_pre.hpp"
+/** =========== define the function ====================== */
+ActionState::ptr BondSetDegreeAction::performCall() {
+  // check preconditions
+  World& world = World::getInstance();
+  if (world.countSelectedAtoms() <= 1) {
+    ELOG(1, "There must be at least two atoms selected for BondSetDegreeAction.");
+    return Action::failure;
+  }
+  for (World::AtomSelectionConstIterator firstiter = world.beginAtomSelection();
+      firstiter != world.endAtomSelection(); ++firstiter) {
+    bool status = false;
+    for (World::AtomSelectionConstIterator seconditer = world.beginAtomSelection();
+        seconditer != world.endAtomSelection(); ++seconditer) {
+      if (firstiter == seconditer)
+        continue;
+      if ((firstiter->second)->IsBondedTo(WorldTime::getTime(), seconditer->second)) {
+        status = true;
+      }
+    }
+    if (!status) {
+      ELOG(1, "Selected atom #" << firstiter->second->getId() << " has no bonds.");
+      return Action::failure;
+    }
+  }
+
+  // store current degrees in vector
+  BondDegrees_t BondDegrees;
+  for (World::AtomSelectionConstIterator firstiter = world.beginAtomSelection();
+      firstiter != world.endAtomSelection(); ++firstiter) {
+    for (World::AtomSelectionConstIterator seconditer = firstiter;
+        seconditer != world.endAtomSelection(); ++seconditer) {
+      if (firstiter == seconditer)
+        continue;
+      if ((firstiter->second)->IsBondedTo(WorldTime::getTime(), seconditer->second)) {
+        bond::ptr bond = (firstiter->second)->getBond(seconditer->second);
+        BondInfo bondinfo(bond);
+        BondDegrees.push_back( bondinfo );
+      }
+    }
+  }
+  if (BondDegrees.empty()) {
+    ELOG(1, "All bonds are already present.");
+    return Action::failure;
+  }
+
+  // create undo state
+  BondSetDegreeState *UndoState = new BondSetDegreeState(BondDegrees, params);
+
+  // execute action
+  for (BondDegrees_t::const_iterator iter = BondDegrees.begin();
+      iter != BondDegrees.end(); ++iter) {
+    atom *firstatom = world.getAtom(AtomById((*iter).leftid));
+    atom *secondatom = world.getAtom(AtomById((*iter).rightid));
+    ASSERT((firstatom != NULL) && (secondatom != NULL),
+        "BondSetDegreeAction::performCall() - at least one of the ids "
+        +toString((*iter).leftid)+" or "+toString((*iter).rightid)+" is not present.");
+    const bond::ptr bond = firstatom->getBond(secondatom);
+    bond->setDegree(params.degree.get());
+  }
+
+  return ActionState::ptr(UndoState);
+}
+
+ActionState::ptr BondSetDegreeAction::performUndo(ActionState::ptr _state) {
+  BondSetDegreeState *state = assert_cast<BondSetDegreeState*>(_state.get());
+
+  // check whether bond already existed
+  World& world = World::getInstance();
+  for (BondDegrees_t::const_iterator iter = state->bonddegrees.begin();
+      iter != state->bonddegrees.end(); ++iter) {
+    atom *firstatom = world.getAtom(AtomById((*iter).leftid));
+    atom *secondatom = world.getAtom(AtomById((*iter).rightid));
+    ASSERT((firstatom != NULL) && (secondatom != NULL),
+        "BondSetDegreeAction::performUndo() - at least one of the ids "
+        +toString((*iter).leftid)+" or "+toString((*iter).rightid)+" is not present.");
+    if (firstatom->IsBondedTo(WorldTime::getTime(), secondatom)) {
+      const bond::ptr bond = firstatom->getBond(secondatom);
+      bond->setDegree((*iter).degree);
+    } else {
+      ELOG(2, "There is no bond in between "+toString((*iter).leftid)
+          +" and "+toString((*iter).rightid)+".");
+    }
+  }
+
+  return ActionState::ptr(_state);
+}
+
+ActionState::ptr BondSetDegreeAction::performRedo(ActionState::ptr _state){
+  BondSetDegreeState *state = assert_cast<BondSetDegreeState*>(_state.get());
+
+  // check whether bond already existed
+  World& world = World::getInstance();
+  for (BondDegrees_t::const_iterator iter = state->bonddegrees.begin();
+      iter != state->bonddegrees.end(); ++iter) {
+    atom * const firstatom = world.getAtom(AtomById((*iter).leftid));
+    atom * const secondatom = world.getAtom(AtomById((*iter).rightid));
+    ASSERT((firstatom != NULL) && (secondatom != NULL),
+        "BondSetDegreeAction::performRedo() - at least one of the ids "
+        +toString((*iter).leftid)+" or "+toString((*iter).rightid)+" is not present.");
+    if (firstatom->IsBondedTo(WorldTime::getTime(), secondatom)) {
+      const bond::ptr bond = firstatom->getBond(secondatom);
+      bond->setDegree(state->params.degree.get());
+    } else {
+      ELOG(2, "There is no bond in between "+toString((*iter).leftid)
+          +" and "+toString((*iter).rightid)+".");
+    }
+  }
+
+  return ActionState::ptr(_state);
+}
+
+bool BondSetDegreeAction::canUndo() {
+  return true;
+}
+
+bool BondSetDegreeAction::shouldUndo() {
+  return true;
+}
+/** =========== end of function ====================== */
Index: src/Actions/BondAction/BondSetDegreeAction.def
===================================================================
--- src/Actions/BondAction/BondSetDegreeAction.def	(revision 596aacf191b75128e8e86114dda85fb17b792e44)
+++ src/Actions/BondAction/BondSetDegreeAction.def	(revision 596aacf191b75128e8e86114dda85fb17b792e44)
@@ -0,0 +1,43 @@
+/*
+ * BondSetDegreeAction.def
+ *
+ *  Created on: Oct 01, 2016
+ *      Author: heber
+ */
+
+// all includes and forward declarations necessary for non-integral types below
+#include "types.hpp"
+#include <vector>
+#include <utility>
+
+#include "Bond/BondInfo.hpp"
+
+typedef std::vector<BondInfo> BondDegrees_t;
+
+#include "Parameters/Validators/RangeValidator.hpp"
+
+// i.e. there is an integer with variable name Z that can be found in
+// 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 (const element *)(BoxVector) TODO: use a validator
+#define paramtypes (int)
+#define paramtokens ("set-bond-degree")
+#define paramdescriptions ("new bond degree for each bond") 
+#define paramreferences (degree)
+#define paramdefaults (PARAM_DEFAULT(1))
+#define paramvalids \
+(RangeValidator<int>(1,10))
+
+#define statetypes (BondDegrees_t)
+#define statereferences (bonddegrees)
+
+// some defines for all the names, you may use ACTION, STATE and PARAMS
+#define CATEGORY Bond
+#define MENUNAME "bond"
+#define MENUPOSITION 3
+#define ACTIONNAME SetDegree
+#define TOKEN "set-bond-degree"
+
+// finally the information stored in the ActionTrait specialization
+#define DESCRIPTION "sets the bond degree for all selected pairs of atoms"
+#undef SHORTFORM
Index: src/Actions/BondAction/BondSetDegreeAction.hpp
===================================================================
--- src/Actions/BondAction/BondSetDegreeAction.hpp	(revision 596aacf191b75128e8e86114dda85fb17b792e44)
+++ src/Actions/BondAction/BondSetDegreeAction.hpp	(revision 596aacf191b75128e8e86114dda85fb17b792e44)
@@ -0,0 +1,22 @@
+/*
+ * BondSetDegreeAction.hpp
+ *
+ *  Created on: Oct 01, 2016
+ *      Author: heber
+ */
+
+#ifndef BONDSETDEGREEACTION_HPP_
+#define BONDSETDEGREEACTION_HPP_
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include "Actions/Action.hpp"
+
+#include "BondSetDegreeAction.def"
+#include "Action_impl_header.hpp"
+
+#endif /* BONDSETDEGREEACTION_HPP_ */
