/** * 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; }