Index: include/IMP/Model.h
===================================================================
--- include/IMP/Model.h	(revision 630)
+++ include/IMP/Model.h	(working copy)
@@ -11,7 +11,6 @@
 
 #include "IMP_config.h"
 #include "ModelData.h"
-#include "Restraint.h"
 #include "RigidBody.h"
 #include "State.h"
 #include "boost/noncopyable.h"
@@ -19,7 +18,8 @@
 namespace IMP
 {
 
-  class Particle;
+class Particle;
+class Restraint;
 
 //! Class for storing model, its restraints, constraints, and particles.
 /** All attribute data for particles is stored through indexing in the
@@ -27,7 +27,7 @@
  */
 class IMPDLLEXPORT Model: public boost::noncopyable
 {
-
+  friend class Restraint;
 public:
   Model();
   ~Model();
@@ -38,39 +38,11 @@
   ModelData* get_model_data() const;
 
   IMP_CONTAINER(Particle, particle, ParticleIndex);
+  IMP_CONTAINER(State, state, StateIndex);
+  IMP_CONTAINER(Restraint, restraint, RestraintIndex);
  public:
 
-  //! Add restraint set to the model.
-  /** \param[in] restraint_set Pointer to the restraint set.
-      \return the index of the newly-added restraint.
-   */
-  RestraintIndex add_restraint(Restraint* restraint_set);
 
-  //! Get restraint set from the model.
-  /** \param[in] i The RestraintIndex returned when adding.
-      \exception std::out_of_range restraint index is out of range.
-      \return pointer to the restraint.
-   */
-  Restraint* get_restraint(RestraintIndex i) const;
-
-  //! Add state to the model.
-  /** \param[in] state Pointer to the state.
-      \return the index of the newly-added state.
-   */
-  StateIndex add_state(State* state);
-
-  //! Get state from the model.
-  /** \param[in] i The StateIndex returned when adding.
-      \exception std::out_of_range state index is out of range.
-      \return pointer to the state.
-   */
-  State* get_state(StateIndex i) const;
-
-  //! Return the total number of restraints
-  unsigned int number_of_restraints() const {
-    return restraints_.size();
-  }
-
   //! Evaluate all of the restraints in the model and return the score.
   /** \param[in] calc_derivs If true, also evaluate the first derivatives.
       \return The score.
@@ -109,16 +81,6 @@
   //! all of the data associated with the particles
   ModelData* model_data_;
 
-  //! all base-level restraints and/or restraint sets of the model
-  std::vector<Restraint*> restraints_;
-
-  // all base-level restraints and/or restraint sets of the model
-  std::vector<State*> states_;
-
-
-  //! sets of particles that move as a single rigid body
-  std::vector<RigidBody*> rigid_bodies_;
-
   //! trajectory file path
   std::string trajectory_path_;
   bool trajectory_on_;
Index: include/IMP/Restraint.h
===================================================================
--- include/IMP/Restraint.h	(revision 630)
+++ include/IMP/Restraint.h	(working copy)
@@ -10,10 +10,12 @@
 
 #include <vector>
 #include <iostream>
+#include <limits>
 
 #include "IMP_config.h"
-#include "ModelData.h"
+#include "Model.h"
 #include "ScoreFunc.h"
+#include "Particle.h"
 #include "DerivativeAccumulator.h"
 #include "boost/noncopyable.h"
 #include "utility.h"
@@ -27,8 +29,8 @@
 //! Abstract class for representing restraints
 class IMPDLLEXPORT Restraint : public boost::noncopyable
 {
-
 public:
+  //! Initialize the Restraint and its model pointer
   Restraint(std::string name=std::string());
   virtual ~Restraint();
 
@@ -37,7 +39,7 @@
                        derivatives.
       \return Current score.
    */
-  virtual Float evaluate(DerivativeAccumulator *accum) = 0;
+  virtual Float evaluate(DerivativeAccumulator *) = 0;
 
   //! Set whether the restraint is active i.e. if it should be evaluated.
   /** \param[in] is_active If true, the restraint is active.
@@ -58,7 +60,7 @@
   //! Show the current restraint.
   /** \param[in] out Stream to send restraint description to.
    */
-  virtual void show(std::ostream& out) const;
+  virtual void show(std::ostream& out=std::cout) const;
 
   virtual std::string version() const = 0;
 
@@ -77,6 +79,7 @@
   Particle *get_particle(unsigned int i) const;
 
   int add_particle(Particle *p) {
+    IMP_assert(p != NULL, "Can't add NULL particle");
     particles_.push_back(p);
     return particles_.size()-1;
   }
@@ -88,10 +91,10 @@
     model_=model;
   }
 
-
-
   //! Return the model containing this restraint
   Model *get_model() const {
+    IMP_assert(model_ != NULL,
+               "get_model() called before set_model()");
     return model_;
   }
 
Index: include/IMP/State.h
===================================================================
--- include/IMP/State.h	(revision 630)
+++ include/IMP/State.h	(working copy)
@@ -11,7 +11,6 @@
 #include <iostream>
 
 #include "IMP_config.h"
-#include "ModelData.h"
 #include "boost/noncopyable.h"
 
 namespace IMP
@@ -50,6 +49,8 @@
 
   //! return the stored model data
   Model *get_model() const {
+    IMP_assert(model_ != NULL,
+               "Must call set_model before get_model on state");
     return model_;
   }
 protected:
Index: include/IMP/Optimizer.h
===================================================================
--- include/IMP/Optimizer.h	(revision 630)
+++ include/IMP/Optimizer.h	(working copy)
@@ -34,9 +34,14 @@
   virtual std::string version() const =0;
   /** \return the last person to modify this restraint */
   virtual std::string last_modified_by() const=0;
-
+  
   //! Get the model being optimized
-  Model *get_model() const {return model_;}
+  Model *get_model() const {
+    IMP_assert(model_ != NULL, 
+               "get_model() called before set_model() "
+               << " this can crash python");
+    return model_;
+  }
 
   //! Set the model being optimized
   /**
Index: src/Optimizer.cpp
===================================================================
--- src/Optimizer.cpp	(revision 630)
+++ src/Optimizer.cpp	(working copy)
@@ -14,13 +14,14 @@
 //! Constructor
 Optimizer::Optimizer()
 {
-  IMP_LOG(VERBOSE, "Created optimizer");
+  IMP_LOG(VERBOSE, "MEMORY: Optimizer created " << this << std::endl);
 }
 
 
 //! Destructor
 Optimizer::~Optimizer()
 {
+  IMP_LOG(VERBOSE, "MEMORY: Optimizer destroyed " << this << std::endl);
 }
 
 }  // namespace IMP
Index: src/Model.cpp
===================================================================
--- src/Model.cpp	(revision 630)
+++ src/Model.cpp	(working copy)
@@ -10,6 +10,7 @@
 #include "IMP/ModelData.h"
 #include "IMP/Particle.h"
 #include "IMP/log.h"
+#include "IMP/Restraint.h"
 #include "IMP/DerivativeAccumulator.h"
 #include "mystdexcept.h"
 
@@ -19,6 +20,7 @@
 //! Constructor
 Model::Model()
 {
+  IMP_LOG(VERBOSE, "MEMORY: Model created " << this << std::endl);
   model_data_ = new ModelData();
   frame_num_ = 0;
   trajectory_on_ = false;
@@ -28,19 +30,10 @@
 //! Destructor
 Model::~Model()
 {
-  IMP_LOG(VERBOSE, "Delete Model: beware of early Python calls to destructor.");
-  for (ParticleIterator it=particles_begin(); it != particles_end(); ++it) {
-    (*it)->set_model(NULL, ParticleIndex());
-  }
+  IMP_LOG(VERBOSE, "MEMORY: Model destroyed " << this << std::endl);
   IMP_CONTAINER_DELETE(Particle, particle);
-  for (unsigned int i = 0; i < restraints_.size(); ++i) {
-    restraints_[i]->set_model(NULL);
-    delete restraints_[i];
-  }
-  for (unsigned int i = 0; i < states_.size(); ++i) {
-    states_[i]->set_model(NULL);
-    delete states_[i];
-  }
+  IMP_CONTAINER_DELETE(State, state);
+  IMP_CONTAINER_DELETE(Restraint, restraint);
 }
 
 
@@ -52,63 +45,17 @@
   return model_data_;
 }
 
+IMP_CONTAINER_IMPL(Model, Restraint, restraint, RestraintIndex,
+                     obj->set_model(this));
 
 
-//! Add restraint set to the model.
-/** \param[in] restraint_set Pointer to the restraint set.
-    \return the index of the newly-added restraint.
- */
-RestraintIndex Model::add_restraint(Restraint* restraint_set)
-{
-  restraints_.push_back(restraint_set);
-  RestraintIndex ri(restraints_.size() - 1);
-  restraint_set->set_model(this);
-  return ri;
-}
+IMP_CONTAINER_IMPL(Model, Particle, particle, ParticleIndex,
+                   obj->set_model(this, index));
 
+IMP_CONTAINER_IMPL(Model, State, state, StateIndex,
+                     obj->set_model(this));
 
-IMP_CONTAINER_IMPL(Model, Particle, particle, ParticleIndex, 
-                  obj->set_model(this, index));
 
-//! Get state from the model.
-/** \param[in] i The StateIndex returned when adding.
-    \exception std::out_of_range state index is out of range.
-    \return pointer to the state.
- */
-State* Model::get_state(StateIndex i) const
-{
-  IMP_check(i.get_index() < states_.size(),
-            "Out of range State requested",
-            std::out_of_range("Invalid State requested"));
-  return states_[i.get_index()];
-}
-
-
-//! Add state to the model.
-/** \param[in] state Pointer to the state.
-    \return the index of the newly-added state.
-*/
-StateIndex Model::add_state(State* state)
-{
-  state->set_model(this);
-  states_.push_back(state);
-  return states_.size() - 1;
-}
-
-
-//! Get restraint set from the model.
-/** \param[in] i The RestraintIndex returned when adding.
-    \exception std::out_of_range restraint index is out of range.
-    \return pointer to the restraint.
- */
-Restraint* Model::get_restraint(RestraintIndex i) const
-{
-  IMP_check(i.get_index() < restraints_.size(),
-            "Out of range restraint requested",
-            std::out_of_range("Invalid restraint requested"));
-  return restraints_[i.get_index()];
-}
-
 //! Evaluate all of the restraints in the model and return the score.
 /** \param[in] calc_derivs If true, also evaluate the first derivatives.
     \return The score.
@@ -118,38 +65,54 @@
   // One or more particles may have been activated or deactivated.
   // Check each restraint to see if it changes its active status.
   IMP_LOG(VERBOSE,
-          "Model evaluate (" << restraints_.size() << " restraint sets):");
+          "Model evaluate (" << number_of_restraints() << " restraints):"
+          << std::endl);
+
   if (model_data_->check_particles_active()) {
-    for (size_t i = 0; i < restraints_.size(); i++) {
-      restraints_[i]->check_particles_active();
+    IMP_LOG(VERBOSE,
+          "Checking for active particles " << std::flush);
+
+    for (RestraintIterator it = restraints_begin(); 
+         it != restraints_end(); ++it) {
+      (*it)->check_particles_active();
+      IMP_LOG(VERBOSE, "." << std::flush);
     }
 
     model_data_->set_check_particles_active(false);
+    IMP_LOG(VERBOSE, "done." << std::endl);
   }
 
   // If calcualting derivatives, first set all derivatives to zero
   if (calc_derivs)
     model_data_->zero_derivatives();
 
-  for (size_t i = 0; i < states_.size(); i++) {
-    IMP_LOG(VERBOSE, "Updating state " << states_[i]->get_name() << ":");
-    states_[i]->update();
+  IMP_LOG(VERBOSE,
+          "Updating States " << std::flush);
+  for (StateIterator it = states_begin(); it != states_end(); ++it) {
+    (*it)->update();
+    IMP_LOG(VERBOSE, "." << std::flush);
   }
+  IMP_LOG(VERBOSE, "done." << std::endl);
 
   // evaluate all of the active restraints to get score (and derivatives)
   // for current state of the model
   Float score = 0.0;
   DerivativeAccumulator accum;
   DerivativeAccumulator *accpt = (calc_derivs ? &accum : NULL);
-  for (size_t i = 0; i < restraints_.size(); i++) {
-    IMP_LOG(VERBOSE,
-            "Evaluating restraint " << restraints_[i]->get_name() << ":");
-    if (restraints_[i]->get_is_active()) {
-      score += restraints_[i]->evaluate(accpt);
-    }
 
-    IMP_LOG(VERBOSE, "Cumulative score: " << score);
+  IMP_LOG(VERBOSE,
+          "Evaluating restraints " << calc_derivs << std::endl);
+  for (RestraintIterator it = restraints_begin();
+       it != restraints_end(); ++it) {
+    IMP_LOG(VERBOSE, (*it)->get_name() << ": " << std::flush);
+    Float tscore=0;
+    if ((*it)->get_is_active()) {
+      tscore = (*it)->evaluate(accpt);
+    }
+    IMP_LOG(VERBOSE, tscore << std::endl);
+    score+= tscore;
   }
+  IMP_LOG(VERBOSE, "done." << std::endl);
 
   // if trajectory is on and we are calculating derivatives, save state in
   // trajectory file
@@ -158,7 +121,7 @@
   if (calc_derivs)
     save_state();
 
-  IMP_LOG(VERBOSE, "Final score: " << score);
+  IMP_LOG(VERBOSE, "Final score: " << score << std::endl);
   return score;
 }
 
@@ -239,17 +202,12 @@
   out << "version: " << version() << "  ";
   out << "last_modified_by: " << last_modified_by() << std::endl;
   out << number_of_particles() << " particles" << std::endl;
-  for (ParticleConstIterator it=particles_begin();
-       it != particles_end(); ++it) {
-    (*it)->show(out);
+  out << "Restraints:" << std::endl;
+  for (RestraintConstIterator it = restraints_begin(); 
+       it != restraints_end(); ++it) {
+    out << (*it)->get_name() << std::endl;
   }
 
-  for (size_t i = 0; i < restraints_.size(); i++) {
-    out  << std::endl << "* Restraint *" << std::endl;
-
-    restraints_[i]->show(out);
-  }
-
   internal::show_attributes(out);
 }
 
Index: src/Restraint.cpp
===================================================================
--- src/Restraint.cpp	(revision 630)
+++ src/Restraint.cpp	(working copy)
@@ -19,7 +19,7 @@
 Restraint::Restraint(std::string name): name_(name)
 {
   model_ = NULL;
-  IMP_LOG(VERBOSE, "Restraint constructed");
+  IMP_LOG(VERBOSE, "MEMORY: Restraint constructed " << this << std::endl);
   is_active_ = true; // active by default
   are_particles_active_ = true; // active by default
 }
@@ -28,11 +28,7 @@
 //! Destructor
 Restraint::~Restraint()
 {
-  IMP_LOG(VERBOSE, "Restraint deleted");
-  IMP_assert(get_model() == NULL,
-             "Attemping to delete restraint while it is still in a model.\n"
-             << " This probably reflects premature destruction"
-             << " of python references.\n");
+  IMP_LOG(VERBOSE, "MEMORY: Restraint deleted " << this << std::endl);
 }
 
 
@@ -76,9 +72,11 @@
  */
 void Restraint::check_particles_active()
 {
+  IMP_assert(get_model() != NULL,
+             "Add Restraint to Model before calling check_particles_active");
   are_particles_active_ = true;
   for (size_t i = 0; i < particles_.size(); i++) {
-    if (!particles_[i]->get_is_active()) {
+    if (!get_particle(i)->get_is_active()) {
       are_particles_active_ = false;
       return;
     }
Index: src/Particle.cpp
===================================================================
--- src/Particle.cpp	(revision 630)
+++ src/Particle.cpp	(working copy)
@@ -17,18 +17,14 @@
 //! Constructor
 Particle::Particle(): model_(NULL)
 {
-  IMP_LOG(VERBOSE, "create particle" << std::endl);
   is_active_ = true;
+  IMP_LOG(VERBOSE, "MEMORY: Particle created " << pi_ << std::endl);
 }
 
 //! Constructor
 Particle::~Particle()
 {
-  IMP_LOG(VERBOSE, "destroy particle " << *this << std::endl);
-  IMP_assert(get_model() == NULL,
-             "Attemping to delete particle while it is still in a model.\n"
-             << " This probably reflects premature destruction"
-             << " of python references.\n");
+  IMP_LOG(VERBOSE, "MEMORY: Particle deleted " << pi_ << std::endl);
 }