Index: kernel/include/IMP/score_states/NonbondedListScoreState.h
===================================================================
--- kernel/include/IMP/score_states/NonbondedListScoreState.h	(revision 338)
+++ kernel/include/IMP/score_states/NonbondedListScoreState.h	(working copy)
@@ -8,10 +8,10 @@
 #ifndef __IMP_NONBONDED_LIST_SCORE_STATE_H
 #define __IMP_NONBONDED_LIST_SCORE_STATE_H
 
+#include "../ScoreState.h"
+#include "BondedListScoreState.h"
 #include <vector>
 #include <limits>
-#include "../ScoreState.h"
-#include "BondedListScoreState.h"
 
 namespace IMP
 {
@@ -19,39 +19,44 @@
 class BondedListScoreState;
 
 //! This class maintains a list of non-bonded pairs.
-/** The distance cutoff is an optimization hint rather than a
-    strict cutoff. That is, the NonbondedListScoreState may
-    choose to ignore pairs above that cutoff, but may not.
- */
 class IMPDLLEXPORT NonbondedListScoreState: public ScoreState
 {
+ protected:
   Particles ps_;
   typedef std::vector<std::pair<Particle*, Particle*> > NBL;
   NBL nbl_;
-  float dist_cutoff_;
 
   void rescan();
-
+  void audit_particles(const Particles &ps) const;
+  void propagate_set_particles(const Particles &aps);
+  void propagate_update();
+  void add_if_nonbonded(Particle *a, Particle *b);
 public:
-  NonbondedListScoreState(const Particles &ps,
-                          float dist_cutoff
-                          = std::numeric_limits<Float>::max());
-  virtual ~NonbondedListScoreState() {}
-  IMP_CONTAINER(BondedListScoreState, bonded_list_score_state,
+  NonbondedListScoreState(const Particles &ps);
+  virtual ~NonbondedListScoreState();
+  IMP_CONTAINER(BondedListScoreState, bonded_list,
                 BondedListIndex);
+  // kind of evil hack to make the names better
+  // perhaps the macro should be made more flexible
+  typedef BondedListScoreStateIterator BondedListIterator;
 public:
   IMP_SCORE_STATE("0.5", "Daniel Russel");
 
   void set_particles(const Particles &ps);
 
+  typedef NBL::const_iterator NonbondedIterator;
+
   //! This iterates through the pairs of non-bonded particles
-  /** \precondition update() must be called first for this to be valid.
-   */
-  typedef NBL::const_iterator NonbondedIterator;
-  NonbondedIterator nonbonded_begin() const {
+  /** \param[in] cutoff The state may ignore pairs which are futher
+      apart than the cutoff.
+      \precondition update() must be called first for this to be valid.
+  */
+  NonbondedIterator nonbonded_begin(Float cutoff
+                                    =std::numeric_limits<Float>::max()) const {
     return nbl_.begin();
   }
-  NonbondedIterator nonbonded_end() const {
+  NonbondedIterator nonbonded_end(Float cutoff
+                                  =std::numeric_limits<Float>::max()) const {
     return nbl_.end();
   }
 };
Index: kernel/src/score_states/NonbondedListScoreState.cpp
===================================================================
--- kernel/src/score_states/NonbondedListScoreState.cpp	(revision 338)
+++ kernel/src/score_states/NonbondedListScoreState.cpp	(working copy)
@@ -6,48 +6,90 @@
  */
 
 #include "IMP/score_states/NonbondedListScoreState.h"
+#include "IMP/decorators/XYZDecorator.h"
 
 namespace IMP
 {
 
-NonbondedListScoreState::NonbondedListScoreState(const Particles &ps,
-                                                 float dist_cutoff) :
-    dist_cutoff_(dist_cutoff)
+NonbondedListScoreState::NonbondedListScoreState(const Particles &ps)
 {
   set_particles(ps);
 }
 
+NonbondedListScoreState::~NonbondedListScoreState()
+{
+  IMP_CONTAINER_DELETE(BondedListScoreState, bonded_list);
+}
+
+void NonbondedListScoreState::audit_particles(const Particles &ps) const
+{
+  for (unsigned int i=0; i< ps.size(); ++i) {
+    try {
+      XYZDecorator d= XYZDecorator::cast(ps[i]);
+    } catch (...) {
+      IMP_WARN("Particle " << ps[i]->get_index() 
+               << " does not have x,y,z coordinates " 
+               << " but was passed to the NonbondedListScoreState.\n");
+    }
+  }
+}
+
+void NonbondedListScoreState::propagate_set_particles(const Particles &aps) 
+{
+  for (BondedListScoreStateIterator bli= bonded_lists_begin();
+       bli != bonded_lists_end(); ++bli) {
+    (*bli)->set_particles(aps);
+  }
+}
+
+void NonbondedListScoreState::propagate_update() 
+{
+  for (BondedListScoreStateIterator bli= bonded_lists_begin();
+           bli != bonded_lists_end(); ++bli) {
+    (*bli)->update();
+  }
+}
+
+void NonbondedListScoreState::add_if_nonbonded(Particle *a, Particle *b)
+{
+  bool found=false;
+  for (BondedListIterator bli= bonded_lists_begin();
+       bli != bonded_lists_end(); ++bli) {
+    if ((*bli)->are_bonded(a, b)) {
+      found = true;
+      break;
+    }
+  }
+  if (!found) {
+    nbl_.push_back(std::make_pair(a, b));
+  }
+}
+
+
 void NonbondedListScoreState::rescan()
 {
   nbl_.clear();
   for (unsigned int i = 0; i < ps_.size(); ++i) {
-    Particle *pi = ps_[i];
+    Particle *pi= ps_[i];
     for (unsigned int j = 0; j < i; ++j) {
       Particle *pj = ps_[j];
-      bool found = false;
-      for (BondedListScoreStateIterator bli = bonded_list_score_states_begin();
-           bli != bonded_list_score_states_end(); ++bli) {
-        if ((*bli)->are_bonded(pi, pj)) {
-          found = true;
-          break;
-        }
-      }
-      if (!found) {
-        nbl_.push_back(std::make_pair(pi, pj));
-      }
+      add_if_nonbonded(pi, pj);
     }
   }
 }
 
-void NonbondedListScoreState::set_particles(const Particles &ps)
+void NonbondedListScoreState::set_particles(const Particles &ps) 
 {
-  ps_ = ps;
+  ps_=ps;
+  audit_particles(ps_);
+  propagate_set_particles(ps);
   rescan();
 }
 
 void NonbondedListScoreState::update()
 {
   IMP_LOG(VERBOSE, "Updating non-bonded list" << std::endl);
+  propagate_update();
   rescan();
 }
 
@@ -57,6 +99,5 @@
 }
 
 IMP_CONTAINER_IMPL(NonbondedListScoreState, BondedListScoreState,
-                   bonded_list_score_state, BondedListIndex,);
-
+                   bonded_list, BondedListIndex, );
 } // namespace IMP