Task (Elaboration / Additional Code): Implement additionOperator: rebuilds architecture, instantiates new model, adds to parent, and synchronizes.
Solution: add additional code
<%

	public void additionOperator(String constType) {
		connections.clear();
		for(Coupling e : getParent().getCouplings()) {
			if(!e.getSource().getName().contains("StimuliGenerator") && !e.getDestination().getName().contains("DRC"))
				connections.add(new Connection((AtomicModelImpl) e.getSource(), e.getSourcePort(), (AtomicModelImpl)e.getDestination(), e.getDestinationPort()));
		}	
		constituents = initializeConstituents();
		if(constType.equalsIgnoreCase("sensor")) {
			AtomicModelImpl toAdd = null;
			for(AtomicModelImpl e : originalConstituents) {
				if(getTypeCons(e).equals("Sensor")) {
					try{
						toAdd = e.getClass().newInstance();
						break;
					}catch(Exception LastHope) {}
				}
			}
			addConstituentSensor(toAdd, true);
			syncModel();
			return;
		}
		if(constType.equalsIgnoreCase("gateway")) {
			AtomicModelImpl toAdd = null;
			for(AtomicModelImpl e : originalConstituents) {
				if(getTypeCons(e).equals("Gateway")) {
					try{
						toAdd = e.getClass().newInstance();
						break;
					}catch(Exception LastHope) {}
				}
			}
			CoupledModelImpl parent = (CoupledModelImpl)getParent();
			toAdd.setName("GatewayRec" + contRecGateway);
			contRecGateway++;
			parent.addChildModel(toAdd);
			ArrayList<AtomicModelImpl> aux = new ArrayList<AtomicModelImpl>();
			ArrayList<Connection> auxC = new ArrayList<Connection>();
			Random rand = new Random();
			
			gateways.add(toAdd);
			
			for (Connection e : connections) {
				if (getTypeCons(e.inClass).equals("Transmitter")) {
					auxC.add(e);
					aux.add(e.inClass);
				} else if (getTypeCons(e.outClass).equals("Transmitter")) {
					auxC.add(e);
					aux.add(e.outClass);
				}
			}
			
			for (AtomicModelImpl e : aux) {
				parent.removeChildModel(e);
				mS4MESimulationInterface.finalizeConstituent(e);
				constituents.remove(e);
				transmitters.remove(e);
			}
			aux.clear();
			connections.removeAll(auxC);
			
			aux.clear();
			for(AtomicModelImpl e : sensors)
				if(!aux.contains(e))
					aux.add(e);    
			for(AtomicModelImpl e : gateways) {
				if(aux.size() == 0) {
					break;
				}
				int j = rand.nextInt(aux.size());
				recConnectionAdd(aux.get(j), e);
				aux.remove(aux.get(j));
			}
			while (aux.size() > 0) {
				int j = rand.nextInt(aux.size());
				addConstituentSensor(aux.get(j), false);
				aux.remove(aux.get(j));
			}
			
			parent.addCoupling(toAdd.getOutputPort("outRemove"),this.inRemove);
			constituents.addAll(gateways);
			syncModel();
			return;
		}
		if(constType.equalsIgnoreCase("crowd")) {
			AtomicModelImpl toAdd = null;
			for(AtomicModelImpl e : originalConstituents) {
				if(getTypeCons(e).equals("Crowd")) {
					try{
						toAdd = e.getClass().newInstance();
						break;
					}catch(Exception LastHope) {}
				}
			}
			addConstituentCrowd(toAdd, true);
			syncModel();
			return;
		}
		if(constType.equalsIgnoreCase("crowdGateway")) {
			AtomicModelImpl toAdd = null;
			for(AtomicModelImpl e : originalConstituents) {
				if(getTypeCons(e).equals("CrowdGateway")) {
					try{
						toAdd = e.getClass().newInstance();
						break;
					}catch(Exception LastHope) {}
				}
			}
			CoupledModelImpl parent = (CoupledModelImpl)getParent();
			toAdd.setName("CrowdGatewayRec" + contRecCrowdGateway);
			contRecCrowdGateway++;
			parent.addChildModel(toAdd);
			ArrayList<AtomicModelImpl> aux = new ArrayList<AtomicModelImpl>();
			ArrayList<Connection> auxC = new ArrayList<Connection>();
			Random rand = new Random();
			
			crowdGateways.add(toAdd);
			
			for (Connection e : connections) {
				if (getTypeCons(e.inClass).equals("CrowdTransmitter")) {
					auxC.add(e);
					aux.add(e.inClass);
				} else if (getTypeCons(e.outClass).equals("CrowdTransmitter")) {
					auxC.add(e);
					aux.add(e.outClass);
				}
			}
			
			for (AtomicModelImpl e : aux) {
				parent.removeChildModel(e);
				mS4MESimulationInterface.finalizeConstituent(e);
				constituents.remove(e);
				crowdTransmitters.remove(e);
			}
			aux.clear();
			connections.removeAll(auxC);
			
			aux.clear();
			for(AtomicModelImpl e : crowds)
				if(!aux.contains(e))
					aux.add(e);    
			for(AtomicModelImpl e : crowdGateways) {
				if(aux.size() == 0) {
					break;
				}
				int j = rand.nextInt(aux.size());
				recConnectionAdd(aux.get(j), e);
				aux.remove(aux.get(j));
			}
			while (aux.size() > 0) {
				int j = rand.nextInt(aux.size());
				addConstituentCrowd(aux.get(j), false);
				aux.remove(aux.get(j));
			}
			
			parent.addCoupling(toAdd.getOutputPort("outRemove"),this.inRemove);
			constituents.addAll(crowdGateways);
			syncModel();
			return;
		}
		if(constType.equalsIgnoreCase("drone")) {
			AtomicModelImpl toAdd = null;
			for(AtomicModelImpl e : originalConstituents) {
				if(getTypeCons(e).equals("Drone")) {
					try{
						toAdd = e.getClass().newInstance();
						break;
					}catch(Exception LastHope) {}
				}
			}
			addConstituentDrone(toAdd, true);
			syncModel();
			return;
		}
		if(constType.equalsIgnoreCase("droneBasis")) {
			AtomicModelImpl toAdd = null;
			for(AtomicModelImpl e : originalConstituents) {
				if(getTypeCons(e).equals("DroneBasis")) {
					try{
						toAdd = e.getClass().newInstance();
						break;
					}catch(Exception LastHope) {}
				}
			}
			CoupledModelImpl parent = (CoupledModelImpl)getParent();
			toAdd.setName("DroneBasisRec" + contRecDroneBasis);
			contRecDroneBasis++;
			parent.addChildModel(toAdd);
			ArrayList<AtomicModelImpl> aux = new ArrayList<AtomicModelImpl>();
			ArrayList<Connection> auxC = new ArrayList<Connection>();
			Random rand = new Random();
			
			droneBasiss.add(toAdd);
			
			for (Connection e : connections) {
				if (getTypeCons(e.inClass).equals("DroneTransmitter")) {
					auxC.add(e);
					aux.add(e.inClass);
				} else if (getTypeCons(e.outClass).equals("DroneTransmitter")) {
					auxC.add(e);
					aux.add(e.outClass);
				}
			}
			
			for (AtomicModelImpl e : aux) {
				parent.removeChildModel(e);
				mS4MESimulationInterface.finalizeConstituent(e);
				constituents.remove(e);
				droneTransmitters.remove(e);
			}
			aux.clear();
			connections.removeAll(auxC);
			
			aux.clear();
			for(AtomicModelImpl e : drones)
				if(!aux.contains(e))
					aux.add(e);    
			for(AtomicModelImpl e : droneBasiss) {
				if(aux.size() == 0) {
					break;
				}
				int j = rand.nextInt(aux.size());
				recConnectionAdd(aux.get(j), e);
				aux.remove(aux.get(j));
			}
			while (aux.size() > 0) {
				int j = rand.nextInt(aux.size());
				addConstituentDrone(aux.get(j), false);
				aux.remove(aux.get(j));
			}
			
			parent.addCoupling(toAdd.getOutputPort("outRemove"),this.inRemove);
			constituents.addAll(droneBasiss);
			syncModel();
			return;
		}
	}
	
	private void addConstituentSensor(AtomicModelImpl toAdd, boolean add) {
		CoupledModelImpl parent = (CoupledModelImpl)getParent();
		if(add) {
			toAdd.setName("SensorRec" + contRecSensor);
			parent.addChildModel(toAdd);
			StimuliGeneratorSensor4 toAdd2 = new StimuliGeneratorSensor4("StimuliGeneratorSensorRec"+contRecSensor);
			parent.addChildModel(toAdd2);
				
			for(Port<?> e : toAdd2.getOutputPorts()) {
				Port<?> aux = toAdd.getInputPort(e.getName().replace("out","in"));
				if(aux != null) {
					parent.addCoupling(e, aux);
					mS4MESimulationInterface.newLink(e, aux);
				}
			}
		}
		if(constituents.size() > 0 ) {
		AtomicModelImpl aux = getToConnectModel(toAdd);
			if(aux != null) {
			recConnectionAdd(toAdd,aux);
			}
		}
		if(add) {
			constituents.add(toAdd);
			sensors.add(toAdd);
			parent.addCoupling(toAdd.getOutputPort("outRemove"),this.inRemove);
			contRecSensor++;
		}
	}
	private void addConstituentCrowd(AtomicModelImpl toAdd, boolean add) {
		CoupledModelImpl parent = (CoupledModelImpl)getParent();
		if(add) {
			toAdd.setName("CrowdRec" + contRecCrowd);
			parent.addChildModel(toAdd);
			StimuliGeneratorCrowd2 toAdd2 = new StimuliGeneratorCrowd2("StimuliGeneratorCrowdRec"+contRecCrowd);
			parent.addChildModel(toAdd2);
				
			for(Port<?> e : toAdd2.getOutputPorts()) {
				Port<?> aux = toAdd.getInputPort(e.getName().replace("out","in"));
				if(aux != null) {
					parent.addCoupling(e, aux);
					mS4MESimulationInterface.newLink(e, aux);
				}
			}
		}
		if(constituents.size() > 0 ) {
		AtomicModelImpl aux = getToConnectModel(toAdd);
			if(aux != null) {
			recConnectionAdd(toAdd,aux);
			}
		}
		if(add) {
			constituents.add(toAdd);
			crowds.add(toAdd);
			parent.addCoupling(toAdd.getOutputPort("outRemove"),this.inRemove);
			contRecCrowd++;
		}
	}
	private void addConstituentDrone(AtomicModelImpl toAdd, boolean add) {
		CoupledModelImpl parent = (CoupledModelImpl)getParent();
		if(add) {
			toAdd.setName("DroneRec" + contRecDrone);
			parent.addChildModel(toAdd);
			StimuliGeneratorDrone4 toAdd2 = new StimuliGeneratorDrone4("StimuliGeneratorDroneRec"+contRecDrone);
			parent.addChildModel(toAdd2);
				
			for(Port<?> e : toAdd2.getOutputPorts()) {
				Port<?> aux = toAdd.getInputPort(e.getName().replace("out","in"));
				if(aux != null) {
					parent.addCoupling(e, aux);
					mS4MESimulationInterface.newLink(e, aux);
				}
			}
		}
		if(constituents.size() > 0 ) {
		AtomicModelImpl aux = getToConnectModel(toAdd);
			if(aux != null) {
			recConnectionAdd(toAdd,aux);
			}
		}
		if(add) {
			constituents.add(toAdd);
			drones.add(toAdd);
			parent.addCoupling(toAdd.getOutputPort("outRemove"),this.inRemove);
			contRecDrone++;
		}
	}
%>!