populateAgent(data, isAdded);
populateAgent(data, true);
  private boolean populate(ComponentData data, float insertionOrder, String assemblyId)    throws SQLException  {    boolean result = false;    ComponentData parent = data.getParent();    String id = getComponentAlibId(data);    boolean isAdded = false;    addComponentDataSubstitutions(data);    substitutions.put(":assembly_id:", sqlQuote(assemblyId));    substitutions.put(":insertion_order:", String.valueOf(insertionOrder));    SortedSet oldArgs = (SortedSet) componentArgs.get(id);    if (oldArgs == null) {  // Don't know what the current args are      insureAlib();       // Insure that the alib and lib components are defined      ResultSet rs;      rs = executeQuery(stmt, dbp.getQuery("queryComponentArgs", substitutions));      oldArgs = new TreeSet();      while (rs.next()) {	oldArgs.add(new Argument(rs.getString(1), rs.getFloat(2)));      }      rs.close();      if (parent != null) {	// Is given component in runtime hierarchy?	rs = executeQuery(stmt, dbp.getQuery("checkComponentHierarchy",					     substitutions));	// If not, add it	if (!rs.next()) {	  executeUpdate(dbp.getQuery("insertComponentHierarchy",				     substitutions));	  isAdded = true;	  result = true; // Modified the experiment in the database 	}	rs.close();      }      componentArgs.put(id, oldArgs); // Avoid doing this again    }    // Now build a SortedSet of what the args should be    SortedSet newArgs = new TreeSet();    Object[] params = data.getParameters();    for (int i = 0; i < params.length; i++) {      newArgs.add(new Argument(params[i].toString(), i));    }    // FIXME: THIS MUST BE CHANGED SOMEHOW!!!!    // If I sense a removal / modification, set some     // flag and abort probably...    // The new args must only contain additions. There must be no    // deletions or alterations of the old args nor is it allowed    // to change the relative order of the existing arguments. If    // there are fewer newArgs than oldArgs, there is clearly a    // violation of this premise.    int excess = newArgs.size() - oldArgs.size();    if (excess < 0) {      throw new IllegalArgumentException("Attempt to remove "					 + (-excess)					 + " args from "					 + data);    }    // Prepare to iterate through both old and new args.    // argsToInsert accumulates the new arguments to be inserted.    // Each of the new args is compared with the next unaccounted    // for old arg. If the new arg has a value different from the    // next old arg it is assumed to be an insertion since    // deletions and modifications are disallowed. But, if the    // excess new arg count has been reduced to zero, then no new    // args are possible because there won't be enought old args    // to match the remaining new ones so we throw an exception.    // The argument order is interpolated between the preceding    // and following old argument.    Iterator newIter = newArgs.iterator();    Iterator oldIter = oldArgs.iterator();    List argsToInsert = new ArrayList();    float prev = Float.NaN;    while (oldIter.hasNext()) {      Argument newArg = (Argument) newIter.next();      Argument oldArg = (Argument) oldIter.next();      while (!newArg.argument.equals(oldArg.argument)) {	if(log.isWarnEnabled()) {	  log.warn("newArg != oldArg, new: " +newArg.toString() + " old: " + oldArg.toString());	}	// Assume arguments were inserted	excess--;	if (excess < 0) {	  throw new IllegalArgumentException("Component args cannot be modified or removed: " + data);	}	if (Float.isNaN(prev)) prev = oldArg.order - 1f;	argsToInsert.add(new Argument(newArg.argument, (prev + oldArg.order) * 0.5f));	newArg = (Argument) newIter.next();      }      prev = oldArg.order;    }    // Finally, any remaining new args are appended    if (Float.isNaN(prev)) prev = 0f;    while (newIter.hasNext()) {      Argument newArg = (Argument) newIter.next();      prev += 1f;      argsToInsert.add(new Argument(newArg.argument, prev));    }    // Now write all the new arguments that were not previously    // present to the database.    for (Iterator i = argsToInsert.iterator(); i.hasNext(); ) {      Argument arg = (Argument) i.next();      substitutions.put(":argument_value:", sqlQuote(arg.argument));      substitutions.put(":argument_order:", sqlQuote(String.valueOf(arg.order)));      executeUpdate(dbp.getQuery("insertComponentArg", substitutions));      oldArgs.add(arg);      result = true;    }    // FIXME:::    // Save in the CSHNA only the fact that an agent is within a Node    // if I can, Probably I have to save its args as well - which     // is just the name, no biggy.    // But I don't want to save the Agent definition there.    // Also, the insureAlibId call above creates the component_alib_id    // which I suppose is OK.    // So far so good. But I also only want to call the populateAgent thing    // if I have to, right? And then only save out the info    // I have to, right? That's the isAdded thing.    // Or maybe I can call this whenever I have an Agent    // and am not in the HNA assembly?    // No, I only want to write that out if     // it isn't already someplace else...    // How do I do that?    // Already we only save in the hierarchy if its not already there.    // That takes care of the existence of plugins, binders    // in the society. Then the logic above is all crazy    // to only do added arguments that were new    // And this populateAgent is probably doing similar.    // What I need is more complex....    if (data.getType().equals(ComponentData.AGENT)) {      if (!assemblyId.equals(hnaAssemblyId)) {	// isAdded: was this agent just added to the hierarchy	populateAgent(data, isAdded);	result = true;      } else {	// If this is an Agent and we're in the CSHNA assembly,	// don't save the plugins, etc now. Just return.	return result;      }    }    ComponentData[] children = data.getChildren();    // The following assumes that the insertion order of old    // children equals their index in the array and that the    // insertion order of all new children should be the their    // index in the array as well.    for (int i = 0, n = children.length; i < n; i++) {      result |= populate(children[i], i, assemblyId);    }    return result;  }