/**
  * create new instance of src object, connecting all inputs from src object Note if input is a
  * SubstModel, it is duplicated as well.
  *
  * @param src object to be copied
  * @param i index used to extend ID with.
  * @return copy of src object
  */
 private Object duplicate(BEASTInterface src, int i) {
   if (src == null) {
     return null;
   }
   BEASTInterface copy;
   try {
     copy = src.getClass().newInstance();
     copy.setID(src.getID() + "_" + i);
   } catch (InstantiationException | IllegalAccessException e) {
     e.printStackTrace();
     throw new RuntimeException(
         "Programmer error: every object in the model should have a default constructor that is publicly accessible: "
             + src.getClass().getName());
   }
   for (Input<?> input : src.listInputs()) {
     if (input.get() != null) {
       if (input.get() instanceof List) {
         // handle lists
         // ((List)copy.getInput(input.getName())).clear();
         for (Object o : (List<?>) input.get()) {
           if (o instanceof BEASTInterface) {
             // make sure it is not already in the list
             copy.setInputValue(input.getName(), o);
           }
         }
       } else if (input.get() instanceof SubstitutionModel) {
         // duplicate subst models
         BEASTInterface substModel = (BEASTInterface) duplicate((BEASTInterface) input.get(), i);
         copy.setInputValue(input.getName(), substModel);
       } else {
         // it is some other value
         copy.setInputValue(input.getName(), input.get());
       }
     }
   }
   copy.initAndValidate();
   return copy;
 }