System.out.println("Experiment: SAVING TO DATABASE");
  public void saveToDb(DBConflictHandler ch) {    System.out.println("Experiment: SAVING TO DATABASE");    try {      updateNameServerHostName(); // Be sure this is up-to-date      List components = getComponents();      boolean componentWasRemoved = false;      PopulateDb pdb = null;      SocietyComponent sc = getSocietyComponent();      if (sc == null) {        if (log.isErrorEnabled())           log.error("Experiment has no society; cannot save it to database.");        return;      }      pdb =	new PopulateDb("CMT", "CSHNA", "CSMI", getExperimentName(),		       getExperimentID(), trialID, ch, sc.getAssemblyId());      setExperimentID(pdb.getExperimentId());      setTrialID(pdb.getTrialId()); // sets trial id and -D argument      // Some components will want access to the complete set of Nodes      // in the society, etc. To get that, they must get back to the      // root soc object, and do a getOwner and go from there. Ugly.      // So far we've just created the pdb (which      // sets up the Experimet & Trial IDs, and puts the CMT assembly      // in the right place if necc, and clears out the other       // assemblies (CSMI, CSHNA)      // Gather the HostNodeAgent stuff      generateHNACDATA();      if(log.isErrorEnabled() && completeSociety == null) {        log.error("save: Society Data is null!");      }      // Problem: Societies from files store _tons_ of properties      // on the Agents. This is most of the society definition, in fact.      // It appears that these end up changing (somehow),      // between saves. So this can throw that IllegalArgumentException      // FIXME!!!!      // Save what we have so far in the CSHNA assembly      if (log.isDebugEnabled()) {	log.debug("About to save HNA data");      }      pdb.populateHNA(completeSociety);      // Now let components add in their pieces      componentWasRemoved = askComponentsToAddCDATA();      // If any component removed something, we need      // to recreate the CMT assembly (under the original ID)      // So this, currently destroys the orig CMT      // Note also it does not effect Agent asset data      // or relationships or OPLAN stuff      if (componentWasRemoved) {	if (log.isDebugEnabled()) {	  log.debug("save: After adding CDATA, got a removed.");	}	pdb.populateCSA(completeSociety);      } else {	if (log.isDebugEnabled()) {	  log.debug("save: Done adding CDATA, ready to modify.");	}      }      // then give everyone a chance to modify what they've collectively produced      for (int i = 0, n = components.size(); i < n; i++) {        BaseComponent soc = (BaseComponent) components.get(i);        soc.modifyComponentData(completeSociety, pdb);        if (soc.componentWasRemoved()) {	  if (log.isDebugEnabled()) {	    log.debug("save: After modifying CDATA by comp " + soc.getShortName() + ", got a removed.");	  }          pdb.populateCSA(completeSociety);        }	try {	  // Incrementally save	  // so that later recipes have the benefit	  // of the earlier modifications	  if (log.isDebugEnabled()) {	    log.debug("About to save CSMI data, having just done mod in " + soc.getShortName());	  }	  pdb.populateCSMI(completeSociety);	} catch (IllegalArgumentException iae) {	  if (log.isInfoEnabled()) {	    log.info("Caught iae " + iae.toString() + " while saving modifications. Must redo as a CSA");	  }	  pdb.populateCSA(completeSociety);	}      } // end of loop over components to do mod      pdb.setModRecipes(recipes);      // Now make sure the runtime/ config time assemblies      // are all correct      if (log.isDebugEnabled()) {	log.debug("About to do fix assemblies");      }      if (! pdb.fixAssemblies()) {	// Some sort of error trying to ensure the assemblies are all correct.	if (log.isErrorEnabled()) {	  log.error("Failed to ensure correct assemblies saved.");	}      }      pdb.close();    } catch (Exception sqle) {      if (log.isErrorEnabled())	log.error("Error saving experiment to database: ", sqle);      return;    }    resetModified();  }