diff --git a/sidechain/doc/disulfid.rst b/sidechain/doc/disulfid.rst
index 6bf6078b9dc311a000be25d2fbf9c408d20aa781..5b330287975708bdf84fa008b20d2e63315f4895 100644
--- a/sidechain/doc/disulfid.rst
+++ b/sidechain/doc/disulfid.rst
@@ -74,7 +74,7 @@ that has also been implemented here.
 
 
 .. method:: ResolveCysteins(rotamer_groups, ca_positions, cb_positions,\
-                            [score_threshold=45.0])
+                            [score_threshold=45.0, optimize_subrotamers=False])
 
   Tries to optimize disulfid bond network. In a first step, all disulfid bonds
   get detected using :func:`DisulfidScore`. If the value between two rotamers is
@@ -88,12 +88,20 @@ that has also been implemented here.
   :param cb_positions:   The CB positions of the according rotamers
   :param score_threshold: The score two rotamers must have to be considered
                           as a disulfid bond
+  :param optimize_subrotamers: If set to true and the input consists of flexible
+                               rotamer groups, the active subrotamers get 
+                               optimized. For every pair of rotamers
+                               participating in a disulfid bond, the subrotamers
+                               with best :func:`DisulfidScore` get activated in
+                               the input **rotamer_groups**. This has an effect
+                               when the rotamers get applied on residues.
 
   :type rotamer_groups:  :class:`list` of 
                          :class:`FRMRotamerGroup`/:class:`RRMRotamerGroup`
   :type ca_positions: :class:`list` of :class:`ost.geom.Vec3`
   :type cb_positions: :class:`list` of :class:`ost.geom.Vec3`
   :type score_threshold: :class:`float`
+  :type optimize_subrotamers: :class:`bool`
 
   :returns: A :class:`tuple` containing two :class:`list` objects with equal
             length. Both lists contain :class:`tuple` objects with two elements.
diff --git a/sidechain/pymod/_reconstruct_sidechains.py b/sidechain/pymod/_reconstruct_sidechains.py
index b9e13dbd689f1200263fc2a923ca38f04f798ccf..ac41d155fe72ce701872f10305f3b00641b2a9fa 100644
--- a/sidechain/pymod/_reconstruct_sidechains.py
+++ b/sidechain/pymod/_reconstruct_sidechains.py
@@ -207,23 +207,27 @@ def _AddCysteinFrameResidues(frame_residues, incomplete_sidechains,
             incomplete_sidechains.append(idx)
 
 def _GetRotamerGroup(res_handle, rot_id, res_idx, rot_lib, rot_constructor,
-                     phi, psi, use_frm, bbdep):
+                     phi, psi, use_frm, bbdep, probability_cutoff = 0.98):
     if use_frm:
         if bbdep:
             return rot_constructor.ConstructFRMRotamerGroup(res_handle, rot_id,
                                                             res_idx, rot_lib,
-                                                            phi, psi)
+                                                            phi, psi,
+                                                            probability_cutoff)
         else:
             return rot_constructor.ConstructFRMRotamerGroup(res_handle, rot_id,
-                                                            res_idx, rot_lib)
+                                                            res_idx, rot_lib,
+                                                            probability_cutoff)
     else:
         if bbdep:
             return rot_constructor.ConstructRRMRotamerGroup(res_handle, rot_id,
                                                             res_idx, rot_lib,
-                                                            phi, psi)
+                                                            phi, psi,
+                                                            probability_cutoff)
         else:
             return rot_constructor.ConstructRRMRotamerGroup(res_handle, rot_id,
-                                                            res_idx, rot_lib)
+                                                            res_idx, rot_lib,
+                                                            probability_cutoff)
 
 def _GetRotamerGroups(res_list, rot_ids, indices, rot_lib, rot_constructor,
                       phi_angles, psi_angles, use_frm, bbdep, frame_residues):
@@ -331,7 +335,8 @@ def _GetDisulfidBridges(frame_residues, cystein_indices, res_list, rotamer_libra
     bond_result, \
     rotamer_result = sidechain.ResolveCysteins(cystein_rot_groups, 
                                                cys_ca_positions,
-                                               cys_cb_positions, 45.0)
+                                               cys_cb_positions, 45.0,
+                                               True)
 
     # get CYS with disulfid bonds and the chosen rotamers
     disulfid_indices = list()
diff --git a/sidechain/pymod/export_disulfid.cc b/sidechain/pymod/export_disulfid.cc
index b9000e9a21aac42c1a1810b0f3961f066ea6111b..72ea6c3c91febe9133ecdfde62ecb92951c63875 100644
--- a/sidechain/pymod/export_disulfid.cc
+++ b/sidechain/pymod/export_disulfid.cc
@@ -31,7 +31,8 @@ Real WrapDisulfidTwo(FRMRotamerPtr rot_one, FRMRotamerPtr rot_two,
 boost::python::tuple WrapResolveCysteins(const boost::python::list& rot_groups,
                                          const boost::python::list& ca_pos,
                                          const boost::python::list& cb_pos,
-                                         Real score_threshold){
+                                         Real score_threshold, 
+                                         bool optimize_subrotamers){
 
   boost::python::list disulfid_return_list;
   boost::python::list rotamer_return_list;
@@ -53,13 +54,15 @@ boost::python::tuple WrapResolveCysteins(const boost::python::list& rot_groups,
   if(extractor.check()){
     std::vector<promod3::sidechain::FRMRotamerGroupPtr> v_rot_groups;
     promod3::core::ConvertListToVector(rot_groups, v_rot_groups);
-    ResolveCysteins(v_rot_groups, v_ca_pos, v_cb_pos, score_threshold, 
+    ResolveCysteins(v_rot_groups, v_ca_pos, v_cb_pos, score_threshold,
+                    optimize_subrotamers, 
                     disulfid_indices, rotamer_indices);
   }
   else{
     std::vector<promod3::sidechain::RRMRotamerGroupPtr> v_rot_groups;
     promod3::core::ConvertListToVector(rot_groups, v_rot_groups);
     ResolveCysteins(v_rot_groups, v_ca_pos, v_cb_pos, score_threshold,
+                    optimize_subrotamers,
                     disulfid_indices, rotamer_indices);
   }
 
@@ -86,15 +89,16 @@ void export_Disulfid(){
                                               arg("cb_pos_two"),
                                               arg("sg_pos_two")));
 
-  def("DisulfidScore",&WrapDisulfidOne,(arg("rotamer_one"),arg("rotamer_two"),
-                                        arg("ca_pos_one"),arg("cb_pos_one"),
-                                        arg("ca_pos_two"),arg("cb_pos_two")));
-  def("DisulfidScore",&WrapDisulfidTwo,(arg("rotamer_one"),arg("rotamer_two"),
-                                        arg("ca_pos_one"),arg("cb_pos_one"),
-                                        arg("ca_pos_two"),arg("cb_pos_two")));
+  def("DisulfidScore",&WrapDisulfidOne,(arg("rotamer_one"), arg("rotamer_two"),
+                                        arg("ca_pos_one"), arg("cb_pos_one"),
+                                        arg("ca_pos_two"), arg("cb_pos_two")));
+  def("DisulfidScore",&WrapDisulfidTwo,(arg("rotamer_one"), arg("rotamer_two"),
+                                        arg("ca_pos_one"), arg("cb_pos_one"),
+                                        arg("ca_pos_two"), arg("cb_pos_two")));
 
   def("ResolveCysteins", &WrapResolveCysteins, (arg("rotamer_groups"),
                                                 arg("ca_positions"),
                                                 arg("cb_positions"),
-                                                arg("score_threshold") = 45.0));
+                                                arg("score_threshold") = 45.0,
+                                                arg("optimize_subrotamers") = false));
 }
\ No newline at end of file
diff --git a/sidechain/src/disulfid.cc b/sidechain/src/disulfid.cc
index f7837bafefa8782953b8a8bacb8260a49832d9fd..a0e1d3c07b4cc0b0c94994825d489f614be5f1fd 100644
--- a/sidechain/src/disulfid.cc
+++ b/sidechain/src/disulfid.cc
@@ -190,7 +190,6 @@ void CysteineResolve(const std::vector<T>& rot_groups,
   }
 }
 
-
 }
 
 
@@ -225,6 +224,52 @@ Real DisulfidRawScore(const geom::Vec3& ca_pos_one,
 }
 
 
+namespace{
+
+// this is only in here because it requires the DisulfidRawScore function..
+void SetOptimalSubrotamer(promod3::sidechain::FRMRotamerPtr rot_one, 
+                          promod3::sidechain::FRMRotamerPtr rot_two,
+                          const geom::Vec3& ca_pos_one, 
+                          const geom::Vec3& cb_pos_one,
+                          const geom::Vec3& ca_pos_two, 
+                          const geom::Vec3& cb_pos_two) {
+
+  std::vector<geom::Vec3> sg_pos_one, sg_pos_two;
+  ExtractCYSSG(*rot_one, *rot_two, sg_pos_one, sg_pos_two);
+
+  if(sg_pos_one.size() != rot_one->subrotamer_size() || 
+     sg_pos_two.size() != rot_two->subrotamer_size() ){
+    throw promod3::Error("Expect cysteins to have exactly one gamma sulfur "
+                         "per subrotamer!");
+  }
+
+  Real min_score = std::numeric_limits<Real>::max();
+  uint min_i = 0;
+  uint min_j = 0;
+
+  for(uint i = 0; i < sg_pos_one.size(); ++i){
+    for(uint j = 0; j < sg_pos_two.size(); ++j){
+
+      Real score = DisulfidRawScore(ca_pos_one,cb_pos_one,
+                                    sg_pos_one[i], ca_pos_two,
+                                    cb_pos_two,sg_pos_two[j]);
+      if(score < min_score){
+        min_score = score;
+        min_i = i;
+        min_j = j;
+      }
+    }
+  }
+
+  if(min_score < std::numeric_limits<Real>::max()){
+    rot_one->SetActiveSubrotamer(min_i);
+    rot_two->SetActiveSubrotamer(min_j);
+  }
+}
+
+}
+
+
 Real DisulfidScore(RRMRotamerPtr rot_one, RRMRotamerPtr rot_two, 
                    const geom::Vec3& ca_pos_one, const geom::Vec3& cb_pos_one, 
                    const geom::Vec3& ca_pos_two, const geom::Vec3& cb_pos_two){
@@ -273,13 +318,13 @@ Real DisulfidScore(FRMRotamerPtr rot_one, FRMRotamerPtr rot_two,
   return min_raw_score + self_energy;
 }
 
-// template functionility of following functions has been hidden in
+// template functionality of following functions has been hidden in
 // the source file to avoid bloating the header...
 void ResolveCysteins(
       const std::vector<RRMRotamerGroupPtr>& rot_groups,
       const std::vector<geom::Vec3>& ca_pos,
       const std::vector<geom::Vec3>& cb_pos,
-      Real disulfid_score_thresh,
+      Real disulfid_score_thresh, bool optimize_subrotamers,
       std::vector<std::pair<uint, uint> >& disulfid_indices,
       std::vector<std::pair<uint, uint> >& rotamer_indices){
 
@@ -292,13 +337,29 @@ void ResolveCysteins(
 void ResolveCysteins(const std::vector<FRMRotamerGroupPtr>& rot_groups,
                      const std::vector<geom::Vec3>& ca_pos,
                      const std::vector<geom::Vec3>& cb_pos,
-                     Real disulfid_score_thresh,
+                     Real disulfid_score_thresh, bool optimize_rotamers,
                      std::vector<std::pair<uint, uint> >& disulfid_indices,
                      std::vector<std::pair<uint, uint> >& rotamer_indices){
 
   CysteineResolve<FRMRotamerGroupPtr>(rot_groups, ca_pos, cb_pos,
                                       disulfid_score_thresh, disulfid_indices,
                                       rotamer_indices);
+
+  if(optimize_rotamers){
+
+    for(uint i = 0; i < disulfid_indices.size(); ++i){
+
+      const std::pair<uint, uint>& group_pair = disulfid_indices[i];
+      const std::pair<uint, uint>& rotamer_pair = rotamer_indices[i];
+
+      SetOptimalSubrotamer((*rot_groups[group_pair.first])[rotamer_pair.first],
+                           (*rot_groups[group_pair.second])[rotamer_pair.second],
+                           ca_pos[group_pair.first], 
+                           cb_pos[group_pair.first],
+                           ca_pos[group_pair.second], 
+                           cb_pos[group_pair.second]);
+    }
+  }
 }
 
 
diff --git a/sidechain/src/disulfid.hh b/sidechain/src/disulfid.hh
index 40613ca192d58f655d319de66b68803a2df30890..84f98aaed96b86342031e10b9f30ad1cafc4016d 100644
--- a/sidechain/src/disulfid.hh
+++ b/sidechain/src/disulfid.hh
@@ -28,14 +28,14 @@ Real DisulfidScore(FRMRotamerPtr rot_one, FRMRotamerPtr rot_two,
  void ResolveCysteins(const std::vector<FRMRotamerGroupPtr>& rot_groups,
                       const std::vector<geom::Vec3>& ca_pos,
                       const std::vector<geom::Vec3>& cb_pos,
-                      Real disulfid_score_thresh,
+                      Real disulfid_score_thresh, bool optimize_subrotamers,
                       std::vector<std::pair<uint, uint> >& disulfid_indices,
                       std::vector<std::pair<uint, uint> >& rotamer_indices);
 
  void ResolveCysteins(const std::vector<RRMRotamerGroupPtr>& rot_groups,
                       const std::vector<geom::Vec3>& ca_pos,
                       const std::vector<geom::Vec3>& cb_pos,
-                      Real disulfid_score_thresh,
+                      Real disulfid_score_thresh, bool optimize_subrotamers,
                       std::vector<std::pair<uint, uint> >& disulfid_indices,
                       std::vector<std::pair<uint, uint> >& rotamer_indices);
 
diff --git a/sidechain/src/sidechain_reconstructor.cc b/sidechain/src/sidechain_reconstructor.cc
index 71cb3ccf7f3cd89d81bb23801ca0679afa579429..92ff3157cf4f71301ee5d6dac8af8f9d7f612c7a 100644
--- a/sidechain/src/sidechain_reconstructor.cc
+++ b/sidechain/src/sidechain_reconstructor.cc
@@ -241,7 +241,8 @@ template<typename RotamerGroup> void SidechainReconstructor::BuildDisulfids_(
   std::vector<std::pair<uint, uint> > rot_solution;
 
   ResolveCysteins(cys_rotamer_groups, ca_pos, cb_pos,
-                  disulfid_score_thresh_, bond_solution, rot_solution);
+                  disulfid_score_thresh_, true,
+                  bond_solution, rot_solution);
 
   std::vector<int> is_bonded(cys_rotamer_groups.size(), 0);