package org.eclipse.stem.populationmodels.standard.impl;

/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.stem.core.graph.DynamicLabel;
import org.eclipse.stem.core.graph.Edge;
import org.eclipse.stem.core.graph.Exchange;
import org.eclipse.stem.core.graph.ExchangeType;
import org.eclipse.stem.core.graph.Graph;
import org.eclipse.stem.core.graph.GraphFactory;
import org.eclipse.stem.core.graph.IntegrationLabelValue;
import org.eclipse.stem.core.graph.LabelValue;
import org.eclipse.stem.core.graph.Node;
import org.eclipse.stem.core.graph.NodeLabel;
import org.eclipse.stem.core.model.STEMTime;
import org.eclipse.stem.core.scenario.ScenarioInitializationException;
import org.eclipse.stem.definitions.labels.PopulationLabelValue;
import org.eclipse.stem.definitions.transport.PipeStyleTransportSystem;
import org.eclipse.stem.definitions.transport.PipeTransportEdge;
import org.eclipse.stem.definitions.transport.PipeTransportEdgeLabelValue;
import org.eclipse.stem.populationmodels.standard.PopulationModelLabel;
import org.eclipse.stem.populationmodels.standard.PopulationModelLabelValue;
import org.eclipse.stem.populationmodels.standard.StandardFactory;
import org.eclipse.stem.populationmodels.standard.StandardPackage;
import org.eclipse.stem.populationmodels.standard.StandardPopulationModel;
import org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabel;
import org.eclipse.stem.populationmodels.standard.StandardPopulationModelLabelValue;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Population Model</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.stem.populationmodels.standard.impl.StandardPopulationModelImpl#getBirthRate <em>Birth Rate</em>}</li>
 *   <li>{@link org.eclipse.stem.populationmodels.standard.impl.StandardPopulationModelImpl#getDeathRate <em>Death Rate</em>}</li>
 *   <li>{@link org.eclipse.stem.populationmodels.standard.impl.StandardPopulationModelImpl#getTimePeriod <em>Time Period</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class StandardPopulationModelImpl extends PopulationModelImpl implements StandardPopulationModel {
	/**
	 * The default value of the '{@link #getBirthRate() <em>Birth Rate</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBirthRate()
	 * @generated
	 * @ordered
	 */
	protected static final double BIRTH_RATE_EDEFAULT = 0.0;

	/**
	 * The cached value of the '{@link #getBirthRate() <em>Birth Rate</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getBirthRate()
	 * @generated
	 * @ordered
	 */
	protected double birthRate = BIRTH_RATE_EDEFAULT;

	/**
	 * The default value of the '{@link #getDeathRate() <em>Death Rate</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDeathRate()
	 * @generated
	 * @ordered
	 */
	protected static final double DEATH_RATE_EDEFAULT = 0.0;

	/**
	 * The cached value of the '{@link #getDeathRate() <em>Death Rate</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDeathRate()
	 * @generated
	 * @ordered
	 */
	protected double deathRate = DEATH_RATE_EDEFAULT;

	/**
	 * The default value of the '{@link #getTimePeriod() <em>Time Period</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTimePeriod()
	 * @generated
	 * @ordered
	 */
	protected static final long TIME_PERIOD_EDEFAULT = 86400000L;

	/**
	 * The cached value of the '{@link #getTimePeriod() <em>Time Period</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTimePeriod()
	 * @generated
	 * @ordered
	 */
	protected long timePeriod = TIME_PERIOD_EDEFAULT;

	protected Map<Node, List<PipeTransportEdge>> pipeTransportationNodeEdgesMap;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public StandardPopulationModelImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return StandardPackage.Literals.STANDARD_POPULATION_MODEL;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public double getBirthRate() {
		return birthRate;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setBirthRate(double newBirthRate) {
		double oldBirthRate = birthRate;
		birthRate = newBirthRate;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.STANDARD_POPULATION_MODEL__BIRTH_RATE, oldBirthRate, birthRate));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public double getDeathRate() {
		return deathRate;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDeathRate(double newDeathRate) {
		double oldDeathRate = deathRate;
		deathRate = newDeathRate;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.STANDARD_POPULATION_MODEL__DEATH_RATE, oldDeathRate, deathRate));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public long getTimePeriod() {
		return timePeriod;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTimePeriod(long newTimePeriod) {
		long oldTimePeriod = timePeriod;
		timePeriod = newTimePeriod;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, StandardPackage.STANDARD_POPULATION_MODEL__TIME_PERIOD, oldTimePeriod, timePeriod));
	}

	/**
	 * Decorate the graph for a standard population model
	 * 
	 */
	@Override
	public void decorateGraph(STEMTime time) throws ScenarioInitializationException {
		if(this.isGraphDecorated()) return;
		super.decorateGraph(time);
		return;
	} // decorateGraph
	
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case StandardPackage.STANDARD_POPULATION_MODEL__BIRTH_RATE:
				return getBirthRate();
			case StandardPackage.STANDARD_POPULATION_MODEL__DEATH_RATE:
				return getDeathRate();
			case StandardPackage.STANDARD_POPULATION_MODEL__TIME_PERIOD:
				return getTimePeriod();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case StandardPackage.STANDARD_POPULATION_MODEL__BIRTH_RATE:
				setBirthRate((Double)newValue);
				return;
			case StandardPackage.STANDARD_POPULATION_MODEL__DEATH_RATE:
				setDeathRate((Double)newValue);
				return;
			case StandardPackage.STANDARD_POPULATION_MODEL__TIME_PERIOD:
				setTimePeriod((Long)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case StandardPackage.STANDARD_POPULATION_MODEL__BIRTH_RATE:
				setBirthRate(BIRTH_RATE_EDEFAULT);
				return;
			case StandardPackage.STANDARD_POPULATION_MODEL__DEATH_RATE:
				setDeathRate(DEATH_RATE_EDEFAULT);
				return;
			case StandardPackage.STANDARD_POPULATION_MODEL__TIME_PERIOD:
				setTimePeriod(TIME_PERIOD_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case StandardPackage.STANDARD_POPULATION_MODEL__BIRTH_RATE:
				return birthRate != BIRTH_RATE_EDEFAULT;
			case StandardPackage.STANDARD_POPULATION_MODEL__DEATH_RATE:
				return deathRate != DEATH_RATE_EDEFAULT;
			case StandardPackage.STANDARD_POPULATION_MODEL__TIME_PERIOD:
				return timePeriod != TIME_PERIOD_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (birthRate: ");
		result.append(birthRate);
		result.append(", deathRate: ");
		result.append(deathRate);
		result.append(", timePeriod: ");
		result.append(timePeriod);
		result.append(')');
		return result.toString();
	}

	@Override
	public PopulationModelLabel createPopulationLabel() {
		PopulationModelLabel retValue =  StandardFactory.eINSTANCE.createStandardPopulationModelLabel();
		retValue.setTypeURI(PopulationModelLabel.URI_TYPE_DYNAMIC_POPULATION_LABEL);
		return retValue;
	}

	@Override
	public PopulationModelLabelValue createPopulationLabelValue() {
		return StandardFactory.eINSTANCE.createStandardPopulationModelLabelValue();
	}

	/**
	 * Compute the changes in the population from the birth/death rate
	 * adjusted for the time period used in the simulation
	 * @param time
	 * @param timeDelta
	 * @param labels
	 */
	public void calculateDelta(STEMTime time, long timeDelta,
			EList<DynamicLabel> labels) {
		// We simply calculate the change from the birth/death rate
		// adjusted for the time period used in the simulation
		
		double adjustedBirthRate = adjustRate(this.getBirthRate(), this.getTimePeriod(), timeDelta);
		double adjustedDeathRate = adjustRate(this.getDeathRate(), this.getTimePeriod(), timeDelta);
		
		for(DynamicLabel label:labels) {
			StandardPopulationModelLabelImpl slabel = (StandardPopulationModelLabelImpl)label;
			StandardPopulationModelLabelValueImpl delta = (StandardPopulationModelLabelValueImpl)slabel.getDeltaValue();
			StandardPopulationModelLabelValue current = (StandardPopulationModelLabelValue)slabel.getProbeValue();
			
			double currentPopulation = current.getCount();
			double births = currentPopulation * adjustedBirthRate;
			double deaths = currentPopulation * adjustedDeathRate;
			delta.setCount(births-deaths);
			delta.setBirths(births);
			delta.setDeaths(deaths);
			
			Exchange birthExchange = GraphFactory.eINSTANCE.createExchange();
			Exchange deathExchange = GraphFactory.eINSTANCE.createExchange();
			
			birthExchange.setType(ExchangeType.BIRTHS_AND_DEATHS);
			birthExchange.setCount(births);
			deathExchange.setType(ExchangeType.BIRTHS_AND_DEATHS);
			deathExchange.setCount(deaths);
			delta.getArrivals().clear();
			delta.getDepartures().clear();
			delta.getArrivals().add(birthExchange);
			delta.getDepartures().add(deathExchange);
			
			handleMigration(slabel, delta.getArrivals(),delta.getDepartures(), this.getTimePeriod(), timeDelta, delta);
			handlePipeTransport(slabel, delta.getArrivals(),delta.getDepartures(), timeDelta, delta);
			ECollections.sort(delta.getArrivals());
			ECollections.sort(delta.getDepartures());
		}
	}// calculateDelta

	
	
	
	
	
	protected void handlePipeTransport(StandardPopulationModelLabelImpl populationLabel, EList<Exchange>arrivals,EList<Exchange>departures, long timeDelta, StandardPopulationModelLabelValueImpl delta) {
		// Get the pipe transport edges to/from the node
		Node node = populationLabel.getNode();
		List<PipeTransportEdge>pedges = pipeTransportationNodeEdgesMap.get(node);
		if(pedges == null) return; // no edges
		
		// Now figure out how many people to actually move between nodes
		for(PipeTransportEdge pedge:pedges) {
			if(!pedge.getPopulationIdentifier().equals(this.getPopulationIdentifier())) continue; // wrong population
			
			boolean incomming = pedge.getB().equals(node);
			if(incomming) {
				for(NodeLabel lab: pedge.getA().getLabels()) {
					if(lab instanceof StandardPopulationModelLabel && ((StandardPopulationModelLabel)lab).getPopulationIdentifier().equals(populationLabel.getPopulationIdentifier())) {
						StandardPopulationModelLabel otherLabel = (StandardPopulationModelLabel)lab;
						StandardPopulationModelLabelValue otherValue = (StandardPopulationModelLabelValue)otherLabel.getTempValue();
						StandardPopulationModelLabelValue change = (StandardPopulationModelLabelValue)EcoreUtil.copy(otherValue);
						PipeTransportEdgeLabelValue edgeLabelValue =  (PipeTransportEdgeLabelValue)pedge.getLabel().getCurrentValue();
						double maxFlow = edgeLabelValue.getMaxFlow();
						double flow = maxFlow;
						double popCount = ((StandardPopulationModelLabelValue)otherLabel.getTempValue()).getCount();
						if(flow > popCount) 
							flow = popCount; // don't move more people than available.
						
						long timePeriod = edgeLabelValue.getTimePeriod();
						double factor = flow / popCount;
						
						factor = factor * timeDelta / timePeriod;
						if(Double.isNaN(factor) || Double.isInfinite(factor)) factor = 0.0;
						change.scale(factor);
						
						delta.add((IntegrationLabelValue)change);
						
						Exchange migrationExchange = GraphFactory.eINSTANCE.createExchange();
						
						migrationExchange.setType(ExchangeType.MIGRATION);
						migrationExchange.setOtherLabel(otherLabel);
						migrationExchange.setCount(change.getCount());
						delta.getArrivals().add(migrationExchange);
						break;
					}
				}
			} else { // outgoing edge
				for(NodeLabel lab: pedge.getB().getLabels()) {
					if(lab instanceof StandardPopulationModelLabel && ((StandardPopulationModelLabel)lab).getPopulationIdentifier().equals(populationLabel.getPopulationIdentifier())) {
						StandardPopulationModelLabel otherLabel = (StandardPopulationModelLabel)lab;
						StandardPopulationModelLabelValue thisValue = (StandardPopulationModelLabelValue)populationLabel.getTempValue();
						StandardPopulationModelLabelValue change = (StandardPopulationModelLabelValue)EcoreUtil.copy(thisValue);
						PipeTransportEdgeLabelValue edgeLabelValue =  (PipeTransportEdgeLabelValue)pedge.getLabel().getCurrentValue();
						double maxFlow = edgeLabelValue.getMaxFlow();
						double popCount = ((StandardPopulationModelLabelValue)populationLabel.getTempValue()).getCount();
						double flow = maxFlow;
						if(flow > popCount) 
							flow = popCount;

						long timePeriod = edgeLabelValue.getTimePeriod();
						double factor = flow / popCount;
						factor = factor * timeDelta / timePeriod;
						if(Double.isNaN(factor) || Double.isInfinite(factor)) factor = 0.0;
						change.scale(factor);
						
						delta.sub((IntegrationLabelValue)change);
						
						Exchange migrationExchange = GraphFactory.eINSTANCE.createExchange();
						
						migrationExchange.setType(ExchangeType.MIGRATION);
						migrationExchange.setOtherLabel(otherLabel);
						migrationExchange.setCount(change.getCount());
						delta.getDepartures().add(migrationExchange);
						break;
					}
				}
			}
		} // for each edge		
	}
	
	protected double adjustRate(double rate, long ratePeriod, long actualPeriod) {
		return rate * ((double)actualPeriod/(double)ratePeriod);
	}
	
	public void doModelSpecificAdjustments(LabelValue label) {
		// TODO Auto-generated method stub
		
	}

	
	public boolean isDeterministic() {
		return true;
	}

	@SuppressWarnings("boxing")
	protected void populatePipeSystemNodes() {
		Graph graph = this.getGraph();
		
		if(pipeTransportationNodeEdgesMap == null)  initPipeTransport(graph);
		
		for(Map.Entry<Node, List<PipeTransportEdge>>entry:pipeTransportationNodeEdgesMap.entrySet()) {
			Node n = entry.getKey();
			if(n instanceof PipeStyleTransportSystem) {
				// We need to create an initial population here. 
				// We do this by looking at all incoming pipe edges to the node and add up the total flow.
				List<PipeTransportEdge>pipeEdges = entry.getValue();
				double totalPop = 0.0;
				for(PipeTransportEdge pedge:pipeEdges) 
					if(pedge.getB().equals(n)) 
						totalPop += ((PipeTransportEdgeLabelValue) pedge.getLabel().getCurrentValue()).getMaxFlow();
			
				for(NodeLabel nlabel:n.getLabels()) {
					if(nlabel instanceof StandardPopulationModelLabel && ((StandardPopulationModelLabel)nlabel).getPopulationIdentifier().equals(this.getPopulationIdentifier())) {
						StandardPopulationModelLabelValue splv = (StandardPopulationModelLabelValue)((StandardPopulationModelLabel)nlabel).getCurrentValue();
						splv.setCount(totalPop);
						PopulationLabelValue plv = (PopulationLabelValue)((StandardPopulationModelLabel)nlabel).getPopulationLabel().getCurrentPopulationValue();
						plv.setCount(totalPop);
					}
				}
			}
		}

		/*Map<Integer, List<PipeTransportEdge>> map = pipeTransportationUpEdgesMap;
		
		Integer [] levels = new Integer[map.keySet().size()];
		levels = map.keySet().toArray(levels);
		Arrays.sort(levels, 0, levels.length, 
				new Comparator<Integer>() {
					public int compare(Integer o1, Integer o2) {
						if(o1 < o2) return 1;
					else if(o1 > o2) return -1;
						return 0;
					}
		});
		
		StandardPopulationModelLabelValue currsrclabelval=null, currdestlabelval=null;
		PopulationLabelValue staticDestLabelValue=null;
		
		// First, we clear out any existing population in the air transportation system nodes. If we don't do this, we will move more people than we
		// expect up into the air the second time we run the same scenario
		
		for(int level : levels) {
			List<PipeTransportEdge> edges = map.get(level);
			
			for(PipeTransportEdge ptedge:edges) {
				// Move people from source to destination using the flow of the pipe
				Node source = ptedge.getA();
				Node dest = ptedge.getB();
				if(source == null || dest == null) continue; // ok, the region or transport system is not part of the model
	
				String popIdSrc=null;
				for(NodeLabel nlabel:source.getLabels()) {
					if(nlabel instanceof PopulationModelLabel) {
						currsrclabelval = (StandardPopulationModelLabelValue)((PopulationModelLabel)nlabel).getCurrentValue();
						popIdSrc = ((PopulationModelLabel)nlabel).getPopulationIdentifier();
					} else continue;
				
					for(NodeLabel nlabel2:dest.getLabels()) {
						if(nlabel2 instanceof PopulationModelLabel &&
								((PopulationModelLabel)nlabel2).getPopulationIdentifier().equals(popIdSrc)) {
							((StandardPopulationModelLabelValue)((PopulationModelLabel)nlabel2).getCurrentValue()).setCount(0.0);
							((PopulationLabelValue)((PopulationModelLabel)nlabel2).getPopulationLabel().getCurrentValue()).setCount(0.0);
						}
					}
				}
			}
		}
		
		
		// Now, move people from the region nodes up into the air transportation nodes. We move exactly a fraction of people corresponding
		// to the passenger counts for each air (pipe) transport edge.
		
		
		for(int level : levels) {
			List<PipeTransportEdge> edges = map.get(level);
			
			for(PipeTransportEdge ptedge:edges) {
				// Move people from source to destination using the flow of the pipe
				Node source = ptedge.getA();
				Node dest = ptedge.getB();
				if(source == null || dest == null) continue; // ok, the region or transport system is not part of the model
				
				PipeTransportEdgeLabelValue label = (PipeTransportEdgeLabelValue) ptedge.getLabel().getCurrentValue();
				double maxflow = label.getMaxFlow();
				
				
				
				String popIdSrc=null;
				for(NodeLabel nlabel:source.getLabels()) {
					if(nlabel instanceof PopulationModelLabel) {
						currsrclabelval = (StandardPopulationModelLabelValue)((PopulationModelLabel)nlabel).getCurrentValue();
						popIdSrc = ((PopulationModelLabel)nlabel).getPopulationIdentifier();
					} else continue;
				
					for(NodeLabel nlabel2:dest.getLabels()) {
						if(nlabel2 instanceof PopulationModelLabel &&
								((PopulationModelLabel)nlabel2).getPopulationIdentifier().equals(popIdSrc)) {
							currdestlabelval = (StandardPopulationModelLabelValue)((PopulationModelLabel)nlabel2).getCurrentValue();
							staticDestLabelValue = (PopulationLabelValue)((PopulationModelLabel)nlabel2).getPopulationLabel().getCurrentValue();
						}
					}
					
					if(currsrclabelval == null || currdestlabelval == null) {
						continue; // possible for transport pipes connected to regions above the lowest region part of the model
					}
					
					// Check, make sure we don't move more people than available
					
					double flow = maxflow;	
					if(currsrclabelval.getCount() < flow) flow = currsrclabelval.getCount(); // check
					
					double factor = flow / currsrclabelval.getCount();
					if(Double.isNaN(factor)) factor = 0.0;
					
					StandardPopulationModelLabelValue move = null;
					
					move = (StandardPopulationModelLabelValue)EcoreUtil.copy(currsrclabelval);
					
					move.scale(factor);
				
					currdestlabelval.add((IntegrationLabelValue)move);
					
					// Also set the populationlabel to the count of the population model label since it's 0 for air transport nodes when built in STEM. Needed when we reset the value back to the original later
					staticDestLabelValue.setCount(currdestlabelval.getCount()+staticDestLabelValue.getCount());
				} // for each label on the source node
			}
		}
		
		// Check for nodes that have no initial population. Get rid of those
		ArrayList<Node>nodesToRemove = new ArrayList<Node>();
		for(Node n:pipeTransportationNodeEdgesMap.keySet()) {
			boolean remove = false;
			if( (n instanceof PipeStyleTransportSystemImpl)) {
				PipeStyleTransportSystemImpl psts = (PipeStyleTransportSystemImpl)n;
				for(NodeLabel l:psts.getLabels()) {
					if(l instanceof StandardPopulationModelLabel) {
						StandardPopulationModelLabel sl = (StandardPopulationModelLabel)l;
						StandardPopulationModelLabelValue slv = (StandardPopulationModelLabelValue)sl.getCurrentValue();
						if(slv.getCount() == 0.0) {
							remove = true;break;
						}
					}
					if(remove)break;
				}
				ArrayList<PipeTransportEdge>edgesToRemove = new ArrayList<PipeTransportEdge>();
				if(remove) {
					Activator.logInformation("Warning, ignoring air transportation node without population "+n, new Exception());
					nodesToRemove.add(n);
					// Remove all air transport edges using the node as well as the node itself
					for(List<PipeTransportEdge>l :pipeTransportationDownEdgesMap.values()) {
						for(PipeTransportEdge pse:l) {
							if(pse.getA() == null || pse.getB() == null) continue;
							if(pse.getA().equals(n) || pse.getB().equals(n)) {
								if(!edgesToRemove.contains(pse))edgesToRemove.add(pse);
							}
						}
					}
					for(List<PipeTransportEdge>l :pipeTransportationUpEdgesMap.values()) {
						for(PipeTransportEdge pse:l) {
							if(pse.getA() == null || pse.getB() == null) continue;
							if(pse.getA().equals(n) || pse.getB().equals(n)) {
								if(!edgesToRemove.contains(pse))edgesToRemove.add(pse);
							}
						}
					}
					for(PipeTransportEdge pse:edgesToRemove) { 
						for(List<PipeTransportEdge>l :pipeTransportationDownEdgesMap.values())
							l.remove(pse);
						for(List<PipeTransportEdge>l :pipeTransportationUpEdgesMap.values())
							l.remove(pse);
					}
					for(PipeTransportEdge pse:edgesToRemove) { 
						for(List<PipeTransportEdge>l :pipeTransportationNodeEdgesMap.values())
							l.remove(pse);
						for(List<PipeTransportEdge>l :pipeTransportationNodeEdgesMap.values())
							l.remove(pse);
					}
					
				}
			}
		}
		for(Node n:nodesToRemove) pipeTransportationNodeEdgesMap.remove(n);
		*/
	}
	
	/**
	 * initialize pipe transport maps organizing pipes by direction (up/down)
	 * and level
	 * @param graph
	 */
	@SuppressWarnings("boxing")
	private void initPipeTransport(Graph graph) {
		pipeTransportationNodeEdgesMap = new HashMap<Node, List<PipeTransportEdge>>();
		// Traverse all pipe transport edges and determine what
		// geographic level their source (A) node is at
		for(URI edgeURI : graph.getEdges().keySet()) {
			Edge edge = graph.getEdges().get(edgeURI);
			
			if(edge instanceof PipeTransportEdge) {
				PipeTransportEdge pedge = (PipeTransportEdge)edge;
								
				
				Node a = edge.getA();
				Node b = edge.getB();
				
				if(a != null)
					if(pipeTransportationNodeEdgesMap.containsKey(a))
						pipeTransportationNodeEdgesMap.get(a).add(pedge);
					else {
						ArrayList<PipeTransportEdge> newList = new ArrayList<PipeTransportEdge>();
						newList.add(pedge);
						pipeTransportationNodeEdgesMap.put(a, newList);
					}	
				
				if(b != null)
					if(pipeTransportationNodeEdgesMap.containsKey(b))
						pipeTransportationNodeEdgesMap.get(b).add(pedge);
					else {
						ArrayList<PipeTransportEdge> newList = new ArrayList<PipeTransportEdge>();
						newList.add(pedge);
						pipeTransportationNodeEdgesMap.put(b, newList);
					}	
			}
		}
		
		
		/*
		pipeTransportationUpEdgesMap = new HashMap<Integer, List<PipeTransportEdge>>();
		pipeTransportationDownEdgesMap = new HashMap<Integer, List<PipeTransportEdge>>();
		pipeTransportationNodeEdgesMap = new HashMap<Node, List<PipeTransportEdge>>();
		// Traverse all pipe transport edges and determine what
		// geographic level their source (A) node is at
		for(URI edgeURI : graph.getEdges().keySet()) {
			Edge edge = graph.getEdges().get(edgeURI);
			
			if(edge instanceof PipeTransportEdge) {
				PipeTransportEdge pedge = (PipeTransportEdge)edge;
				int beginLevel = Utility.keyLevel(edge.getNodeAURI().lastSegment());
				int endLevel = Utility.keyLevel(edge.getNodeBURI().lastSegment());
				
				Map<Integer, List<PipeTransportEdge>> map;
				if(beginLevel > endLevel) map = pipeTransportationUpEdgesMap;
				else map = pipeTransportationDownEdgesMap;
				
				if(map.containsKey(beginLevel)) {
					map.get(beginLevel).add(pedge);
				} else {
					ArrayList<PipeTransportEdge> list = new ArrayList<PipeTransportEdge>();
					list.add(pedge);
					map.put(beginLevel, list);
				}
				
				Node a = edge.getA();
				Node b = edge.getB();
				
				if(a != null)
					if(pipeTransportationNodeEdgesMap.containsKey(a))
						pipeTransportationNodeEdgesMap.get(a).add(pedge);
					else {
						ArrayList<PipeTransportEdge> newList = new ArrayList<PipeTransportEdge>();
						newList.add(pedge);
						pipeTransportationNodeEdgesMap.put(a, newList);
					}	
				
				if(b != null)
					if(pipeTransportationNodeEdgesMap.containsKey(b))
						pipeTransportationNodeEdgesMap.get(b).add(pedge);
					else {
						ArrayList<PipeTransportEdge> newList = new ArrayList<PipeTransportEdge>();
						newList.add(pedge);
						pipeTransportationNodeEdgesMap.put(b, newList);
					}	
			}
		}
		*/
	}
	
		
	
	@Override
	public void resetLabels() throws ScenarioInitializationException {
		super.resetLabels();
		// Populate the pipe transportation systems
		this.populatePipeSystemNodes();
	}
} //StandardPopulationModelImpl
