public KSTransition deepCopy(KSState sa, KSState sb) {
    FunctionTransition ret = makeCopy(sa, sb);

    for (Constant c : constants) {
      ret.addConstant(c.makeCopy());
    }

    // TODO shallow copy OK??
    ret.setFunctions(funcs);

    ret.refTransition = null;
    return ret;
  }
  public FunctionTransition makeCopy(KSState sa, KSState sb) {
    FunctionTransition ret = makeLocalCopy();
    ret.setEnds(sa, sb);

    ret.constants = constants;
    ret.funcs = funcs;
    ret.assignments = assignments;

    FunctionTransition rtr = this;
    while (rtr.refTransition != null) {
      rtr = rtr.refTransition;
    }
    ret.refTransition = rtr;
    //	E.info("copied coded transition from " + hashCode() + " to " + ret.hashCode() + " " +
    // rtr.getSysID());

    ret.fwdFactor = fwdFactor;
    ret.revFactor = revFactor;
    copyTemperatureTo(ret);
    return ret;
  }
 // N.B. two copies here: shallow used for expanding out multi-complex chanels, so that we
 // end up using the same evaluator object.
 // deep is used for derived channels where one is like another but with some parameter changes
 // in coded transitions. All copies for non coded transitions are deep
 public FunctionTransition makeMultiCopy(KSState sa, KSState sb, double ff, double fr) {
   FunctionTransition ret = makeCopy(sa, sb);
   ret.applyMultipliers(ff, fr);
   return ret;
 }