log.debug("copy: Putting ne Agent " + nagents[k].getShortName() + " on new Node " + nnodes[i].getShortName());
log.debug("copy: Putting new Agent " + nagents[k].getShortName() + " on new Node " + nnodes[i].getShortName());
  public ModifiableComponent copy(String uniqueName) {    if (log.isDebugEnabled()) {      log.debug("Experiment copying " + getExperimentName() + " into new name " + uniqueName);    }    Experiment experimentCopy = null;    if (DBUtils.dbMode)       experimentCopy = new Experiment(uniqueName, expID, trialID);    else      experimentCopy = new Experiment(uniqueName);    // FIXME: Unset the experiment and trial IDs? I think so...    experimentCopy.expID = null;    experimentCopy.trialID = null;    Properties newProps = experimentCopy.getDefaultNodeArguments();    newProps.clear();    newProps.putAll(getDefaultNodeArguments());//     // Copy the society component//     ModifiableComponent society = getSocietyComponent();//     if (society != null) {//       ModifiableComponent copiedSocietyComponent = null;//       // FIXME: USe a name based on the original society!!//       //      copiedSocietyComponent = society.copy("Society for " + uniqueName);//       copiedSocietyComponent = society.copy(society.getShortName() + " copy");//       if (copiedSocietyComponent != null) {//         // FIXME: Must save the copied society to the DB? I think the // 	// society does it for me...//         experimentCopy.addComponent(copiedSocietyComponent);//       }//     }    // Don't copy the society.    experimentCopy.addComponent(getSocietyComponent());        // Copy the recipe components    for (int i = 0; i < getRecipeComponentCount(); i++) {      ModifiableComponent mc = getRecipeComponent(i);//       ModifiableComponent copiedComponent = null;//       // FIXME: USe a name based on the original recipe!!//       //      copiedComponent = mc.copy("Recipe for " + uniqueName);//       copiedComponent = mc.copy(mc.getShortName() + " copy");//       if (copiedComponent != null) {//         experimentCopy.addComponent(copiedComponent);//       }      // Don't copy recipes either      experimentCopy.addComponent(mc);    }    // copy hosts    HostComponent[] hosts = getHostComponents();    HostComponent[] nhosts = new HostComponent[hosts.length];    for (int i = 0; i < hosts.length; i++) {      // FIXME: instead to nhosts[i] = hosts[i].copy();      // and then don't need the following 2 set calls hopefully      nhosts[i] = experimentCopy.addHost(hosts[i].getShortName().toString());      nhosts[i].setServerPort(hosts[i].getServerPort());      nhosts[i].setMonitoringPort(hosts[i].getMonitoringPort());      // FIXME: What about other Host fields? OS, etc?      // -- answer - see above fixme    }    // copy nodes    NodeComponent[] nodes = getNodeComponents();    NodeComponent[] nnodes = new NodeComponent[nodes.length];    for (int i = 0; i < nodes.length; i++) {      nnodes[i] = ((ExperimentNode)nodes[i]).copy(experimentCopy);      experimentCopy.addNodeComponent((ExperimentNode)nnodes[i]);      // FIXME: What about other Node fields?      // answer -- see comment in ExperimentNode.copy    }    // reconcile hosts-nodes-agents    AgentComponent[] nagents = experimentCopy.getAgents();    NodeComponent nnode = null;    ArrayList nNodesCopied = new ArrayList();    for (int i = 0; i < hosts.length; i++) {      NodeComponent[] onodes = hosts[i].getNodes();      // for each of the old nodes, find the corresponding new node      for (int j = 0; j < onodes.length; j++) {        for (int k = 0; k < nnodes.length; k++) {          if (nnodes[k].getShortName().equals(onodes[j].getShortName())) {              nnode = nnodes[k];              // add new node to new host              nhosts[i].addNode(nnode);              break;          }        }        // add new agents to new node        AgentComponent[] oagents = onodes[j].getAgents();        for (int x = 0; x < oagents.length; x++)           for (int y = 0; y < nagents.length; y++)             if (nagents[y].getShortName().equals(oagents[x].getShortName()))              nnode.addAgent(nagents[y]);	// Record which Nodes we've copied the Agents for	nNodesCopied.add(nnode);      }    }    // FIXME: What about if orig Experiment had Agents assigned to a Node    // that was not assigned to a host - is that mapping lost?    // I think so. So we need to maybe keep track of which Nodes we updated just now    for (int i = 0; i < nnodes.length; i++) {      if (! nNodesCopied.contains(nnodes[i])) {	// We may need to copy the old node-agent mapping onto this new node	AgentComponent[] oagents = nodes[i].getAgents();	if (log.isDebugEnabled() && oagents.length > 0) {	  log.debug("copy: Found node whose Agent mapping may not have been copied: " + nnodes[i]);	}	for (int j = 0; j < oagents.length; j++)	  for (int k = 0; k < nagents.length; k++)	    if (nagents[k].getShortName().equals(oagents[j].getShortName())) {	      if (log.isDebugEnabled()) {		log.debug("copy: Putting ne Agent " + nagents[k].getShortName() + " on new Node " + nnodes[i].getShortName());	      }	      nnodes[i].addAgent(nagents[k]);	    }      }    }    // copy the results directory; results from the copied experiment    // will be stored in this directory under the copied experiment name    experimentCopy.setResultDirectory(getResultDirectory());        return experimentCopy;  }