gt: 			if (l instanceof SimulationComputationListener) {
context: package net.sf.openrocket.simulation.listeners;
  
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import net.sf.openrocket.aerodynamics.AerodynamicForces;
  import net.sf.openrocket.aerodynamics.FlightConditions;
  import net.sf.openrocket.aerodynamics.Warning;
  import net.sf.openrocket.models.atmosphere.AtmosphericConditions;
  import net.sf.openrocket.motor.MotorId;
  import net.sf.openrocket.motor.MotorInstance;
  import net.sf.openrocket.rocketcomponent.MotorMount;
  import net.sf.openrocket.rocketcomponent.RecoveryDevice;
  import net.sf.openrocket.simulation.AccelerationData;
  import net.sf.openrocket.simulation.FlightEvent;
  import net.sf.openrocket.simulation.MassData;
  import net.sf.openrocket.simulation.SimulationStatus;
  import net.sf.openrocket.simulation.exception.SimulationException;
  import net.sf.openrocket.util.Coordinate;
  import net.sf.openrocket.util.MathUtil;
  
  /**
   * Helper methods for firing events to simulation listeners.
   * 
   * @author Sampo Niskanen <sampo.niskanen@iki.fi>
   */
  public class SimulationListenerHelper {
  	
  	private static final Logger log = LoggerFactory.getLogger(SimulationListenerHelper.class);
  	
  	////////  SimulationListener methods  ////////
  	
  
  	/**
  	 * Fire startSimulation event.
  	 */
  	public static void fireStartSimulation(SimulationStatus status)
  			throws SimulationException {
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			l.startSimulation(status);
  			if (modID != status.getModID()) {
  				warn(status, l);
  				modID = status.getModID();
  			}
  		}
  	}
  	
  	
  	/**
  	 * Fire endSimulation event.
  	 */
  	public static void fireEndSimulation(SimulationStatus status, SimulationException exception) {
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			l.endSimulation(status, exception);
  			if (modID != status.getModID()) {
  				warn(status, l);
  				modID = status.getModID();
  			}
  		}
  	}
  	
  	
  
  
  	/**
  	 * Fire preStep event.
  	 * 
  	 * @return	<code>true</code> to handle step normally, <code>false</code> to skip the step.
  	 */
  	public static boolean firePreStep(SimulationStatus status)
  			throws SimulationException {
  		boolean b;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			b = l.preStep(status);
  			if (modID != status.getModID()) {
  				warn(status, l);
  				modID = status.getModID();
  			}
  			if (b == false) {
  				warn(status, l);
  				return false;
  			}
  		}
  		return true;
  	}
  	
  	
  	/**
  	 * Fire postStep event.
  	 */
  	public static void firePostStep(SimulationStatus status)
  			throws SimulationException {
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			l.postStep(status);
  			if (modID != status.getModID()) {
  				warn(status, l);
  				modID = status.getModID();
  			}
  		}
  	}
  	
  	
  
  	////////  SimulationEventListener methods  ////////
  	
  	/**
  	 * Fire an add flight event event.
  	 * 
  	 * @return	<code>true</code> to add the event normally, <code>false</code> to skip adding the event.
  	 */
  	public static boolean fireAddFlightEvent(SimulationStatus status, FlightEvent event) throws SimulationException {
  		boolean b;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationEventListener) {
  				b = ((SimulationEventListener) l).addFlightEvent(status, event);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (b == false) {
  					warn(status, l);
  					return false;
  				}
  			}
  		}
  		return true;
  	}
  	
  	/**
  	 * Fire a handle flight event event.
  	 * 
  	 * @return	<code>true</code> to handle the event normally, <code>false</code> to skip event.
  	 */
  	public static boolean fireHandleFlightEvent(SimulationStatus status, FlightEvent event) throws SimulationException {
  		boolean b;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationEventListener) {
  				b = ((SimulationEventListener) l).handleFlightEvent(status, event);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (b == false) {
  					warn(status, l);
  					return false;
  				}
  			}
  		}
  		return true;
  	}
  	
  	/**
  	 * Fire motor ignition event.
  	 * 
  	 * @return	<code>true</code> to handle the event normally, <code>false</code> to skip event.
  	 */
  	public static boolean fireMotorIgnition(SimulationStatus status, MotorId motorId, MotorMount mount,
  			MotorInstance instance) throws SimulationException {
  		boolean b;
  		int modID = status.getModID(); // Contains also motor instance
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationEventListener) {
  				b = ((SimulationEventListener) l).motorIgnition(status, motorId, mount, instance);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (b == false) {
  					warn(status, l);
  					return false;
  				}
  			}
  		}
  		return true;
  	}
  	
  	
  	/**
  	 * Fire recovery device deployment event.
  	 * 
  	 * @return	<code>true</code> to handle the event normally, <code>false</code> to skip event.
  	 */
  	public static boolean fireRecoveryDeviceDeployment(SimulationStatus status, RecoveryDevice device)
  			throws SimulationException {
  		boolean b;
  		int modID = status.getModID(); // Contains also motor instance
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationEventListener) {
  				b = ((SimulationEventListener) l).recoveryDeviceDeployment(status, device);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (b == false) {
  					warn(status, l);
  					return false;
  				}
  			}
  		}
  		return true;
  	}
  	
  	
  	////////  SimulationComputationalListener methods  ////////
  	
  	/**
  	 * Fire preAtmosphericModel event.
  	 * 
  	 * @return	<code>null</code> normally, or overriding atmospheric conditions.
  	 */
  	public static AtmosphericConditions firePreAtmosphericModel(SimulationStatus status)
  			throws SimulationException {
  		AtmosphericConditions conditions;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				conditions = ((SimulationComputationListener) l).preAtmosphericModel(status);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (conditions != null) {
  					warn(status, l);
  					return conditions;
  				}
  			}
  		}
  		return null;
  	}
  	
  	/**
  	 * Fire postAtmosphericModel event.
  	 * 
  	 * @return	the atmospheric conditions to use.
  	 */
  	public static AtmosphericConditions firePostAtmosphericModel(SimulationStatus status, AtmosphericConditions conditions)
  			throws SimulationException {
  		AtmosphericConditions c;
  		AtmosphericConditions clone = conditions.clone();
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				c = ((SimulationComputationListener) l).postAtmosphericModel(status, clone);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (c != null && !c.equals(conditions)) {
  					warn(status, l);
  					conditions = c;
  					clone = conditions.clone();
  				}
  			}
  		}
  		return conditions;
  	}
  	
  	
  
  	/**
  	 * Fire preWindModel event.
  	 * 
  	 * @return	<code>null</code> normally, or overriding wind.
  	 */
  	public static Coordinate firePreWindModel(SimulationStatus status)
  			throws SimulationException {
  		Coordinate wind;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				wind = ((SimulationComputationListener) l).preWindModel(status);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (wind != null) {
  					warn(status, l);
  					return wind;
  				}
  			}
  		}
  		return null;
  	}
  	
  	/**
  	 * Fire postWindModel event.
  	 * 
  	 * @return	the wind to use.
  	 */
  	public static Coordinate firePostWindModel(SimulationStatus status, Coordinate wind) throws SimulationException {
  		Coordinate w;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				w = ((SimulationComputationListener) l).postWindModel(status, wind);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (w != null && !w.equals(wind)) {
  					warn(status, l);
  					wind = w;
  				}
  			}
  		}
  		return wind;
  	}
  	
  	
  
  	/**
  	 * Fire preGravityModel event.
  	 * 
  	 * @return	<code>NaN</code> normally, or overriding gravity.
  	 */
  	public static double firePreGravityModel(SimulationStatus status)
  			throws SimulationException {
  		double gravity;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				gravity = ((SimulationComputationListener) l).preGravityModel(status);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (!Double.isNaN(gravity)) {
  					warn(status, l);
  					return gravity;
  				}
  			}
  		}
  		return Double.NaN;
  	}
  	
  	/**
  	 * Fire postGravityModel event.
  	 * 
  	 * @return	the gravity to use.
  	 */
  	public static double firePostGravityModel(SimulationStatus status, double gravity) throws SimulationException {
  		double g;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				g = ((SimulationComputationListener) l).postGravityModel(status, gravity);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (!Double.isNaN(g) && !MathUtil.equals(g, gravity)) {
  					warn(status, l);
  					gravity = g;
  				}
  			}
  		}
  		return gravity;
  	}
  	
  	
  
  
  	/**
  	 * Fire preFlightConditions event.
  	 * 
  	 * @return	<code>null</code> normally, or overriding flight conditions.
  	 */
  	public static FlightConditions firePreFlightConditions(SimulationStatus status)
  			throws SimulationException {
  		FlightConditions conditions;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				conditions = ((SimulationComputationListener) l).preFlightConditions(status);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (conditions != null) {
  					warn(status, l);
  					return conditions;
  				}
  			}
  		}
  		return null;
  	}
  	
  	/**
  	 * Fire postFlightConditions event.
  	 * 
  	 * @return	the flight conditions to use: either <code>conditions</code> or a new object
  	 * 			containing the modified conditions.
  	 */
  	public static FlightConditions firePostFlightConditions(SimulationStatus status, FlightConditions conditions)
  			throws SimulationException {
  		FlightConditions c;
  		FlightConditions clone = conditions.clone();
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  			if (l instanceof SimulationComputationListener) {
  				c = ((SimulationComputationListener) l).postFlightConditions(status, clone);
  				if (modID != status.getModID()) {
  					warn(status, l);
  					modID = status.getModID();
  				}
  				if (c != null && !c.equals(conditions)) {
  					warn(status, l);
  					conditions = c;
  					clone = conditions.clone();
  				}
  			}
  		}
  		return conditions;
  	}
  	
  	
  
  
  	/**
  	 * Fire preAerodynamicCalculation event.
  	 * 
  	 * @return	<code>null</code> normally, or overriding aerodynamic forces.
  	 */
  	public static AerodynamicForces firePreAerodynamicCalculation(SimulationStatus status)
  			throws SimulationException {
  		AerodynamicForces forces;
  		int modID = status.getModID();
  		
  		for (SimulationListener l : status.getSimulationConditions().getSimulationListenerList()) {
  