gt:                 pc = new PotentialComputeAggregate(pmBonding, pcPair);
context: /* This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
  package etomica.virial.simulations;
  
  
  import etomica.action.controller.Activity;
  import etomica.action.controller.Controller;
  import etomica.atom.AtomTypeOriented;
  import etomica.atom.IAtom;
  import etomica.atom.IAtomList;
  import etomica.data.*;
  import etomica.data.histogram.HistogramNotSoSimple;
  import etomica.data.histogram.HistogramSimple;
  import etomica.data.types.DataDoubleArray;
  import etomica.data.types.DataDoubleArray.DataInfoDoubleArray;
  import etomica.data.types.DataGroup;
  import etomica.integrator.Integrator;
  import etomica.integrator.IntegratorEvent;
  import etomica.integrator.IntegratorListener;
  import etomica.integrator.IntegratorMC;
  import etomica.integrator.mcmove.MCMoveBoxStep;
  import etomica.integrator.mcmove.MCMoveManager;
  import etomica.math.DoubleRange;
  import etomica.overlap.IntegratorOverlap;
  import etomica.potential.IPotential2;
  import etomica.potential.PotentialMasterBonding;
  import etomica.potential.compute.NeighborManagerIntra;
  import etomica.potential.compute.PotentialCompute;
  import etomica.potential.compute.PotentialComputeAggregate;
  import etomica.potential.compute.PotentialComputePair;
  import etomica.simulation.Simulation;
  import etomica.space.Space;
  import etomica.space.Vector;
  import etomica.species.ISpecies;
  import etomica.species.SpeciesManager;
  import etomica.units.dimensions.Null;
  import etomica.virial.BoxCluster;
  import etomica.virial.ConfigurationCluster;
  import etomica.virial.CoordinatePairSet;
  import etomica.virial.MeterVirial;
  import etomica.virial.cluster.ClusterAbstract;
  import etomica.virial.cluster.ClusterWeight;
  import etomica.virial.cluster.ClusterWeightAbs;
  import etomica.virial.mcmove.*;
  import etomica.virial.overlap.DataProcessorVirialOverlap;
  import etomica.virial.overlap.DataVirialOverlap;
  
  import java.io.*;
  import java.util.Arrays;
  
  /**
   * Simulation implementing the overlap-sampling approach to evaluating a cluster
   * diagram.
   * 
   * @author kofke, Andrew Schultz
   */
  public class SimulationVirialOverlap2 extends Simulation {
  
      public final AccumulatorRatioAverageCovarianceFull[] accumulators;
      public final BoxCluster[] box;
      public final IntegratorMC[] integrators;
      public final MeterVirial[] meters;
      public final DataProcessorVirialOverlap[] dpVirialOverlap;
      protected final ISpecies[] species;
      protected final double temperature;
      protected final ClusterAbstract[] valueClusters;
      protected final int[] nMolecules;
      protected final ClusterWeight[] sampleClusters;
      public DataVirialOverlap dvo;
      public AccumulatorAverageCovariance blockAccumulator;
      public MCMoveBoxStep[] mcMoveRotate;
      public MCMoveBoxStep[] mcMoveTranslate;
      public MCMoveBoxStep[] mcMoveWiggle;
      public int numExtraTargetClusters;
  
      public IntegratorOverlap integratorOS;
      public double refPref;
      protected boolean initialized;
      protected boolean doWiggle;
      protected ClusterAbstract[] extraTargetClusters;
      public DataPumpListener[] accumulatorPumps;
      protected long blockSize;
      protected int numAlpha = 1;
      protected HistogramSimple targHist;
      protected HistogramNotSoSimple targPiHist;
      protected double[] boxLengths = new double[]{0, 0};
      protected PotentialMasterBonding.FullBondingInfo bondingInfo;
      protected IPotential2[][] pairPotentials;
      protected PotentialComputeFactory potentialComputeFactory;
  
      /**
       * This constructor will create your simulation class, but you may call
       * set methods before using it.  When you are done calling set methods,
       * you must call init() before using it.
       */
      public SimulationVirialOverlap2(Space aSpace, ISpecies species, int nMolecules,
                                      double temperature, ClusterAbstract refCluster, ClusterAbstract targetCluster) {
          this(aSpace, new ISpecies[]{species}, new int[]{nMolecules}, temperature, refCluster, targetCluster);
      }
  
      /**
       * This constructor will create your simulation class, but you may call
       * set methods before using it.  When you are done calling set methods,
       * you must call init() before using it.
       */
      public SimulationVirialOverlap2(Space aSpace, SpeciesManager sm, int nMolecules,
                                      double temperature, ClusterAbstract refCluster, ClusterAbstract targetCluster) {
          super(aSpace, sm);
          this.temperature = temperature;
          this.species = new ISpecies[0];
          this.nMolecules = new int[]{nMolecules};
          valueClusters = new ClusterAbstract[]{refCluster, targetCluster};
          sampleClusters = new ClusterWeight[]{ClusterWeightAbs.makeWeightCluster(refCluster), ClusterWeightAbs.makeWeightCluster(targetCluster)};
          meters = new MeterVirial[2];
          integrators = new IntegratorMC[2];
          dpVirialOverlap = new DataProcessorVirialOverlap[2];
          box = new BoxCluster[2];
          accumulators = new AccumulatorRatioAverageCovarianceFull[2];
          extraTargetClusters = new ClusterAbstract[0];
      }
  
      /**
       * This constructor will create your simulation class, but you may call
       * set methods before using it.  When you are done calling set methods,
       * you must call init() before using it.
       */
      public SimulationVirialOverlap2(Space aSpace, ISpecies[] species, int[] nMolecules,
                                      double temperature, ClusterAbstract refCluster, ClusterAbstract targetCluster) {
          super(aSpace);
          this.species = species;
          this.temperature = temperature;
          this.nMolecules = nMolecules;
          valueClusters = new ClusterAbstract[]{refCluster, targetCluster};
          sampleClusters = new ClusterWeight[]{ClusterWeightAbs.makeWeightCluster(refCluster),ClusterWeightAbs.makeWeightCluster(targetCluster)};
          meters = new MeterVirial[2];
          integrators = new IntegratorMC[2];
          dpVirialOverlap = new DataProcessorVirialOverlap[2];
          box = new BoxCluster[2];
          accumulators = new AccumulatorRatioAverageCovarianceFull[2];
          extraTargetClusters = new ClusterAbstract[0];
      }
  
      public void setPotentialComputeFactory(PotentialComputeFactory potentialComputeFactory) {
          this.potentialComputeFactory = potentialComputeFactory;
      }
  
      public boolean getDoWiggle() {
          return doWiggle;
      }
  
      public void setDoWiggle(boolean newDoWiggle) {
          if (initialized) throw new RuntimeException("too late");
          doWiggle = newDoWiggle;
      }
  
      public ClusterAbstract[] getExtraTargetClusters() {
          return extraTargetClusters;
      }
  
      public void setExtraTargetClusters(ClusterAbstract[] extraTargetClusters) {
          if (initialized) throw new RuntimeException("too late");
          this.extraTargetClusters = extraTargetClusters;
      }
  
      public ClusterWeight[] getSampleClusters() {
          return sampleClusters;
      }
  
      public void setSampleClusters(ClusterWeight[] sampleClusters) {
          if (initialized) throw new RuntimeException("too late");
          this.sampleClusters[0] = sampleClusters[0];
          this.sampleClusters[1] = sampleClusters[1];
      }
  
      public void setBoxLengths(double refLength, double targetLength) {
          if (initialized) throw new RuntimeException("too late");
          boxLengths[0] = refLength;
          boxLengths[1] = targetLength;
      }
  
      public void setIntraPairPotentials(IPotential2[][] pairPotentials) {
          if (initialized) throw new RuntimeException("too late");
          this.pairPotentials = pairPotentials;
      }
  
      public void setBondingInfo(PotentialMasterBonding.FullBondingInfo bondingInfo) {
          this.bondingInfo = bondingInfo;
      }
  
      public void init() {
          if (initialized) throw new RuntimeException("you can only call me once");
          // we aren't actually initialized yet, but we will be unless we crash.
          // if we crash, we shouldn't get called again!
          initialized = true;
  
          numExtraTargetClusters = extraTargetClusters.length;
          boolean doRotate = false;
          boolean multiAtomic = false;
          for (int i = 0; i < species.length; i++) {
              addSpecies(species[i]);
          }
          for (ISpecies sp : getSpeciesList()) {
              if (sp.getLeafAtomCount() == 1 && sp.getLeafType() instanceof AtomTypeOriented) {
                  doRotate = true;
              }
              if (sp.getLeafAtomCount() > 1) {
                  multiAtomic = true;
              }
          }
          accumulatorPumps = new DataPumpListener[2];
          mcMoveTranslate = new MCMoveBoxStep[2];
          if (doRotate || multiAtomic) {
              mcMoveRotate = new MCMoveBoxStep[2];
          }
          if (doWiggle) {
              mcMoveWiggle = new MCMoveBoxStep[2];
          }
  
          blockSize = 1000;
  
          for (int iBox=0; iBox<2; iBox++) {
              // integrator for iBox samples based on iBox cluster
              box[iBox] = new BoxCluster(sampleClusters[iBox], space, boxLengths[iBox]);
              addBox(box[iBox]);
              for (ISpecies sp : getSpeciesList()) {
                  box[iBox].setNMolecules(sp, nMolecules[sp.getIndex()]);
              }
  
              PotentialCompute pc = null;
              if (potentialComputeFactory != null) {
                  pc = potentialComputeFactory.makePotentialCompute(getSpeciesManager(), box[iBox]);
              }
              else if (pairPotentials != null) {
                  PotentialMasterBonding pmBonding = new PotentialMasterBonding(getSpeciesManager(), box[iBox], bondingInfo);
                  PotentialComputePair pcPair = new PotentialComputePair(getSpeciesManager(), box[iBox], new NeighborManagerIntra(box[iBox], bondingInfo), pairPotentials);
  