diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs
index df3cc851b0f88cd2f4cdf8f25c335d2f749a7280..4e58f0cc8168bae342244d3144378d134e694921 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs
@@ -29,450 +29,456 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.InputData.Reader.ComponentData;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
-{
-	public class DeclarationDataAdapter : AbstractSimulationDataAdapter
-	{
-		public DriverData CreateDriverData(IDriverDeclarationInputData data)
-		{
-			if (!data.SavedInDeclarationMode) {
-				WarnDeclarationMode("DriverData");
-			}
-			var lookAheadData = new DriverData.LACData {
-				Enabled = DeclarationData.Driver.LookAhead.Enabled,
-				//Deceleration = DeclarationData.Driver.LookAhead.Deceleration,
-				MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed,
-				LookAheadDecisionFactor = new LACDecisionFactor(),
-				LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor,
-			};
-			var overspeedData = new DriverData.OverSpeedEcoRollData {
-				Mode = data.OverSpeedEcoRoll.Mode,
-				MinSpeed = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed,
-				OverSpeed = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed,
-				UnderSpeed = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed
-			};
-			if (!DeclarationData.Driver.OverSpeedEcoRoll.AllowedModes.Contains(overspeedData.Mode)) {
-				throw new VectoSimulationException(
-					"Specified Overspeed/EcoRoll Mode not allowed in declaration mode! {0}",
-					overspeedData.Mode);
-			}
-			var retVal = new DriverData {
-				LookAheadCoasting = lookAheadData,
-				OverSpeedEcoRoll = overspeedData,
-			};
-			return retVal;
-		}
-
-		internal VehicleData CreateVehicleData(IVehicleDeclarationInputData data, Mission mission, Kilogram loading,
-			Kilogram municipalBodyWeight)
-		{
-			if (!data.SavedInDeclarationMode) {
-				WarnDeclarationMode("VehicleData");
-			}
-
-			var retVal = SetCommonVehicleData(data);
-			retVal.VIN = data.VIN;
-			retVal.ManufacturerAddress = data.ManufacturerAddress;
-			retVal.LegislativeClass = data.LegislativeClass;
-			retVal.TrailerGrossVehicleWeight = mission.Trailer.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0);
-
-			retVal.BodyAndTrailerWeight = (mission.MissionType == MissionType.MunicipalUtility
-				? municipalBodyWeight
-				: mission.BodyCurbWeight) + mission.Trailer.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0);
-			//retVal.CurbWeight += retVal.BodyAndTrailerWeight;
-
-			retVal.Loading = loading;
-			var drivenIndex = DrivenAxleIndex(data.Axles);
-			retVal.DynamicTyreRadius =
-				DeclarationData.Wheels.Lookup(data.Axles[drivenIndex].Wheels).DynamicTyreRadius;
-			retVal.CargoVolume = mission.MissionType != MissionType.Construction ? mission.TotalCargoVolume : 0.SI<CubicMeter>();
-
-
-			var axles = data.Axles;
-			if (axles.Count < mission.AxleWeightDistribution.Length) {
-				throw new VectoException("Vehicle does not contain sufficient axles. {0} axles defined, {1} axles required",
-					data.Axles.Count, mission.AxleWeightDistribution.Length);
-			}
-			var axleData = new List<Axle>();
-			for (var i = 0; i < mission.AxleWeightDistribution.Length; i++) {
-				var axleInput = axles[i];
-				var axle = new Axle {
-					WheelsDimension = axleInput.Wheels,
-					AxleType = axleInput.AxleType,
-					AxleWeightShare = mission.AxleWeightDistribution[i],
-					TwinTyres = axleInput.TwinTyres,
-					RollResistanceCoefficient = axleInput.RollResistanceCoefficient,
-					TyreTestLoad = axleInput.TyreTestLoad,
-					Inertia = DeclarationData.Wheels.Lookup(axleInput.Wheels.RemoveWhitespace()).Inertia,
-				};
-				axleData.Add(axle);
-			}
-
-			foreach (var trailer in mission.Trailer) {
-				axleData.AddRange(trailer.TrailerWheels.Select(trailerWheel => new Axle {
-					AxleType = AxleType.Trailer,
-					AxleWeightShare = trailer.TrailerAxleWeightShare / trailer.TrailerWheels.Count,
-					TwinTyres = DeclarationData.Trailer.TwinTyres,
-					RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient,
-					TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(),
-					Inertia = trailerWheel.Inertia
-				}));
-			}
-			retVal.AxleData = axleData;
-			return retVal;
-		}
-
-		private static int DrivenAxleIndex(IList<IAxleDeclarationInputData> axles)
-		{
-			for (var i = 0; i < axles.Count; i++) {
-				if (axles[i].AxleType != AxleType.VehicleDriven) {
-					continue;
-				}
-				return i;
-			}
-			return DeclarationData.PoweredAxle();
-		}
-
-		internal CombustionEngineData CreateEngineData(IEngineDeclarationInputData engine, PerSecond vehicleEngineIdleSpeed,
-			IGearboxDeclarationInputData gearbox, IEnumerable<ITorqueLimitInputData> torqueLimits)
-		{
-			if (!engine.SavedInDeclarationMode) {
-				WarnDeclarationMode("EngineData");
-			}
-
-			var retVal = SetCommonCombustionEngineData(engine);
-			retVal.IdleSpeed = VectoMath.Max(engine.IdleSpeed, vehicleEngineIdleSpeed);
-			retVal.WHTCUrban = engine.WHTCUrban;
-			retVal.WHTCMotorway = engine.WHTCMotorway;
-			retVal.WHTCRural = engine.WHTCRural;
-			retVal.ColdHotCorrectionFactor = engine.ColdHotBalancingFactor;
-			retVal.Inertia = DeclarationData.Engine.EngineInertia(retVal.Displacement, gearbox.Type);
-			var limits = torqueLimits.ToDictionary(e => e.Gear);
-			var numGears = gearbox.Gears.Count;
-			var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1);
-			fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve, true);
-			fullLoadCurves[0].EngineData = retVal;
-			foreach (var gear in gearbox.Gears) {
-				var maxTorque = VectoMath.Min(
-					GbxMaxTorque(gear, numGears, fullLoadCurves[0].MaxTorque),
-					VehMaxTorque(gear, numGears, limits, fullLoadCurves[0].MaxTorque));
-				fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque);
-			}
-			retVal.FullLoadCurves = fullLoadCurves;
-			return retVal;
-		}
-
-		private static NewtonMeter VehMaxTorque(ITransmissionInputData gear, int numGears,
-			Dictionary<int, ITorqueLimitInputData> limits,
-			NewtonMeter maxEngineTorque)
-		{
-			if (gear.Gear - 1 >= numGears / 2) {
-				// only upper half of gears can limit if max-torque <= 0.95 of engine max torque
-				if (limits.ContainsKey(gear.Gear) &&
-					limits[gear.Gear].MaxTorque <= DeclarationData.Engine.TorqueLimitVehicleFactor * maxEngineTorque) {
-					return limits[gear.Gear].MaxTorque;
-				}
-			}
-			return null;
-		}
-
-		private static NewtonMeter GbxMaxTorque(ITransmissionInputData gear, int numGears, NewtonMeter maxEngineTorque
-			)
-		{
-			if (gear.Gear - 1 < numGears / 2) {
-				// gears count from 1 to n, -> n entries, lower half can always limit
-				if (gear.MaxTorque != null) {
-					return gear.MaxTorque;
-				}
-			} else {
-				// upper half can only limit if max-torque <= 90% of engine max torque
-				if (gear.MaxTorque != null && gear.MaxTorque <= DeclarationData.Engine.TorqueLimitGearboxFactor * maxEngineTorque) {
-					return gear.MaxTorque;
-				}
-			}
-			return null;
-		}
-
-		internal GearboxData CreateGearboxData(IGearboxDeclarationInputData gearbox, CombustionEngineData engine,
-			double axlegearRatio, Meter dynamicTyreRadius, bool useEfficiencyFallback)
-		{
-			if (!gearbox.SavedInDeclarationMode) {
-				WarnDeclarationMode("GearboxData");
-			}
-			var retVal = SetCommonGearboxData(gearbox);
-			switch (gearbox.Type) {
-				case GearboxType.DrivingCycle:
-				case GearboxType.ATPowerSplit:
-					throw new VectoSimulationException(
-						"Unsupported gearbox type: {0}!", retVal.Type);
-				//case GearboxType.Custom:
-				//	throw new VectoSimulationException("Custom Transmission not supported in DeclarationMode!");
-			}
-			var gearsInput = gearbox.Gears;
-			if (gearsInput.Count < 1) {
-				throw new VectoSimulationException(
-					"At least one Gear-Entry must be defined in Gearbox!");
-			}
-
-			SetDeclarationData(retVal);
-
-			var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2
-				? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio
-				: 1.0;
-
-			var gears = new Dictionary<uint, GearData>();
-			var tcShiftPolygon = DeclarationData.TorqueConverter.ComputeShiftPolygon(engine.FullLoadCurves[0]);
-			for (uint i = 0; i < gearsInput.Count; i++) {
-				var gear = gearsInput[(int)i];
-				var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, true);
-
-				var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engine.FullLoadCurves[i + 1],
-					gearsInput, engine,
-					axlegearRatio, dynamicTyreRadius);
-
-				var gearData = new GearData {
-					ShiftPolygon = shiftPolygon,
-					MaxSpeed = gear.MaxInputSpeed,
-					Ratio = gear.Ratio,
-					LossMap = lossMap,
-				};
-
-				if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) {
-					// powersplit transmission: torque converter already contains ratio and losses
-					CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon);
-				}
-				if (gearbox.Type == GearboxType.ATSerial) {
-					if (i == 0) {
-						// torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode
-						CreateTCFirstGearATSerial(gearData, tcShiftPolygon);
-					}
-					if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) {
-						// ratio between first and second gear is above threshold, torqueconverter is active in second gear as well
-						// -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear
-						CreateTCSecondGearATSerial(gearData, tcShiftPolygon);
-						// NOTE: the lower gear in 'gears' dictionary has index i !!
-						gears[i].Ratio = double.NaN;
-						gears[i].LossMap = null;
-					}
-				}
-				gears.Add(i + 1, gearData);
-			}
-			retVal.Gears = gears;
-			if (retVal.Type.AutomaticTransmission()) {
-				var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio;
-				retVal.PowershiftShiftTime = DeclarationData.Gearbox.PowershiftShiftTime;
-				retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData,
-					DeclarationData.TorqueConverter.ReferenceRPM, DeclarationData.TorqueConverter.MaxInputSpeed,
-					ExecutionMode.Declaration, ratio,
-					DeclarationData.TorqueConverter.CLUpshiftMinAcceleration, DeclarationData.TorqueConverter.CCUpshiftMinAcceleration);
-			}
-
-			return retVal;
-		}
-
-		private static void SetDeclarationData(GearboxData retVal)
-		{
-			retVal.Inertia = DeclarationData.Gearbox.Inertia;
-			retVal.TractionInterruption = retVal.Type.TractionInterruption();
-			retVal.TorqueReserve = DeclarationData.Gearbox.TorqueReserve;
-			retVal.StartTorqueReserve = DeclarationData.Gearbox.TorqueReserveStart;
-			retVal.ShiftTime = DeclarationData.Gearbox.MinTimeBetweenGearshifts;
-			retVal.StartSpeed = DeclarationData.Gearbox.StartSpeed;
-			retVal.StartAcceleration = DeclarationData.Gearbox.StartAcceleration;
-			retVal.DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay;
-			retVal.UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay;
-			retVal.UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration;
-		}
-
-		public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesDeclarationInputData auxInputData,
-			MissionType mission, VehicleClass hvdClass)
-		{
-			if (!auxInputData.SavedInDeclarationMode) {
-				WarnDeclarationMode("AuxiliariesData");
-			}
-			var retVal = new List<VectoRunData.AuxData>();
-
-			if (auxInputData.Auxiliaries.Count != 5) {
-				Log.Error(
-					"In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System.");
-				throw new VectoException(
-					"In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System.");
-			}
-
-			foreach (var auxType in EnumHelper.GetValues<AuxiliaryType>()) {
-				var auxData = auxInputData.Auxiliaries.FirstOrDefault(a => a.Type == auxType);
-				if (auxData == null) {
-					throw new VectoException("Auxiliary {0} not found.", auxType);
-				}
-				var aux = new VectoRunData.AuxData {
-					DemandType = AuxiliaryDemandType.Constant,
-					Technology = auxData.Technology
-				};
-
-				mission = mission.GetNonEMSMissionType();
-				switch (auxType) {
-					case AuxiliaryType.Fan:
-						aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.FirstOrDefault());
-						aux.ID = Constants.Auxiliaries.IDs.Fan;
-						break;
-					case AuxiliaryType.SteeringPump:
-						aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, auxData.Technology);
-						aux.ID = Constants.Auxiliaries.IDs.SteeringPump;
-						break;
-					case AuxiliaryType.HVAC:
-						aux.PowerDemand = DeclarationData.HeatingVentilationAirConditioning.Lookup(mission,
-							auxData.Technology.FirstOrDefault(), hvdClass);
-						aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition;
-						break;
-					case AuxiliaryType.PneumaticSystem:
-						aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, auxData.Technology.FirstOrDefault());
-						aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem;
-						break;
-					case AuxiliaryType.ElectricSystem:
-						aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.Technology.FirstOrDefault());
-						aux.ID = Constants.Auxiliaries.IDs.ElectricSystem;
-						break;
-					default:
-						continue;
-				}
-				retVal.Add(aux);
-			}
-			return retVal;
-		}
-
-		private void WarnDeclarationMode(string inputData)
-		{
-			Log.Warn("{0} not in Declaration Mode!", inputData);
-		}
-
-		public RetarderData CreateRetarderData(IRetarderInputData retarder)
-		{
-			return SetCommonRetarderData(retarder);
-		}
-
-		public static List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> GetDeclarationAirResistanceCurve(
-			string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight)
-		{
-			const int startSpeed = 60;
-			const int maxSpeed = 130;
-			const int speedStep = 5;
-
-			const int maxAlpha = 180;
-			const int alphaStep = 10;
-
-			const int startHeightPercent = 5;
-			const int maxHeightPercent = 100;
-			const int heightPercentStep = 10;
-			const double heightShare = (double)heightPercentStep / maxHeightPercent;
-
-			var values = DeclarationData.AirDrag.Lookup(crosswindCorrectionParameters);
-
-			// first entry (0m/s) will get CdxA of second entry.
-			var points = new List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> {
-				new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry {
-					Velocity = 0.SI<MeterPerSecond>(),
-					EffectiveCrossSectionArea = 0.SI<SquareMeter>()
-				}
-			};
-
-			for (var speed = startSpeed; speed <= maxSpeed; speed += speedStep) {
-				var vVeh = speed.KMPHtoMeterPerSecond();
-
-				var cdASum = 0.SI<SquareMeter>();
-
-				for (var heightPercent = startHeightPercent; heightPercent < maxHeightPercent; heightPercent += heightPercentStep) {
-					var height = heightPercent / 100.0 * vehicleHeight;
-					var vWind = Physics.BaseWindSpeed * Math.Pow(height / Physics.BaseWindHeight, Physics.HellmannExponent);
-
-					for (var alpha = 0; alpha <= maxAlpha; alpha += alphaStep) {
-						var vAirX = vVeh + vWind * Math.Cos(alpha.ToRadian());
-						var vAirY = vWind * Math.Sin(alpha.ToRadian());
-
-						var beta = Math.Atan(vAirY / vAirX).ToDegree();
-
-						// ΔCdxA = A1β + A2β² + A3β³
-						var deltaCdA = values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta;
-
-						// CdxA(β) = CdxA(0) + ΔCdxA(β)
-						var cdA = aerodynamicDragAera + deltaCdA;
-
-						var share = (alpha == 0 || alpha == maxAlpha ? alphaStep / 2.0 : alphaStep) / maxAlpha;
-
-						// v_air = sqrt(v_airX²+vAirY²)
-						// cdASum = CdxA(β) * v_air²/v_veh²
-						cdASum += heightShare * share * cdA * (vAirX * vAirX + vAirY * vAirY) / (vVeh * vVeh);
-					}
-				}
-				points.Add(new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry {
-					Velocity = vVeh,
-					EffectiveCrossSectionArea = cdASum
-				});
-			}
-
-			points[0].EffectiveCrossSectionArea = points[1].EffectiveCrossSectionArea;
-			return points;
-		}
-
-		public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto)
-		{
-			if (pto.PTOTransmissionType != "None") {
-				return new PTOData {
-					TransmissionType = pto.PTOTransmissionType,
-					LossMap = PTOIdleLossMapReader.GetZeroLossMap(),
-				};
-			}
-
-			return null;
-		}
-
-		public AirdragData CreateAirdragData(IAirdragDeclarationInputData airdragInputData, Mission mission,
-			Segment segment)
-		{
-			if (airdragInputData == null || airdragInputData.AirDragArea == null) {
-				return DefaultAirdragData(mission, segment);
-			}
-
-			var retVal = SetCommonAirdragData(airdragInputData);
-			var aerodynamicDragArea = airdragInputData.AirDragArea + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0);
-
-			retVal.DeclaredAirdragArea = airdragInputData.AirDragArea;
-			retVal.CrossWindCorrectionCurve =
-				new CrosswindCorrectionCdxALookup(aerodynamicDragArea,
-					GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight),
-					CrossWindCorrectionMode.DeclarationModeCorrection);
-			return retVal;
-		}
-
-		private AirdragData DefaultAirdragData(Mission mission, Segment segment)
-		{
-			var aerodynamicDragArea = mission.MissionType == MissionType.Construction
-				? segment.CdAConstruction
-				: segment.CdADefault + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0);
-
-			return new AirdragData() {
-				CertificationMethod = CertificationMethod.StandardValues,
-				DeclaredAirdragArea = mission.MissionType == MissionType.Construction ? segment.CdAConstruction : segment.CdADefault,
-				CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(aerodynamicDragArea,
-					GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight),
-					CrossWindCorrectionMode.DeclarationModeCorrection)
-			};
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
+{
+	public class DeclarationDataAdapter : AbstractSimulationDataAdapter
+	{
+		public DriverData CreateDriverData(IDriverDeclarationInputData data)
+		{
+			if (!data.SavedInDeclarationMode) {
+				WarnDeclarationMode("DriverData");
+			}
+			var lookAheadData = new DriverData.LACData {
+				Enabled = DeclarationData.Driver.LookAhead.Enabled,
+				//Deceleration = DeclarationData.Driver.LookAhead.Deceleration,
+				MinSpeed = DeclarationData.Driver.LookAhead.MinimumSpeed,
+				LookAheadDecisionFactor = new LACDecisionFactor(),
+				LookAheadDistanceFactor = DeclarationData.Driver.LookAhead.LookAheadDistanceFactor,
+			};
+			var overspeedData = new DriverData.OverSpeedEcoRollData {
+				Mode = data.OverSpeedEcoRoll.Mode,
+				MinSpeed = DeclarationData.Driver.OverSpeedEcoRoll.MinSpeed,
+				OverSpeed = DeclarationData.Driver.OverSpeedEcoRoll.OverSpeed,
+				UnderSpeed = DeclarationData.Driver.OverSpeedEcoRoll.UnderSpeed
+			};
+			if (!DeclarationData.Driver.OverSpeedEcoRoll.AllowedModes.Contains(overspeedData.Mode)) {
+				throw new VectoSimulationException(
+					"Specified Overspeed/EcoRoll Mode not allowed in declaration mode! {0}",
+					overspeedData.Mode);
+			}
+			var retVal = new DriverData {
+				LookAheadCoasting = lookAheadData,
+				OverSpeedEcoRoll = overspeedData,
+			};
+			return retVal;
+		}
+
+		internal VehicleData CreateVehicleData(IVehicleDeclarationInputData data, Mission mission, Kilogram loading,
+			Kilogram municipalBodyWeight)
+		{
+			if (!data.SavedInDeclarationMode) {
+				WarnDeclarationMode("VehicleData");
+			}
+
+			var retVal = SetCommonVehicleData(data);
+			retVal.VIN = data.VIN;
+			retVal.ManufacturerAddress = data.ManufacturerAddress;
+			retVal.LegislativeClass = data.LegislativeClass;
+			retVal.TrailerGrossVehicleWeight = mission.Trailer.Sum(t => t.TrailerGrossVehicleWeight).DefaultIfNull(0);
+
+			retVal.BodyAndTrailerWeight = (mission.MissionType == MissionType.MunicipalUtility
+				? municipalBodyWeight
+				: mission.BodyCurbWeight) + mission.Trailer.Sum(t => t.TrailerCurbWeight).DefaultIfNull(0);
+			//retVal.CurbWeight += retVal.BodyAndTrailerWeight;
+
+			retVal.Loading = loading;
+			var drivenIndex = DrivenAxleIndex(data.Axles);
+			retVal.DynamicTyreRadius =
+				DeclarationData.Wheels.Lookup(data.Axles[drivenIndex].Wheels).DynamicTyreRadius;
+			retVal.CargoVolume = mission.MissionType != MissionType.Construction ? mission.TotalCargoVolume : 0.SI<CubicMeter>();
+
+
+			var axles = data.Axles;
+			if (axles.Count < mission.AxleWeightDistribution.Length) {
+				throw new VectoException("Vehicle does not contain sufficient axles. {0} axles defined, {1} axles required",
+					data.Axles.Count, mission.AxleWeightDistribution.Length);
+			}
+			var axleData = new List<Axle>();
+			for (var i = 0; i < mission.AxleWeightDistribution.Length; i++) {
+				var axleInput = axles[i];
+				var axle = new Axle {
+					WheelsDimension = axleInput.Wheels,
+					AxleType = axleInput.AxleType,
+					AxleWeightShare = mission.AxleWeightDistribution[i],
+					TwinTyres = axleInput.TwinTyres,
+					RollResistanceCoefficient = axleInput.RollResistanceCoefficient,
+					TyreTestLoad = axleInput.TyreTestLoad,
+					Inertia = DeclarationData.Wheels.Lookup(axleInput.Wheels.RemoveWhitespace()).Inertia,
+				};
+				axleData.Add(axle);
+			}
+
+			foreach (var trailer in mission.Trailer) {
+				axleData.AddRange(trailer.TrailerWheels.Select(trailerWheel => new Axle {
+					AxleType = AxleType.Trailer,
+					AxleWeightShare = trailer.TrailerAxleWeightShare / trailer.TrailerWheels.Count,
+					TwinTyres = DeclarationData.Trailer.TwinTyres,
+					RollResistanceCoefficient = DeclarationData.Trailer.RollResistanceCoefficient,
+					TyreTestLoad = DeclarationData.Trailer.TyreTestLoad.SI<Newton>(),
+					Inertia = trailerWheel.Inertia
+				}));
+			}
+			retVal.AxleData = axleData;
+			return retVal;
+		}
+
+		private static int DrivenAxleIndex(IList<IAxleDeclarationInputData> axles)
+		{
+			for (var i = 0; i < axles.Count; i++) {
+				if (axles[i].AxleType != AxleType.VehicleDriven) {
+					continue;
+				}
+				return i;
+			}
+			return DeclarationData.PoweredAxle();
+		}
+
+		internal CombustionEngineData CreateEngineData(IEngineDeclarationInputData engine, PerSecond vehicleEngineIdleSpeed,
+			IGearboxDeclarationInputData gearbox, IEnumerable<ITorqueLimitInputData> torqueLimits)
+		{
+			if (!engine.SavedInDeclarationMode) {
+				WarnDeclarationMode("EngineData");
+			}
+
+			var retVal = SetCommonCombustionEngineData(engine);
+			retVal.IdleSpeed = VectoMath.Max(engine.IdleSpeed, vehicleEngineIdleSpeed);
+			retVal.WHTCUrban = engine.WHTCUrban;
+			retVal.WHTCMotorway = engine.WHTCMotorway;
+			retVal.WHTCRural = engine.WHTCRural;
+			retVal.ColdHotCorrectionFactor = engine.ColdHotBalancingFactor;
+			retVal.Inertia = DeclarationData.Engine.EngineInertia(retVal.Displacement, gearbox.Type);
+			var limits = torqueLimits.ToDictionary(e => e.Gear);
+			var numGears = gearbox.Gears.Count;
+			var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1);
+			fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve, true);
+			fullLoadCurves[0].EngineData = retVal;
+			foreach (var gear in gearbox.Gears) {
+				var maxTorque = VectoMath.Min(
+					GbxMaxTorque(gear, numGears, fullLoadCurves[0].MaxTorque),
+					VehMaxTorque(gear, numGears, limits, fullLoadCurves[0].MaxTorque));
+				fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque);
+			}
+			retVal.FullLoadCurves = fullLoadCurves;
+			return retVal;
+		}
+
+		private static NewtonMeter VehMaxTorque(ITransmissionInputData gear, int numGears,
+			Dictionary<int, ITorqueLimitInputData> limits,
+			NewtonMeter maxEngineTorque)
+		{
+			if (gear.Gear - 1 >= numGears / 2) {
+				// only upper half of gears can limit if max-torque <= 0.95 of engine max torque
+				if (limits.ContainsKey(gear.Gear) &&
+					limits[gear.Gear].MaxTorque <= DeclarationData.Engine.TorqueLimitVehicleFactor * maxEngineTorque) {
+					return limits[gear.Gear].MaxTorque;
+				}
+			}
+			return null;
+		}
+
+		private static NewtonMeter GbxMaxTorque(ITransmissionInputData gear, int numGears, NewtonMeter maxEngineTorque
+			)
+		{
+			if (gear.Gear - 1 < numGears / 2) {
+				// gears count from 1 to n, -> n entries, lower half can always limit
+				if (gear.MaxTorque != null) {
+					return gear.MaxTorque;
+				}
+			} else {
+				// upper half can only limit if max-torque <= 90% of engine max torque
+				if (gear.MaxTorque != null && gear.MaxTorque <= DeclarationData.Engine.TorqueLimitGearboxFactor * maxEngineTorque) {
+					return gear.MaxTorque;
+				}
+			}
+			return null;
+		}
+
+		internal GearboxData CreateGearboxData(IGearboxDeclarationInputData gearbox, CombustionEngineData engine,
+			double axlegearRatio, Meter dynamicTyreRadius, bool useEfficiencyFallback)
+		{
+			if (!gearbox.SavedInDeclarationMode) {
+				WarnDeclarationMode("GearboxData");
+			}
+			var retVal = SetCommonGearboxData(gearbox);
+			switch (gearbox.Type) {
+				case GearboxType.DrivingCycle:
+				case GearboxType.ATPowerSplit:
+					throw new VectoSimulationException(
+						"Unsupported gearbox type: {0}!", retVal.Type);
+				//case GearboxType.Custom:
+				//	throw new VectoSimulationException("Custom Transmission not supported in DeclarationMode!");
+			}
+			var gearsInput = gearbox.Gears;
+			if (gearsInput.Count < 1) {
+				throw new VectoSimulationException(
+					"At least one Gear-Entry must be defined in Gearbox!");
+			}
+
+			SetDeclarationData(retVal);
+
+			var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2
+				? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio
+				: 1.0;
+
+			var gears = new Dictionary<uint, GearData>();
+			var tcShiftPolygon = DeclarationData.TorqueConverter.ComputeShiftPolygon(engine.FullLoadCurves[0]);
+			for (uint i = 0; i < gearsInput.Count; i++) {
+				var gear = gearsInput[(int)i];
+				var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, true);
+
+				var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engine.FullLoadCurves[i + 1],
+					gearsInput, engine,
+					axlegearRatio, dynamicTyreRadius);
+
+				var gearData = new GearData {
+					ShiftPolygon = shiftPolygon,
+					MaxSpeed = gear.MaxInputSpeed,
+					Ratio = gear.Ratio,
+					LossMap = lossMap,
+				};
+
+				CreateATGearData(gearbox, i, gearData, tcShiftPolygon, gearDifferenceRatio, gears);
+				gears.Add(i + 1, gearData);
+			}
+			retVal.Gears = gears;
+			if (retVal.Type.AutomaticTransmission()) {
+				var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio;
+				retVal.PowershiftShiftTime = DeclarationData.Gearbox.PowershiftShiftTime;
+				retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData,
+					DeclarationData.TorqueConverter.ReferenceRPM, DeclarationData.TorqueConverter.MaxInputSpeed,
+					ExecutionMode.Declaration, ratio,
+					DeclarationData.TorqueConverter.CLUpshiftMinAcceleration, DeclarationData.TorqueConverter.CCUpshiftMinAcceleration);
+			}
+
+			return retVal;
+		}
+
+		private static void CreateATGearData(IGearboxDeclarationInputData gearbox, uint i, GearData gearData,
+			ShiftPolygon tcShiftPolygon, double gearDifferenceRatio, Dictionary<uint, GearData> gears)
+		{
+			if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) {
+				// powersplit transmission: torque converter already contains ratio and losses
+				CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon);
+			}
+			if (gearbox.Type == GearboxType.ATSerial) {
+				if (i == 0) {
+					// torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode
+					CreateTCFirstGearATSerial(gearData, tcShiftPolygon);
+				}
+				if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) {
+					// ratio between first and second gear is above threshold, torqueconverter is active in second gear as well
+					// -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear
+					CreateTCSecondGearATSerial(gearData, tcShiftPolygon);
+					// NOTE: the lower gear in 'gears' dictionary has index i !!
+					gears[i].Ratio = double.NaN;
+					gears[i].LossMap = null;
+				}
+			}
+		}
+
+		private static void SetDeclarationData(GearboxData retVal)
+		{
+			retVal.Inertia = DeclarationData.Gearbox.Inertia;
+			retVal.TractionInterruption = retVal.Type.TractionInterruption();
+			retVal.TorqueReserve = DeclarationData.Gearbox.TorqueReserve;
+			retVal.StartTorqueReserve = DeclarationData.Gearbox.TorqueReserveStart;
+			retVal.ShiftTime = DeclarationData.Gearbox.MinTimeBetweenGearshifts;
+			retVal.StartSpeed = DeclarationData.Gearbox.StartSpeed;
+			retVal.StartAcceleration = DeclarationData.Gearbox.StartAcceleration;
+			retVal.DownshiftAfterUpshiftDelay = DeclarationData.Gearbox.DownshiftAfterUpshiftDelay;
+			retVal.UpshiftAfterDownshiftDelay = DeclarationData.Gearbox.UpshiftAfterDownshiftDelay;
+			retVal.UpshiftMinAcceleration = DeclarationData.Gearbox.UpshiftMinAcceleration;
+		}
+
+		public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesDeclarationInputData auxInputData,
+			MissionType mission, VehicleClass hvdClass)
+		{
+			if (!auxInputData.SavedInDeclarationMode) {
+				WarnDeclarationMode("AuxiliariesData");
+			}
+			var retVal = new List<VectoRunData.AuxData>();
+
+			if (auxInputData.Auxiliaries.Count != 5) {
+				Log.Error(
+					"In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System.");
+				throw new VectoException(
+					"In Declaration Mode exactly 5 Auxiliaries must be defined: Fan, Steering pump, HVAC, Electric System, Pneumatic System.");
+			}
+
+			foreach (var auxType in EnumHelper.GetValues<AuxiliaryType>()) {
+				var auxData = auxInputData.Auxiliaries.FirstOrDefault(a => a.Type == auxType);
+				if (auxData == null) {
+					throw new VectoException("Auxiliary {0} not found.", auxType);
+				}
+				var aux = new VectoRunData.AuxData {
+					DemandType = AuxiliaryDemandType.Constant,
+					Technology = auxData.Technology
+				};
+
+				mission = mission.GetNonEMSMissionType();
+				switch (auxType) {
+					case AuxiliaryType.Fan:
+						aux.PowerDemand = DeclarationData.Fan.Lookup(mission, auxData.Technology.FirstOrDefault());
+						aux.ID = Constants.Auxiliaries.IDs.Fan;
+						break;
+					case AuxiliaryType.SteeringPump:
+						aux.PowerDemand = DeclarationData.SteeringPump.Lookup(mission, hvdClass, auxData.Technology);
+						aux.ID = Constants.Auxiliaries.IDs.SteeringPump;
+						break;
+					case AuxiliaryType.HVAC:
+						aux.PowerDemand = DeclarationData.HeatingVentilationAirConditioning.Lookup(mission,
+							auxData.Technology.FirstOrDefault(), hvdClass);
+						aux.ID = Constants.Auxiliaries.IDs.HeatingVentilationAirCondition;
+						break;
+					case AuxiliaryType.PneumaticSystem:
+						aux.PowerDemand = DeclarationData.PneumaticSystem.Lookup(mission, auxData.Technology.FirstOrDefault());
+						aux.ID = Constants.Auxiliaries.IDs.PneumaticSystem;
+						break;
+					case AuxiliaryType.ElectricSystem:
+						aux.PowerDemand = DeclarationData.ElectricSystem.Lookup(mission, auxData.Technology.FirstOrDefault());
+						aux.ID = Constants.Auxiliaries.IDs.ElectricSystem;
+						break;
+					default:
+						continue;
+				}
+				retVal.Add(aux);
+			}
+			return retVal;
+		}
+
+		private void WarnDeclarationMode(string inputData)
+		{
+			Log.Warn("{0} not in Declaration Mode!", inputData);
+		}
+
+		public RetarderData CreateRetarderData(IRetarderInputData retarder)
+		{
+			return SetCommonRetarderData(retarder);
+		}
+
+		public static List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> GetDeclarationAirResistanceCurve(
+			string crosswindCorrectionParameters, SquareMeter aerodynamicDragAera, Meter vehicleHeight)
+		{
+			const int startSpeed = 60;
+			const int maxSpeed = 130;
+			const int speedStep = 5;
+
+			const int maxAlpha = 180;
+			const int alphaStep = 10;
+
+			const int startHeightPercent = 5;
+			const int maxHeightPercent = 100;
+			const int heightPercentStep = 10;
+			const double heightShare = (double)heightPercentStep / maxHeightPercent;
+
+			var values = DeclarationData.AirDrag.Lookup(crosswindCorrectionParameters);
+
+			// first entry (0m/s) will get CdxA of second entry.
+			var points = new List<CrossWindCorrectionCurveReader.CrossWindCorrectionEntry> {
+				new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry {
+					Velocity = 0.SI<MeterPerSecond>(),
+					EffectiveCrossSectionArea = 0.SI<SquareMeter>()
+				}
+			};
+
+			for (var speed = startSpeed; speed <= maxSpeed; speed += speedStep) {
+				var vVeh = speed.KMPHtoMeterPerSecond();
+
+				var cdASum = 0.SI<SquareMeter>();
+
+				for (var heightPercent = startHeightPercent; heightPercent < maxHeightPercent; heightPercent += heightPercentStep) {
+					var height = heightPercent / 100.0 * vehicleHeight;
+					var vWind = Physics.BaseWindSpeed * Math.Pow(height / Physics.BaseWindHeight, Physics.HellmannExponent);
+
+					for (var alpha = 0; alpha <= maxAlpha; alpha += alphaStep) {
+						var vAirX = vVeh + vWind * Math.Cos(alpha.ToRadian());
+						var vAirY = vWind * Math.Sin(alpha.ToRadian());
+
+						var beta = Math.Atan(vAirY / vAirX).ToDegree();
+
+						// ΔCdxA = A1β + A2β² + A3β³
+						var deltaCdA = values.A1 * beta + values.A2 * beta * beta + values.A3 * beta * beta * beta;
+
+						// CdxA(β) = CdxA(0) + ΔCdxA(β)
+						var cdA = aerodynamicDragAera + deltaCdA;
+
+						var share = (alpha == 0 || alpha == maxAlpha ? alphaStep / 2.0 : alphaStep) / maxAlpha;
+
+						// v_air = sqrt(v_airX²+vAirY²)
+						// cdASum = CdxA(β) * v_air²/v_veh²
+						cdASum += heightShare * share * cdA * (vAirX * vAirX + vAirY * vAirY) / (vVeh * vVeh);
+					}
+				}
+				points.Add(new CrossWindCorrectionCurveReader.CrossWindCorrectionEntry {
+					Velocity = vVeh,
+					EffectiveCrossSectionArea = cdASum
+				});
+			}
+
+			points[0].EffectiveCrossSectionArea = points[1].EffectiveCrossSectionArea;
+			return points;
+		}
+
+		public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto)
+		{
+			if (pto.PTOTransmissionType != "None") {
+				return new PTOData {
+					TransmissionType = pto.PTOTransmissionType,
+					LossMap = PTOIdleLossMapReader.GetZeroLossMap(),
+				};
+			}
+
+			return null;
+		}
+
+		public AirdragData CreateAirdragData(IAirdragDeclarationInputData airdragInputData, Mission mission,
+			Segment segment)
+		{
+			if (airdragInputData == null || airdragInputData.AirDragArea == null) {
+				return DefaultAirdragData(mission, segment);
+			}
+
+			var retVal = SetCommonAirdragData(airdragInputData);
+			var aerodynamicDragArea = airdragInputData.AirDragArea + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0);
+
+			retVal.DeclaredAirdragArea = airdragInputData.AirDragArea;
+			retVal.CrossWindCorrectionCurve =
+				new CrosswindCorrectionCdxALookup(aerodynamicDragArea,
+					GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight),
+					CrossWindCorrectionMode.DeclarationModeCorrection);
+			return retVal;
+		}
+
+		private AirdragData DefaultAirdragData(Mission mission, Segment segment)
+		{
+			var aerodynamicDragArea = mission.MissionType == MissionType.Construction
+				? segment.CdAConstruction
+				: segment.CdADefault + mission.Trailer.Sum(t => t.DeltaCdA).DefaultIfNull(0);
+
+			return new AirdragData() {
+				CertificationMethod = CertificationMethod.StandardValues,
+				DeclaredAirdragArea = mission.MissionType == MissionType.Construction ? segment.CdAConstruction : segment.CdADefault,
+				CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(aerodynamicDragArea,
+					GetDeclarationAirResistanceCurve(mission.CrossWindCorrectionParameters, aerodynamicDragArea, segment.VehicleHeight),
+					CrossWindCorrectionMode.DeclarationModeCorrection)
+			};
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
index 50c771198b3326f4d8956c1f7f706ec0dc98b286..f5af5e2dcd4f73446c93c39f1313c3d63e5325a1 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/EngineeringDataAdapter.cs
@@ -29,340 +29,346 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.InputData.Reader.ComponentData;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-
-namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
-{
-	public class EngineeringDataAdapter : AbstractSimulationDataAdapter
-	{
-		internal VehicleData CreateVehicleData(IVehicleEngineeringInputData data)
-		{
-			if (data.SavedInDeclarationMode) {
-				WarnEngineeringMode("VehicleData");
-			}
-
-			var retVal = SetCommonVehicleData(data);
-			retVal.BodyAndTrailerWeight = data.CurbMassExtra;
-			//retVal.CurbWeight += data.CurbMassExtra;
-			retVal.TrailerGrossVehicleWeight = 0.SI<Kilogram>();
-			retVal.Loading = data.Loading;
-			retVal.DynamicTyreRadius = data.DynamicTyreRadius;
-			var axles = data.Axles;
-
-
-			retVal.AxleData = axles.Select(axle => new Axle {
-				WheelsDimension = axle.Wheels,
-				Inertia = axle.Inertia,
-				TwinTyres = axle.TwinTyres,
-				RollResistanceCoefficient = axle.RollResistanceCoefficient,
-				AxleWeightShare = axle.AxleWeightShare,
-				TyreTestLoad = axle.TyreTestLoad,
-				//Wheels = axle.WheelsStr
-			}).ToList();
-			return retVal;
-		}
-
-		public AirdragData CreateAirdragData(IAirdragEngineeringInputData airdragData, IVehicleEngineeringInputData data)
-		{
-			var retVal = SetCommonAirdragData(airdragData);
-			retVal.CrossWindCorrectionMode = airdragData.CrossWindCorrectionMode;
-
-			switch (airdragData.CrossWindCorrectionMode) {
-				case CrossWindCorrectionMode.NoCorrection:
-					retVal.CrossWindCorrectionCurve =
-						new CrosswindCorrectionCdxALookup(airdragData.AirDragArea,
-							CrossWindCorrectionCurveReader.GetNoCorrectionCurve(airdragData.AirDragArea),
-							CrossWindCorrectionMode.NoCorrection);
-					break;
-				case CrossWindCorrectionMode.SpeedDependentCorrectionFactor:
-					retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airdragData.AirDragArea,
-						CrossWindCorrectionCurveReader.ReadSpeedDependentCorrectionCurve(airdragData.CrosswindCorrectionMap,
-							airdragData.AirDragArea), CrossWindCorrectionMode.SpeedDependentCorrectionFactor);
-					break;
-				case CrossWindCorrectionMode.VAirBetaLookupTable:
-					retVal.CrossWindCorrectionCurve = new CrosswindCorrectionVAirBeta(airdragData.AirDragArea,
-						CrossWindCorrectionCurveReader.ReadCdxABetaTable(airdragData.CrosswindCorrectionMap));
-					break;
-				case CrossWindCorrectionMode.DeclarationModeCorrection:
-					var height = DeclarationData.Segments.LookupHeight(data.VehicleCategory, data.AxleConfiguration,
-						data.GrossVehicleMassRating);
-					retVal.CrossWindCorrectionCurve =
-						new CrosswindCorrectionCdxALookup(airdragData.AirDragArea,
-							DeclarationDataAdapter.GetDeclarationAirResistanceCurve(
-								GetAirdragParameterSet(data.VehicleCategory, data.AxleConfiguration, data.Axles.Count),
-								airdragData.AirDragArea, height), CrossWindCorrectionMode.DeclarationModeCorrection);
-					break;
-				default:
-					throw new ArgumentOutOfRangeException("CrosswindCorrection", airdragData.CrossWindCorrectionMode.ToString());
-			}
-			return retVal;
-		}
-
-		private string GetAirdragParameterSet(VehicleCategory vehicleCategory, AxleConfiguration axles, int numAxles)
-		{
-			switch (vehicleCategory) {
-				case VehicleCategory.RigidTruck:
-					return numAxles > axles.NumAxles() ? "RigidTrailer" : "RigidSolo";
-				case VehicleCategory.Tractor:
-					return "TractorSemitrailer";
-				case VehicleCategory.CityBus:
-				case VehicleCategory.InterurbanBus:
-				case VehicleCategory.Coach:
-					return "CoachBus";
-				default:
-					throw new ArgumentOutOfRangeException("vehicleCategory", vehicleCategory, null);
-			}
-		}
-
-		private void WarnEngineeringMode(string msg)
-		{
-			Log.Error("{0} is in Declaration Mode but is used for Engineering Mode!", msg);
-		}
-
-		internal CombustionEngineData CreateEngineData(IEngineEngineeringInputData engine, IGearboxEngineeringInputData gbx,
-			IEnumerable<ITorqueLimitInputData> torqueLimits)
-		{
-			if (engine.SavedInDeclarationMode) {
-				WarnEngineeringMode("EngineData");
-			}
-
-			var retVal = SetCommonCombustionEngineData(engine);
-			retVal.Inertia = engine.Inertia +
-							(gbx != null && gbx.Type.AutomaticTransmission() ? gbx.TorqueConverter.Inertia : 0.SI<KilogramSquareMeter>());
-			var limits = torqueLimits.ToDictionary(e => e.Gear);
-			var numGears = gbx == null ? 0 : gbx.Gears.Count;
-			var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1);
-			fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve);
-			fullLoadCurves[0].EngineData = retVal;
-			if (gbx != null) {
-				foreach (var gear in gbx.Gears) {
-					var maxTorque = VectoMath.Min(gear.MaxTorque, limits.ContainsKey(gear.Gear) ? limits[gear.Gear].MaxTorque : null);
-					fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque);
-				}
-			}
-			retVal.FullLoadCurves = fullLoadCurves;
-			retVal.FuelConsumptionCorrectionFactor = engine.WHTCEngineering;
-			return retVal;
-		}
-
-		internal GearboxData CreateGearboxData(IGearboxEngineeringInputData gearbox, CombustionEngineData engineData,
-			double axlegearRatio, Meter dynamicTyreRadius, bool useEfficiencyFallback)
-		{
-			if (gearbox.SavedInDeclarationMode) {
-				WarnEngineeringMode("GearboxData");
-			}
-
-			var retVal = SetCommonGearboxData(gearbox);
-
-			//var gears = gearbox.Gears;
-			if (gearbox.Gears.Count < 2) {
-				throw new VectoSimulationException("At least two Gear-Entries must be defined in Gearbox!");
-			}
-
-			SetEngineeringData(gearbox, retVal);
-
-			var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2
-				? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio
-				: 1.0;
-
-			var gears = new Dictionary<uint, GearData>();
-			ShiftPolygon tcShiftPolygon = null;
-			if (gearbox.Type.AutomaticTransmission()) {
-				tcShiftPolygon = gearbox.TorqueConverter.ShiftPolygon != null
-					? ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon)
-					: DeclarationData.TorqueConverter.ComputeShiftPolygon(engineData.FullLoadCurves[0]);
-			}
-			for (uint i = 0; i < gearbox.Gears.Count; i++) {
-				var gear = gearbox.Gears[(int)i];
-				var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, false);
-
-				var shiftPolygon = gear.ShiftPolygon != null && gear.ShiftPolygon.SourceType != DataSourceType.Missing
-					? ShiftPolygonReader.Create(gear.ShiftPolygon)
-					: DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engineData.FullLoadCurves[i + 1], gearbox.Gears,
-						engineData,
-						axlegearRatio, dynamicTyreRadius);
-				var gearData = new GearData {
-					ShiftPolygon = shiftPolygon,
-					MaxSpeed = gear.MaxInputSpeed,
-					Ratio = gear.Ratio,
-					LossMap = lossMap,
-				};
-
-				if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) {
-					// powersplit transmission: torque converter already contains ratio and losses
-					CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon);
-				}
-				if (gearbox.Type == GearboxType.ATSerial) {
-					if (i == 0) {
-						// torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode
-						CreateTCFirstGearATSerial(gearData, tcShiftPolygon);
-					}
-					if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) {
-						// ratio between first and second gear is above threshold, torqueconverter is active in second gear as well
-						// -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear
-						CreateTCSecondGearATSerial(gearData, tcShiftPolygon);
-						// NOTE: the lower gear in 'gears' dictionary has index i !!
-						gears[i].Ratio = double.NaN;
-						gears[i].LossMap = null;
-					}
-				}
-				gears.Add(i + 1, gearData);
-			}
-			retVal.Gears = gears;
-
-			if (retVal.Type.AutomaticTransmission()) {
-				var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio;
-				retVal.PowershiftShiftTime = gearbox.PowershiftShiftTime;
-				retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData,
-					gearbox.TorqueConverter.ReferenceRPM, gearbox.TorqueConverter.MaxInputSpeed, ExecutionMode.Engineering, ratio,
-					gearbox.TorqueConverter.CLUpshiftMinAcceleration, gearbox.TorqueConverter.CCUpshiftMinAcceleration);
-			}
-
-
-			return retVal;
-		}
-
-		private static void SetEngineeringData(IGearboxEngineeringInputData gearbox, GearboxData retVal)
-		{
-			retVal.Inertia = gearbox.Type.ManualTransmission() ? gearbox.Inertia : 0.SI<KilogramSquareMeter>();
-			retVal.TractionInterruption = gearbox.TractionInterruption;
-			retVal.TorqueReserve = gearbox.TorqueReserve;
-			retVal.StartTorqueReserve = gearbox.StartTorqueReserve;
-			retVal.ShiftTime = gearbox.MinTimeBetweenGearshift;
-			retVal.StartSpeed = gearbox.StartSpeed;
-			retVal.StartAcceleration = gearbox.StartAcceleration;
-			retVal.DownshiftAfterUpshiftDelay = gearbox.DownshiftAfterUpshiftDelay;
-			retVal.UpshiftAfterDownshiftDelay = gearbox.UpshiftAfterDownshiftDelay;
-			retVal.UpshiftMinAcceleration = gearbox.UpshiftMinAcceleration;
-		}
-
-
-		public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesEngineeringInputData auxInputData)
-		{
-			var auxList = new List<VectoRunData.AuxData>(auxInputData.Auxiliaries.Count + 1) {
-				new VectoRunData.AuxData { ID = Constants.Auxiliaries.Cycle, DemandType = AuxiliaryDemandType.Direct }
-			};
-
-			foreach (var a in auxInputData.Auxiliaries) {
-				switch (a.AuxiliaryType) {
-					case AuxiliaryDemandType.Mapping:
-						auxList.Add(CreateMappingAuxiliary(a));
-						break;
-					case AuxiliaryDemandType.Constant:
-						auxList.Add(CreateConstantAuxiliary(a));
-						break;
-					default:
-						throw new VectoException("Auxiliary type {0} not supported!", a.AuxiliaryType);
-				}
-			}
-			return auxList;
-		}
-
-		private static VectoRunData.AuxData CreateMappingAuxiliary(IAuxiliaryEngineeringInputData a)
-		{
-			if (a.DemandMap == null) {
-				throw new VectoSimulationException("Demand Map for auxiliary {0} required", a.ID);
-			}
-			if (a.DemandMap.Columns.Count != 3 || a.DemandMap.Rows.Count < 4) {
-				throw new VectoSimulationException(
-					"Demand Map for auxiliary {0} has to contain exactly 3 columns and at least 4 rows", a.ID);
-			}
-			return new VectoRunData.AuxData {
-				ID = a.ID,
-				DemandType = AuxiliaryDemandType.Mapping,
-				Data = AuxiliaryDataReader.Create(a)
-			};
-		}
-
-		private static VectoRunData.AuxData CreateConstantAuxiliary(IAuxiliaryEngineeringInputData a)
-		{
-			return new VectoRunData.AuxData {
-				ID = a.ID,
-				DemandType = AuxiliaryDemandType.Constant,
-				PowerDemand = a.ConstantPowerDemand
-			};
-		}
-
-		internal DriverData CreateDriverData(IDriverEngineeringInputData driver)
-		{
-			if (driver.SavedInDeclarationMode) {
-				WarnEngineeringMode("DriverData");
-			}
-
-			AccelerationCurveData accelerationData = null;
-			if (driver.AccelerationCurve != null) {
-				accelerationData = AccelerationCurveReader.Create(driver.AccelerationCurve);
-			}
-
-			if (driver.Lookahead == null) {
-				throw new VectoSimulationException("Error: Lookahead Data is missing.");
-			}
-			var lookAheadData = new DriverData.LACData {
-				Enabled = driver.Lookahead.Enabled,
-				//Deceleration = driver.Lookahead.Deceleration,
-				MinSpeed = driver.Lookahead.MinSpeed,
-				LookAheadDecisionFactor =
-					new LACDecisionFactor(driver.Lookahead.CoastingDecisionFactorOffset, driver.Lookahead.CoastingDecisionFactorScaling,
-						driver.Lookahead.CoastingDecisionFactorTargetSpeedLookup,
-						driver.Lookahead.CoastingDecisionFactorVelocityDropLookup),
-				LookAheadDistanceFactor = driver.Lookahead.LookaheadDistanceFactor
-			};
-			var overspeedData = new DriverData.OverSpeedEcoRollData {
-				Mode = driver.OverSpeedEcoRoll.Mode,
-				MinSpeed = driver.OverSpeedEcoRoll.MinSpeed,
-				OverSpeed = driver.OverSpeedEcoRoll.OverSpeed,
-				UnderSpeed = driver.OverSpeedEcoRoll.UnderSpeed,
-			};
-			var retVal = new DriverData {
-				AccelerationCurve = accelerationData,
-				LookAheadCoasting = lookAheadData,
-				OverSpeedEcoRoll = overspeedData,
-			};
-			return retVal;
-		}
-
-		//=================================
-		public RetarderData CreateRetarderData(IRetarderInputData retarder)
-		{
-			return SetCommonRetarderData(retarder);
-		}
-
-		public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto)
-		{
-			if (pto.PTOTransmissionType != "None") {
-				var ptoData = new PTOData {
-					TransmissionType = pto.PTOTransmissionType,
-					LossMap = PTOIdleLossMapReader.Create(pto.PTOLossMap),
-				};
-				if (pto.PTOCycle != null) {
-					ptoData.PTOCycle = DrivingCycleDataReader.ReadFromDataTable(pto.PTOCycle, CycleType.PTO, "PTO", false);
-				}
-				return ptoData;
-			}
-
-			return null;
-		}
-
-		public AdvancedAuxData CreateAdvancedAuxData(IAuxiliariesEngineeringInputData auxInputData)
-		{
-			return new AdvancedAuxData() {
-				AdvancedAuxiliaryFilePath = auxInputData.AdvancedAuxiliaryFilePath,
-				AuxiliaryAssembly = auxInputData.AuxiliaryAssembly,
-				AuxiliaryVersion = auxInputData.AuxiliaryVersion
-			};
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+
+namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
+{
+	public class EngineeringDataAdapter : AbstractSimulationDataAdapter
+	{
+		internal VehicleData CreateVehicleData(IVehicleEngineeringInputData data)
+		{
+			if (data.SavedInDeclarationMode) {
+				WarnEngineeringMode("VehicleData");
+			}
+
+			var retVal = SetCommonVehicleData(data);
+			retVal.BodyAndTrailerWeight = data.CurbMassExtra;
+			//retVal.CurbWeight += data.CurbMassExtra;
+			retVal.TrailerGrossVehicleWeight = 0.SI<Kilogram>();
+			retVal.Loading = data.Loading;
+			retVal.DynamicTyreRadius = data.DynamicTyreRadius;
+			var axles = data.Axles;
+
+
+			retVal.AxleData = axles.Select(axle => new Axle {
+				WheelsDimension = axle.Wheels,
+				Inertia = axle.Inertia,
+				TwinTyres = axle.TwinTyres,
+				RollResistanceCoefficient = axle.RollResistanceCoefficient,
+				AxleWeightShare = axle.AxleWeightShare,
+				TyreTestLoad = axle.TyreTestLoad,
+				//Wheels = axle.WheelsStr
+			}).ToList();
+			return retVal;
+		}
+
+		public AirdragData CreateAirdragData(IAirdragEngineeringInputData airdragData, IVehicleEngineeringInputData data)
+		{
+			var retVal = SetCommonAirdragData(airdragData);
+			retVal.CrossWindCorrectionMode = airdragData.CrossWindCorrectionMode;
+
+			switch (airdragData.CrossWindCorrectionMode) {
+				case CrossWindCorrectionMode.NoCorrection:
+					retVal.CrossWindCorrectionCurve =
+						new CrosswindCorrectionCdxALookup(airdragData.AirDragArea,
+							CrossWindCorrectionCurveReader.GetNoCorrectionCurve(airdragData.AirDragArea),
+							CrossWindCorrectionMode.NoCorrection);
+					break;
+				case CrossWindCorrectionMode.SpeedDependentCorrectionFactor:
+					retVal.CrossWindCorrectionCurve = new CrosswindCorrectionCdxALookup(airdragData.AirDragArea,
+						CrossWindCorrectionCurveReader.ReadSpeedDependentCorrectionCurve(airdragData.CrosswindCorrectionMap,
+							airdragData.AirDragArea), CrossWindCorrectionMode.SpeedDependentCorrectionFactor);
+					break;
+				case CrossWindCorrectionMode.VAirBetaLookupTable:
+					retVal.CrossWindCorrectionCurve = new CrosswindCorrectionVAirBeta(airdragData.AirDragArea,
+						CrossWindCorrectionCurveReader.ReadCdxABetaTable(airdragData.CrosswindCorrectionMap));
+					break;
+				case CrossWindCorrectionMode.DeclarationModeCorrection:
+					var height = DeclarationData.Segments.LookupHeight(data.VehicleCategory, data.AxleConfiguration,
+						data.GrossVehicleMassRating);
+					retVal.CrossWindCorrectionCurve =
+						new CrosswindCorrectionCdxALookup(airdragData.AirDragArea,
+							DeclarationDataAdapter.GetDeclarationAirResistanceCurve(
+								GetAirdragParameterSet(data.VehicleCategory, data.AxleConfiguration, data.Axles.Count),
+								airdragData.AirDragArea, height), CrossWindCorrectionMode.DeclarationModeCorrection);
+					break;
+				default:
+					throw new ArgumentOutOfRangeException("CrosswindCorrection", airdragData.CrossWindCorrectionMode.ToString());
+			}
+			return retVal;
+		}
+
+		private string GetAirdragParameterSet(VehicleCategory vehicleCategory, AxleConfiguration axles, int numAxles)
+		{
+			switch (vehicleCategory) {
+				case VehicleCategory.RigidTruck:
+					return numAxles > axles.NumAxles() ? "RigidTrailer" : "RigidSolo";
+				case VehicleCategory.Tractor:
+					return "TractorSemitrailer";
+				case VehicleCategory.CityBus:
+				case VehicleCategory.InterurbanBus:
+				case VehicleCategory.Coach:
+					return "CoachBus";
+				default:
+					throw new ArgumentOutOfRangeException("vehicleCategory", vehicleCategory, null);
+			}
+		}
+
+		private void WarnEngineeringMode(string msg)
+		{
+			Log.Error("{0} is in Declaration Mode but is used for Engineering Mode!", msg);
+		}
+
+		internal CombustionEngineData CreateEngineData(IEngineEngineeringInputData engine, IGearboxEngineeringInputData gbx,
+			IEnumerable<ITorqueLimitInputData> torqueLimits)
+		{
+			if (engine.SavedInDeclarationMode) {
+				WarnEngineeringMode("EngineData");
+			}
+
+			var retVal = SetCommonCombustionEngineData(engine);
+			retVal.Inertia = engine.Inertia +
+							(gbx != null && gbx.Type.AutomaticTransmission() ? gbx.TorqueConverter.Inertia : 0.SI<KilogramSquareMeter>());
+			var limits = torqueLimits.ToDictionary(e => e.Gear);
+			var numGears = gbx == null ? 0 : gbx.Gears.Count;
+			var fullLoadCurves = new Dictionary<uint, EngineFullLoadCurve>(numGears + 1);
+			fullLoadCurves[0] = FullLoadCurveReader.Create(engine.FullLoadCurve);
+			fullLoadCurves[0].EngineData = retVal;
+			if (gbx != null) {
+				foreach (var gear in gbx.Gears) {
+					var maxTorque = VectoMath.Min(gear.MaxTorque, limits.ContainsKey(gear.Gear) ? limits[gear.Gear].MaxTorque : null);
+					fullLoadCurves[(uint)gear.Gear] = IntersectFullLoadCurves(fullLoadCurves[0], maxTorque);
+				}
+			}
+			retVal.FullLoadCurves = fullLoadCurves;
+			retVal.FuelConsumptionCorrectionFactor = engine.WHTCEngineering;
+			return retVal;
+		}
+
+		internal GearboxData CreateGearboxData(IGearboxEngineeringInputData gearbox, CombustionEngineData engineData,
+			double axlegearRatio, Meter dynamicTyreRadius, bool useEfficiencyFallback)
+		{
+			if (gearbox.SavedInDeclarationMode) {
+				WarnEngineeringMode("GearboxData");
+			}
+
+			var retVal = SetCommonGearboxData(gearbox);
+
+			//var gears = gearbox.Gears;
+			if (gearbox.Gears.Count < 2) {
+				throw new VectoSimulationException("At least two Gear-Entries must be defined in Gearbox!");
+			}
+
+			SetEngineeringData(gearbox, retVal);
+
+			var gearDifferenceRatio = gearbox.Type.AutomaticTransmission() && gearbox.Gears.Count > 2
+				? gearbox.Gears[0].Ratio / gearbox.Gears[1].Ratio
+				: 1.0;
+
+			var gears = new Dictionary<uint, GearData>();
+			ShiftPolygon tcShiftPolygon = null;
+			if (gearbox.Type.AutomaticTransmission()) {
+				tcShiftPolygon = gearbox.TorqueConverter.ShiftPolygon != null
+					? ShiftPolygonReader.Create(gearbox.TorqueConverter.ShiftPolygon)
+					: DeclarationData.TorqueConverter.ComputeShiftPolygon(engineData.FullLoadCurves[0]);
+			}
+			for (uint i = 0; i < gearbox.Gears.Count; i++) {
+				var gear = gearbox.Gears[(int)i];
+				var lossMap = CreateGearLossMap(gear, i, useEfficiencyFallback, false);
+
+				var shiftPolygon = gear.ShiftPolygon != null && gear.ShiftPolygon.SourceType != DataSourceType.Missing
+					? ShiftPolygonReader.Create(gear.ShiftPolygon)
+					: DeclarationData.Gearbox.ComputeShiftPolygon(gearbox.Type, (int)i, engineData.FullLoadCurves[i + 1], gearbox.Gears,
+						engineData,
+						axlegearRatio, dynamicTyreRadius);
+				var gearData = new GearData {
+					ShiftPolygon = shiftPolygon,
+					MaxSpeed = gear.MaxInputSpeed,
+					Ratio = gear.Ratio,
+					LossMap = lossMap,
+				};
+
+				CreateATGearData(gearbox, i, gearData, tcShiftPolygon, gearDifferenceRatio, gears);
+				gears.Add(i + 1, gearData);
+			}
+			retVal.Gears = gears;
+
+			if (retVal.Type.AutomaticTransmission()) {
+				var ratio = double.IsNaN(retVal.Gears[1].Ratio) ? 1 : retVal.Gears[1].TorqueConverterRatio / retVal.Gears[1].Ratio;
+				retVal.PowershiftShiftTime = gearbox.PowershiftShiftTime;
+				retVal.TorqueConverterData = TorqueConverterDataReader.Create(gearbox.TorqueConverter.TCData,
+					gearbox.TorqueConverter.ReferenceRPM, gearbox.TorqueConverter.MaxInputSpeed, ExecutionMode.Engineering, ratio,
+					gearbox.TorqueConverter.CLUpshiftMinAcceleration, gearbox.TorqueConverter.CCUpshiftMinAcceleration);
+			}
+
+
+			return retVal;
+		}
+
+		private static void CreateATGearData(IGearboxEngineeringInputData gearbox, uint i, GearData gearData,
+			ShiftPolygon tcShiftPolygon, double gearDifferenceRatio, Dictionary<uint, GearData> gears)
+		{
+			if (gearbox.Type == GearboxType.ATPowerSplit && i == 0) {
+				// powersplit transmission: torque converter already contains ratio and losses
+				CretateTCFirstGearATPowerSplit(gearData, i, tcShiftPolygon);
+			}
+			if (gearbox.Type == GearboxType.ATSerial) {
+				if (i == 0) {
+					// torqueconverter is active in first gear - duplicate ratio and lossmap for torque converter mode
+					CreateTCFirstGearATSerial(gearData, tcShiftPolygon);
+				}
+				if (i == 1 && gearDifferenceRatio >= DeclarationData.Gearbox.TorqueConverterSecondGearThreshold) {
+					// ratio between first and second gear is above threshold, torqueconverter is active in second gear as well
+					// -> duplicate ratio and lossmap for torque converter mode, remove locked transmission for previous gear
+					CreateTCSecondGearATSerial(gearData, tcShiftPolygon);
+					// NOTE: the lower gear in 'gears' dictionary has index i !!
+					gears[i].Ratio = double.NaN;
+					gears[i].LossMap = null;
+				}
+			}
+		}
+
+		private static void SetEngineeringData(IGearboxEngineeringInputData gearbox, GearboxData retVal)
+		{
+			retVal.Inertia = gearbox.Type.ManualTransmission() ? gearbox.Inertia : 0.SI<KilogramSquareMeter>();
+			retVal.TractionInterruption = gearbox.TractionInterruption;
+			retVal.TorqueReserve = gearbox.TorqueReserve;
+			retVal.StartTorqueReserve = gearbox.StartTorqueReserve;
+			retVal.ShiftTime = gearbox.MinTimeBetweenGearshift;
+			retVal.StartSpeed = gearbox.StartSpeed;
+			retVal.StartAcceleration = gearbox.StartAcceleration;
+			retVal.DownshiftAfterUpshiftDelay = gearbox.DownshiftAfterUpshiftDelay;
+			retVal.UpshiftAfterDownshiftDelay = gearbox.UpshiftAfterDownshiftDelay;
+			retVal.UpshiftMinAcceleration = gearbox.UpshiftMinAcceleration;
+		}
+
+
+		public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesEngineeringInputData auxInputData)
+		{
+			var auxList = new List<VectoRunData.AuxData>(auxInputData.Auxiliaries.Count + 1) {
+				new VectoRunData.AuxData { ID = Constants.Auxiliaries.Cycle, DemandType = AuxiliaryDemandType.Direct }
+			};
+
+			foreach (var a in auxInputData.Auxiliaries) {
+				switch (a.AuxiliaryType) {
+					case AuxiliaryDemandType.Mapping:
+						auxList.Add(CreateMappingAuxiliary(a));
+						break;
+					case AuxiliaryDemandType.Constant:
+						auxList.Add(CreateConstantAuxiliary(a));
+						break;
+					default:
+						throw new VectoException("Auxiliary type {0} not supported!", a.AuxiliaryType);
+				}
+			}
+			return auxList;
+		}
+
+		private static VectoRunData.AuxData CreateMappingAuxiliary(IAuxiliaryEngineeringInputData a)
+		{
+			if (a.DemandMap == null) {
+				throw new VectoSimulationException("Demand Map for auxiliary {0} required", a.ID);
+			}
+			if (a.DemandMap.Columns.Count != 3 || a.DemandMap.Rows.Count < 4) {
+				throw new VectoSimulationException(
+					"Demand Map for auxiliary {0} has to contain exactly 3 columns and at least 4 rows", a.ID);
+			}
+			return new VectoRunData.AuxData {
+				ID = a.ID,
+				DemandType = AuxiliaryDemandType.Mapping,
+				Data = AuxiliaryDataReader.Create(a)
+			};
+		}
+
+		private static VectoRunData.AuxData CreateConstantAuxiliary(IAuxiliaryEngineeringInputData a)
+		{
+			return new VectoRunData.AuxData {
+				ID = a.ID,
+				DemandType = AuxiliaryDemandType.Constant,
+				PowerDemand = a.ConstantPowerDemand
+			};
+		}
+
+		internal DriverData CreateDriverData(IDriverEngineeringInputData driver)
+		{
+			if (driver.SavedInDeclarationMode) {
+				WarnEngineeringMode("DriverData");
+			}
+
+			AccelerationCurveData accelerationData = null;
+			if (driver.AccelerationCurve != null) {
+				accelerationData = AccelerationCurveReader.Create(driver.AccelerationCurve);
+			}
+
+			if (driver.Lookahead == null) {
+				throw new VectoSimulationException("Error: Lookahead Data is missing.");
+			}
+			var lookAheadData = new DriverData.LACData {
+				Enabled = driver.Lookahead.Enabled,
+				//Deceleration = driver.Lookahead.Deceleration,
+				MinSpeed = driver.Lookahead.MinSpeed,
+				LookAheadDecisionFactor =
+					new LACDecisionFactor(driver.Lookahead.CoastingDecisionFactorOffset, driver.Lookahead.CoastingDecisionFactorScaling,
+						driver.Lookahead.CoastingDecisionFactorTargetSpeedLookup,
+						driver.Lookahead.CoastingDecisionFactorVelocityDropLookup),
+				LookAheadDistanceFactor = driver.Lookahead.LookaheadDistanceFactor
+			};
+			var overspeedData = new DriverData.OverSpeedEcoRollData {
+				Mode = driver.OverSpeedEcoRoll.Mode,
+				MinSpeed = driver.OverSpeedEcoRoll.MinSpeed,
+				OverSpeed = driver.OverSpeedEcoRoll.OverSpeed,
+				UnderSpeed = driver.OverSpeedEcoRoll.UnderSpeed,
+			};
+			var retVal = new DriverData {
+				AccelerationCurve = accelerationData,
+				LookAheadCoasting = lookAheadData,
+				OverSpeedEcoRoll = overspeedData,
+			};
+			return retVal;
+		}
+
+		//=================================
+		public RetarderData CreateRetarderData(IRetarderInputData retarder)
+		{
+			return SetCommonRetarderData(retarder);
+		}
+
+		public PTOData CreatePTOTransmissionData(IPTOTransmissionInputData pto)
+		{
+			if (pto.PTOTransmissionType != "None") {
+				var ptoData = new PTOData {
+					TransmissionType = pto.PTOTransmissionType,
+					LossMap = PTOIdleLossMapReader.Create(pto.PTOLossMap),
+				};
+				if (pto.PTOCycle != null) {
+					ptoData.PTOCycle = DrivingCycleDataReader.ReadFromDataTable(pto.PTOCycle, CycleType.PTO, "PTO", false);
+				}
+				return ptoData;
+			}
+
+			return null;
+		}
+
+		public AdvancedAuxData CreateAdvancedAuxData(IAuxiliariesEngineeringInputData auxInputData)
+		{
+			return new AdvancedAuxData() {
+				AdvancedAuxiliaryFilePath = auxInputData.AdvancedAuxiliaryFilePath,
+				AuxiliaryAssembly = auxInputData.AuxiliaryAssembly,
+				AuxiliaryVersion = auxInputData.AuxiliaryVersion
+			};
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
index 37846d8653cff369a62ea4b6d0636c9ad7c2128c..83f67a12679fe968c8b94cb4cd8e7e0f9f8ef023 100644
--- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
@@ -29,176 +29,200 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Xml.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.OutputData;
-using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData;
-
-namespace TUGraz.VectoCore.Models.Simulation.Data
-{
-	[CustomValidation(typeof(VectoRunData), "ValidateRunData")]
-	public class VectoRunData : SimulationComponentData
-	{
-		[ValidateObject]
-		public VehicleData VehicleData { get; internal set; }
-
-		[ValidateObject]
-		public AirdragData AirdragData { get; internal set; }
-
-		[ValidateObject]
-		public CombustionEngineData EngineData { get; internal set; }
-
-		[ValidateObject]
-		public GearboxData GearboxData { get; internal set; }
-
-		[ValidateObject]
-		public AxleGearData AxleGearData { get; internal set; }
-
-		[ValidateObject]
-		public AngledriveData AngledriveData { get; internal set; }
-
-		[Required, ValidateObject]
-		public IDrivingCycleData Cycle { get; internal set; }
-
-		[ValidateObject]
-		public IEnumerable<AuxData> Aux { get; internal set; }
-
-		public AdvancedAuxData AdvancedAux { get; internal set; }
-
-		[ValidateObject]
-		public RetarderData Retarder { get; internal set; }
-
-		[ValidateObject]
-		public PTOData PTO { get; internal set; }
-
-		[ValidateObject]
-		public DriverData DriverData { get; internal set; }
-
-		public ExecutionMode ExecutionMode { get; internal set; }
-
-		[Required, MinLength(1)]
-		public string JobName { get; internal set; }
-
-		public string ModFileSuffix { get; internal set; }
-
-		[ValidateObject]
-		public IDeclarationReport Report { get; internal set; }
-
-		[Required, ValidateObject]
-		public LoadingType Loading { get; internal set; }
-
-		[ValidateObject]
-		public Mission Mission { get; internal set; }
-
-		public XElement InputDataHash { get; internal set; }
-
-		public class AuxData
-		{
-			// ReSharper disable once InconsistentNaming
-			public string ID;
-
-			public IList<string> Technology;
-
-			[SIRange(0, 100 * Constants.Kilo)] public Watt PowerDemand;
-
-			[Required] public AuxiliaryDemandType DemandType;
-
-			[ValidateObject] public AuxiliaryData Data;
-		}
-
-		public static ValidationResult ValidateRunData(VectoRunData runData, ValidationContext validationContext)
-		{
-			var gearboxData = runData.GearboxData;
-			var engineData = runData.EngineData;
-
-			var maxSpeed = 95.KMPHtoMeterPerSecond();
-
-			if (gearboxData != null) {
-				var axleGearData = runData.AxleGearData;
-				var angledriveData = runData.AngledriveData;
-				var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null;
-				var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive
-					? angledriveData.Angledrive.Ratio
-					: 1.0;
-				var axlegearRatio = axleGearData != null ? axleGearData.AxleGear.Ratio : 1.0;
-				var dynamicTyreRadius = runData.VehicleData != null ? runData.VehicleData.DynamicTyreRadius : 0.0.SI<Meter>();
-
-				if (gearboxData.Gears.Count + 1 != engineData.FullLoadCurves.Count) {
-					return
-						new ValidationResult(
-							string.Format("number of full-load curves in engine does not match gear count. engine fld: {0}, gears: {1}",
-								engineData.FullLoadCurves.Count, gearboxData.Gears.Count));
-				}
-
-				foreach (var gear in gearboxData.Gears) {
-					for (var angularVelocity = engineData.IdleSpeed;
-						angularVelocity < engineData.FullLoadCurves[gear.Key].RatedSpeed;
-						angularVelocity += 2.0 / 3.0 * (engineData.FullLoadCurves[gear.Key].RatedSpeed - engineData.IdleSpeed) / 10.0) {
-						if (!gear.Value.HasLockedGear) {
-							continue;
-						}
-
-						var velocity = angularVelocity / gear.Value.Ratio / angledriveRatio / axlegearRatio * dynamicTyreRadius;
-
-						if (velocity > maxSpeed) {
-							continue;
-						}
-
-						for (var inTorque = engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 3;
-							inTorque < engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity);
-							inTorque += 2.0 / 3.0 * engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 10.0) {
-							NewtonMeter angledriveTorque;
-							try {
-								angledriveTorque = gear.Value.LossMap.GetOutTorque(angularVelocity, inTorque);
-							} catch (VectoException) {
-								return new ValidationResult(
-									string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key,
-										inTorque, angularVelocity.ConvertTo().Rounds.Per.Minute));
-							}
-							var axlegearTorque = angledriveTorque;
-							try {
-								if (hasAngleDrive) {
-									axlegearTorque = angledriveData.Angledrive.LossMap.GetOutTorque(angularVelocity / gear.Value.Ratio,
-										angledriveTorque);
-								}
-							} catch (VectoException) {
-								return new ValidationResult(
-									string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}",
-										angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertTo().Rounds.Per.Minute));
-							}
-
-							if (axleGearData != null) {
-								var axleAngularVelocity = angularVelocity / gear.Value.Ratio / angledriveRatio;
-								try {
-									axleGearData.AxleGear.LossMap.GetOutTorque(axleAngularVelocity, axlegearTorque);
-								} catch (VectoException) {
-									return
-										new ValidationResult(
-											string.Format(
-												"Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})",
-												axlegearTorque, axleAngularVelocity.ConvertTo().Rounds.Per.Minute, gear.Key, velocity));
-								}
-							}
-						}
-					}
-				}
-			}
-
-			if (runData.Cycle != null && runData.Cycle.Entries.Any(e => e.PTOActive)) {
-				if (runData.PTO == null || runData.PTO.PTOCycle == null) {
-					return new ValidationResult("PTOCycle is used in DrivingCycle, but is not defined in Vehicle-Data.");
-				}
-			}
-
-			return ValidationResult.Success;
-		}
-	}
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Xml.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.OutputData;
+using DriverData = TUGraz.VectoCore.Models.SimulationComponent.Data.DriverData;
+
+namespace TUGraz.VectoCore.Models.Simulation.Data
+{
+	[CustomValidation(typeof(VectoRunData), "ValidateRunData")]
+	public class VectoRunData : SimulationComponentData
+	{
+		[ValidateObject]
+		public VehicleData VehicleData { get; internal set; }
+
+		[ValidateObject]
+		public AirdragData AirdragData { get; internal set; }
+
+		[ValidateObject]
+		public CombustionEngineData EngineData { get; internal set; }
+
+		[ValidateObject]
+		public GearboxData GearboxData { get; internal set; }
+
+		[ValidateObject]
+		public AxleGearData AxleGearData { get; internal set; }
+
+		[ValidateObject]
+		public AngledriveData AngledriveData { get; internal set; }
+
+		[Required, ValidateObject]
+		public IDrivingCycleData Cycle { get; internal set; }
+
+		[ValidateObject]
+		public IEnumerable<AuxData> Aux { get; internal set; }
+
+		public AdvancedAuxData AdvancedAux { get; internal set; }
+
+		[ValidateObject]
+		public RetarderData Retarder { get; internal set; }
+
+		[ValidateObject]
+		public PTOData PTO { get; internal set; }
+
+		[ValidateObject]
+		public DriverData DriverData { get; internal set; }
+
+		public ExecutionMode ExecutionMode { get; internal set; }
+
+		[Required, MinLength(1)]
+		public string JobName { get; internal set; }
+
+		public string ModFileSuffix { get; internal set; }
+
+		[ValidateObject]
+		public IDeclarationReport Report { get; internal set; }
+
+		[Required, ValidateObject]
+		public LoadingType Loading { get; internal set; }
+
+		[ValidateObject]
+		public Mission Mission { get; internal set; }
+
+		public XElement InputDataHash { get; internal set; }
+
+		public class AuxData
+		{
+			// ReSharper disable once InconsistentNaming
+			public string ID;
+
+			public IList<string> Technology;
+
+			[SIRange(0, 100 * Constants.Kilo)] public Watt PowerDemand;
+
+			[Required] public AuxiliaryDemandType DemandType;
+
+			[ValidateObject] public AuxiliaryData Data;
+		}
+
+		public static ValidationResult ValidateRunData(VectoRunData runData, ValidationContext validationContext)
+		{
+			var gearboxData = runData.GearboxData;
+			var engineData = runData.EngineData;
+
+			if (gearboxData != null) {
+				var validationResult = CheckPowertrainLossMapsSize(runData, gearboxData, engineData);
+				if (validationResult != null) {
+					return validationResult;
+				}
+			}
+
+			if (runData.Cycle != null && runData.Cycle.Entries.Any(e => e.PTOActive)) {
+				if (runData.PTO == null || runData.PTO.PTOCycle == null) {
+					return new ValidationResult("PTOCycle is used in DrivingCycle, but is not defined in Vehicle-Data.");
+				}
+			}
+
+			return ValidationResult.Success;
+		}
+
+		private static ValidationResult CheckPowertrainLossMapsSize(VectoRunData runData, GearboxData gearboxData,
+			CombustionEngineData engineData)
+		{
+			var maxSpeed = 95.KMPHtoMeterPerSecond();
+			var axleGearData = runData.AxleGearData;
+			var angledriveData = runData.AngledriveData;
+			var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null;
+			var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive
+				? angledriveData.Angledrive.Ratio
+				: 1.0;
+			var axlegearRatio = axleGearData != null ? axleGearData.AxleGear.Ratio : 1.0;
+			var dynamicTyreRadius = runData.VehicleData != null ? runData.VehicleData.DynamicTyreRadius : 0.0.SI<Meter>();
+
+			if (gearboxData.Gears.Count + 1 != engineData.FullLoadCurves.Count) {
+				return
+					new ValidationResult(
+						string.Format("number of full-load curves in engine does not match gear count. engine fld: {0}, gears: {1}",
+							engineData.FullLoadCurves.Count, gearboxData.Gears.Count));
+			}
+
+			foreach (var gear in gearboxData.Gears) {
+				for (var angularVelocity = engineData.IdleSpeed;
+					angularVelocity < engineData.FullLoadCurves[gear.Key].RatedSpeed;
+					angularVelocity += 2.0 / 3.0 * (engineData.FullLoadCurves[gear.Key].RatedSpeed - engineData.IdleSpeed) / 10.0) {
+					if (!gear.Value.HasLockedGear) {
+						continue;
+					}
+
+					var velocity = angularVelocity / gear.Value.Ratio / angledriveRatio / axlegearRatio * dynamicTyreRadius;
+
+					if (velocity > maxSpeed) {
+						continue;
+					}
+
+					for (var inTorque = engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 3;
+						inTorque < engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity);
+						inTorque += 2.0 / 3.0 * engineData.FullLoadCurves[gear.Key].FullLoadStationaryTorque(angularVelocity) / 10.0) {
+						var validateRunData = CheckLossMapsEntries(gear, angularVelocity, inTorque, angledriveData, axleGearData, velocity);
+						if (validateRunData != null) {
+							return validateRunData;
+						}
+					}
+				}
+			}
+			return null;
+		}
+
+		private static ValidationResult CheckLossMapsEntries(KeyValuePair<uint, GearData> gear, PerSecond angularVelocity,
+			NewtonMeter inTorque, AngledriveData angledriveData, AxleGearData axleGearData, SI velocity)
+		{
+			var hasAngleDrive = angledriveData != null && angledriveData.Angledrive != null;
+			var angledriveRatio = hasAngleDrive && angledriveData.Type == AngledriveType.SeparateAngledrive
+				? angledriveData.Angledrive.Ratio
+				: 1.0;
+			NewtonMeter angledriveTorque;
+			try {
+				angledriveTorque = gear.Value.LossMap.GetOutTorque(angularVelocity, inTorque);
+			} catch (VectoException) {
+				return new ValidationResult(
+					string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key,
+						inTorque, angularVelocity.ConvertTo().Rounds.Per.Minute));
+			}
+			var axlegearTorque = angledriveTorque;
+			try {
+				if (hasAngleDrive) {
+					axlegearTorque = angledriveData.Angledrive.LossMap.GetOutTorque(angularVelocity / gear.Value.Ratio,
+						angledriveTorque);
+				}
+			} catch (VectoException) {
+				return new ValidationResult(
+					string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}",
+						angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertTo().Rounds.Per.Minute));
+			}
+
+			if (axleGearData != null) {
+				var axleAngularVelocity = angularVelocity / gear.Value.Ratio / angledriveRatio;
+				try {
+					axleGearData.AxleGear.LossMap.GetOutTorque(axleAngularVelocity, axlegearTorque);
+				} catch (VectoException) {
+					return
+						new ValidationResult(
+							string.Format(
+								"Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})",
+								axlegearTorque, axleAngularVelocity.ConvertTo().Rounds.Per.Minute, gear.Key, velocity));
+				}
+			}
+			return null;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs
index 8d72fe26083182bd5cedd333b70d9ff088840611..2c395c3bdecff8629c84e037a59256f356582539 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs
@@ -29,166 +29,203 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.InputData;
-using TUGraz.VectoCore.InputData.Reader.Impl;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.OutputData.ModFilter;
-using TUGraz.VectoCore.OutputData.XML;
-
-namespace TUGraz.VectoCore.Models.Simulation.Impl
-{
-	public class SimulatorFactory : LoggingObject
-	{
-		private static int _jobNumberCounter;
-
-		private readonly ExecutionMode _mode;
-		private readonly bool _engineOnlyMode;
-
-		public SimulatorFactory(ExecutionMode mode, IInputDataProvider dataProvider, IOutputDataWriter writer,
-			IDeclarationReport declarationReport = null, bool validate = true)
-		{
-			Log.Info("########## VectoCore Version {0} ##########", Assembly.GetExecutingAssembly().GetName().Version);
-			JobNumber = Interlocked.Increment(ref _jobNumberCounter);
-			_mode = mode;
-			ModWriter = writer;
-			Validate = validate;
-
-			int workerThreads;
-			int completionThreads;
-			ThreadPool.GetMinThreads(out workerThreads, out completionThreads);
-			if (workerThreads < 12) {
-				workerThreads = 12;
-			}
-			ThreadPool.SetMinThreads(workerThreads, completionThreads);
-
-			switch (mode) {
-				case ExecutionMode.Declaration:
-					var declDataProvider = dataProvider as IDeclarationInputDataProvider;
-					if (declDataProvider == null) {
-						throw new VectoException("InputDataProvider does not implement DeclarationData interface");
-					}
-					var report = declarationReport ?? new XMLDeclarationReport(writer);
-					DataReader = new DeclarationModeVectoRunDataFactory(declDataProvider, report);
-					break;
-				case ExecutionMode.Engineering:
-					var engDataProvider = dataProvider as IEngineeringInputDataProvider;
-					if (engDataProvider == null) {
-						throw new VectoException("InputDataProvider does not implement Engineering interface");
-					}
-					if (engDataProvider.JobInputData().EngineOnlyMode) {
-						DataReader = new EngineOnlyVectoRunDataFactory(engDataProvider);
-						_engineOnlyMode = true;
-					} else {
-						DataReader = new EngineeringModeVectoRunDataFactory(engDataProvider);
-					}
-					break;
-				default:
-					throw new VectoException("Unkown factory mode in SimulatorFactory: {0}", mode);
-			}
-		}
-
-		public bool Validate { get; set; }
-
-		public IVectoRunDataFactory DataReader { get; private set; }
-
-		public SummaryDataContainer SumData { get; set; }
-
-		public IOutputDataWriter ModWriter { get; private set; }
-
-		public int JobNumber { get; set; }
-
-		public bool WriteModalResults { get; set; }
-		public bool ModalResults1Hz { get; set; }
-		public bool ActualModalData { get; set; }
-
-		/// <summary>
-		/// Creates powertrain and initializes it with the component's data.
-		/// </summary>
-		/// <returns>new VectoRun Instance</returns>
-		public IEnumerable<IVectoRun> SimulationRuns()
-		{
-			var i = 0;
-			var modDataFilter = ModalResults1Hz
-				? new IModalDataFilter[] { new ModalData1HzFilter() }
-				: null;
-
-			if (ActualModalData) {
-				modDataFilter = new IModalDataFilter[] { new ActualModalDataFilter(), };
-			}
-
-
-			var warning1Hz = false;
-
-			foreach (var data in DataReader.NextRun()) {
-				var d = data;
-				if (d.Report != null) {
-					d.Report.PrepareResult(d.Loading, d.Mission, d);
-				}
-				Action<ModalDataContainer> addReportResult = writer => {
-					if (d.Report != null) {
-						d.Report.AddResult(d.Loading, d.Mission, d, writer);
-					}
-				};
-				if (!data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz && !warning1Hz) {
-					Log.Error("Output filter for 1Hz results is only available for distance-based cycles!");
-					warning1Hz = true;
-				}
-				IModalDataContainer modContainer =
-					new ModalDataContainer(data, ModWriter,
-						addReportResult: _mode == ExecutionMode.Declaration ? addReportResult : null,
-						writeEngineOnly: _engineOnlyMode,
-						filter: data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz || ActualModalData ? modDataFilter : null) {
-							WriteAdvancedAux = data.AdvancedAux != null && data.AdvancedAux.AuxiliaryAssembly == AuxiliaryModel.Advanced,
-							WriteModalResults = _mode != ExecutionMode.Declaration || WriteModalResults
-						};
-				var current = i++;
-				var builder = new PowertrainBuilder(modContainer, modData => {
-					if (SumData != null) {
-						SumData.Write(modData, JobNumber, current, d);
-						//SumData.Write(modContainer, d.JobName, string.Format("{0}-{1}", JobNumber, current),
-						//	d.Cycle.Name + Constants.FileExtensions.CycleFile, mass, loading, volume ?? 0.SI<CubicMeter>(), gearCount);
-					}
-				});
-
-				VectoRun run;
-
-				switch (data.Cycle.CycleType) {
-					case CycleType.DistanceBased:
-						run = new DistanceRun(builder.Build(data));
-						break;
-					case CycleType.EngineOnly:
-					case CycleType.PWheel:
-					case CycleType.MeasuredSpeed:
-					case CycleType.MeasuredSpeedGear:
-						run = new TimeRun(builder.Build(data));
-						break;
-					case CycleType.PTO:
-						throw new VectoException("PTO Cycle can not be used as main cycle!");
-					default:
-						throw new ArgumentOutOfRangeException("CycleType unknown:" + data.Cycle.CycleType);
-				}
-
-				if (Validate) {
-					var validationErrors = run.Validate(_mode, data.GearboxData == null ? (GearboxType?)null : data.GearboxData.Type,
-						data.Mission != null && data.Mission.MissionType.IsEMS());
-					if (validationErrors.Any()) {
-						throw new VectoException("Validation of Run-Data Failed: " +
-												string.Join("\n", validationErrors.Select(r => r.ErrorMessage + string.Join("; ", r.MemberNames))));
-					}
-				}
-				yield return run;
-			}
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData;
+using TUGraz.VectoCore.InputData.Reader.Impl;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.OutputData.ModFilter;
+using TUGraz.VectoCore.OutputData.XML;
+
+namespace TUGraz.VectoCore.Models.Simulation.Impl
+{
+	public class SimulatorFactory : LoggingObject
+	{
+		private static int _jobNumberCounter;
+
+		private readonly ExecutionMode _mode;
+		private bool _engineOnlyMode;
+
+		public SimulatorFactory(ExecutionMode mode, IInputDataProvider dataProvider, IOutputDataWriter writer,
+			IDeclarationReport declarationReport = null, bool validate = true)
+		{
+			Log.Info("########## VectoCore Version {0} ##########", Assembly.GetExecutingAssembly().GetName().Version);
+			JobNumber = Interlocked.Increment(ref _jobNumberCounter);
+			_mode = mode;
+			ModWriter = writer;
+			Validate = validate;
+
+			int workerThreads;
+			int completionThreads;
+			ThreadPool.GetMinThreads(out workerThreads, out completionThreads);
+			if (workerThreads < 12) {
+				workerThreads = 12;
+			}
+			ThreadPool.SetMinThreads(workerThreads, completionThreads);
+
+			switch (mode) {
+				case ExecutionMode.Declaration:
+					var declDataProvider = ToDeclarationInputDataProvider(dataProvider);
+					var report = declarationReport ?? new XMLDeclarationReport(writer);
+					DataReader = new DeclarationModeVectoRunDataFactory(declDataProvider, report);
+					break;
+				case ExecutionMode.Engineering:
+					CreateEngineeringDataReader(dataProvider);
+					break;
+				default:
+					throw new VectoException("Unkown factory mode in SimulatorFactory: {0}", mode);
+			}
+		}
+
+		private void CreateEngineeringDataReader(IInputDataProvider dataProvider)
+		{
+			var engDataProvider = ToEngineeringInputDataProvider(dataProvider);
+			if (engDataProvider.JobInputData().EngineOnlyMode) {
+				DataReader = new EngineOnlyVectoRunDataFactory(engDataProvider);
+				_engineOnlyMode = true;
+			} else {
+				DataReader = new EngineeringModeVectoRunDataFactory(engDataProvider);
+			}
+		}
+
+		private static IDeclarationInputDataProvider ToDeclarationInputDataProvider(IInputDataProvider dataProvider)
+		{
+			var declDataProvider = dataProvider as IDeclarationInputDataProvider;
+			if (declDataProvider == null) {
+				throw new VectoException("InputDataProvider does not implement DeclarationData interface");
+			}
+			return declDataProvider;
+		}
+
+		private static IEngineeringInputDataProvider ToEngineeringInputDataProvider(IInputDataProvider dataProvider)
+		{
+			var engDataProvider = dataProvider as IEngineeringInputDataProvider;
+			if (engDataProvider == null) {
+				throw new VectoException("InputDataProvider does not implement Engineering interface");
+			}
+			return engDataProvider;
+		}
+
+		public bool Validate { get; set; }
+
+		public IVectoRunDataFactory DataReader { get; private set; }
+
+		public SummaryDataContainer SumData { get; set; }
+
+		public IOutputDataWriter ModWriter { get; private set; }
+
+		public int JobNumber { get; set; }
+
+		public bool WriteModalResults { get; set; }
+		public bool ModalResults1Hz { get; set; }
+		public bool ActualModalData { get; set; }
+
+		/// <summary>
+		/// Creates powertrain and initializes it with the component's data.
+		/// </summary>
+		/// <returns>new VectoRun Instance</returns>
+		public IEnumerable<IVectoRun> SimulationRuns()
+		{
+			var i = 0;
+
+
+			var warning1Hz = false;
+
+			foreach (var data in DataReader.NextRun()) {
+				var d = data;
+				var addReportResult = PrepareReport(data);
+				if (!data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz && !warning1Hz) {
+					Log.Error("Output filter for 1Hz results is only available for distance-based cycles!");
+					warning1Hz = true;
+				}
+				IModalDataContainer modContainer =
+					new ModalDataContainer(data, ModWriter,
+						addReportResult: _mode == ExecutionMode.Declaration ? addReportResult : null,
+						writeEngineOnly: _engineOnlyMode,
+						filter: GetModDataFilter(data)) {
+							WriteAdvancedAux = data.AdvancedAux != null && data.AdvancedAux.AuxiliaryAssembly == AuxiliaryModel.Advanced,
+							WriteModalResults = _mode != ExecutionMode.Declaration || WriteModalResults
+						};
+				var current = i++;
+				var builder = new PowertrainBuilder(modContainer, modData => {
+					if (SumData != null) {
+						SumData.Write(modData, JobNumber, current, d);
+					}
+				});
+
+				var run = GetVectoRun(data, builder);
+
+				if (Validate) {
+					ValidateVectoRunData(run, data.GearboxData == null ? (GearboxType?)null : data.GearboxData.Type,
+						data.Mission != null && data.Mission.MissionType.IsEMS());
+				}
+				yield return run;
+			}
+		}
+
+		private IModalDataFilter[] GetModDataFilter(VectoRunData data)
+		{
+			var modDataFilter = ModalResults1Hz
+				? new IModalDataFilter[] { new ModalData1HzFilter() }
+				: null;
+
+			if (ActualModalData) {
+				modDataFilter = new IModalDataFilter[] { new ActualModalDataFilter(), };
+			}
+			return data.Cycle.CycleType.IsDistanceBased() && ModalResults1Hz || ActualModalData ? modDataFilter : null;
+		}
+
+		private void ValidateVectoRunData(VectoRun run, GearboxType? gearboxtype, bool isEms)
+		{
+			var validationErrors = run.Validate(_mode, gearboxtype, isEms);
+			if (validationErrors.Any()) {
+				throw new VectoException("Validation of Run-Data Failed: " +
+										string.Join("\n", validationErrors.Select(r => r.ErrorMessage + string.Join("; ", r.MemberNames))));
+			}
+		}
+
+		private static VectoRun GetVectoRun(VectoRunData data, PowertrainBuilder builder)
+		{
+			VectoRun run;
+			switch (data.Cycle.CycleType) {
+				case CycleType.DistanceBased:
+					run = new DistanceRun(builder.Build(data));
+					break;
+				case CycleType.EngineOnly:
+				case CycleType.PWheel:
+				case CycleType.MeasuredSpeed:
+				case CycleType.MeasuredSpeedGear:
+					run = new TimeRun(builder.Build(data));
+					break;
+				case CycleType.PTO:
+					throw new VectoException("PTO Cycle can not be used as main cycle!");
+				default:
+					throw new ArgumentOutOfRangeException("CycleType unknown:" + data.Cycle.CycleType);
+			}
+			return run;
+		}
+
+		private static Action<ModalDataContainer> PrepareReport(VectoRunData data)
+		{
+			if (data.Report != null) {
+				data.Report.PrepareResult(data.Loading, data.Mission, data);
+			}
+			Action<ModalDataContainer> addReportResult = writer => {
+				if (data.Report != null) {
+					data.Report.AddResult(data.Loading, data.Mission, data, writer);
+				}
+			};
+			return addReportResult;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
index d9f0b0341354b449747a868b53ad183e4080f860..d9fb06e6d86da8aa421209671e5ca90f2a3385aa 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATGearbox.cs
@@ -29,386 +29,395 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class ATGearbox : AbstractGearbox<ATGearbox.ATGearboxState>
-	{
-		private readonly IShiftStrategy _strategy;
-		protected internal readonly TorqueConverter TorqueConverter;
-		private IIdleController _idleController;
-		protected bool RequestAfterGearshift;
-
-		public bool TorqueConverterLocked
-		{
-			get { return CurrentState.TorqueConverterLocked; }
-			set { CurrentState.TorqueConverterLocked = value; }
-		}
-
-		public ATGearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData)
-			: base(container, runData)
-		{
-			_strategy = strategy;
-			_strategy.Gearbox = this;
-			LastShift = -double.MaxValue.SI<Second>();
-			TorqueConverter = new TorqueConverter(this, _strategy, container, ModelData.TorqueConverterData,
-				runData);
-		}
-
-		public IIdleController IdleController
-		{
-			get { return _idleController; }
-			set {
-				_idleController = value;
-				_idleController.RequestPort = NextComponent;
-			}
-		}
-
-		public bool Disengaged
-		{
-			get { return CurrentState.Disengaged; }
-			set { CurrentState.Disengaged = value; }
-		}
-
-		public override void Connect(ITnOutPort other)
-		{
-			base.Connect(other);
-			TorqueConverter.NextComponent = other;
-		}
-
-		public override GearInfo NextGear
-		{
-			get { return _strategy.NextGear; }
-		}
-
-		public override bool ClutchClosed(Second absTime)
-		{
-			return absTime.IsGreater(DataBus.AbsTime) ||
-					!(CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted));
-		}
-
-		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			if (CurrentState.Disengaged) {
-				Gear = _strategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, outTorque,
-					outAngularVelocity);
-			}
-			var inAngularVelocity = 0.SI<PerSecond>();
-			var inTorque = 0.SI<NewtonMeter>();
-			var effectiveRatio = ModelData.Gears[Gear].Ratio;
-			var effectiveLossMap = ModelData.Gears[Gear].LossMap;
-			if (!CurrentState.TorqueConverterLocked) {
-				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
-				effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap;
-			}
-			if (!DataBus.VehicleStopped) {
-				inAngularVelocity = outAngularVelocity * effectiveRatio;
-				var torqueLossResult = effectiveLossMap.GetTorqueLoss(outAngularVelocity, outTorque);
-				CurrentState.TorqueLossResult = torqueLossResult;
-
-				inTorque = outTorque / effectiveRatio + torqueLossResult.Value;
-			}
-			if (CurrentState.Disengaged) {
-				return NextComponent.Initialize(0.SI<NewtonMeter>(), null);
-			}
-
-			if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) {
-				throw new VectoSimulationException(
-					"Torque converter requested by strategy for gear without torque converter!");
-			}
-			var response = CurrentState.TorqueConverterLocked
-				? NextComponent.Initialize(inTorque, inAngularVelocity)
-				: TorqueConverter.Initialize(inTorque, inAngularVelocity);
-
-			CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() {
-				Value = 0.SI<NewtonMeter>(),
-				Extrapolated = false
-			};
-
-			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-			PreviousState.Gear = Gear;
-			PreviousState.TorqueConverterLocked = CurrentState.TorqueConverterLocked;
-			return response;
-		}
-
-		internal ResponseDryRun Initialize(uint gear, bool torqueConverterLocked, NewtonMeter outTorque,
-			PerSecond outAngularVelocity)
-		{
-			var effectiveRatio = torqueConverterLocked
-				? ModelData.Gears[gear].Ratio
-				: ModelData.Gears[gear].TorqueConverterRatio;
-
-			var inAngularVelocity = outAngularVelocity * effectiveRatio;
-			var torqueLossResult = torqueConverterLocked
-				? ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque)
-				: ModelData.Gears[gear].TorqueConverterGearLossMap.GetTorqueLoss(outAngularVelocity, outTorque);
-
-			var inTorque = outTorque / effectiveRatio + torqueLossResult.Value;
-
-			IResponse response;
-			if (torqueConverterLocked) {
-				response = NextComponent.Initialize(inTorque, inAngularVelocity);
-			} else {
-				if (!ModelData.Gears[gear].HasTorqueConverter) {
-					throw new VectoSimulationException(
-						"Torque converter requested by strategy for gear without torque converter!");
-				}
-				response = TorqueConverter.Initialize(inTorque, inAngularVelocity);
-			}
-
-			response.Switch().
-				Case<ResponseSuccess>(). // accept
-				Case<ResponseUnderload>(). // accept
-				Case<ResponseOverload>(). // accept
-				Default(r => { throw new UnexpectedResponseException("AT-Gearbox.Initialize", r); });
-
-			return new ResponseDryRun {
-				Source = this,
-				EngineSpeed = response.EngineSpeed,
-				EnginePowerRequest = response.EnginePowerRequest,
-				GearboxPowerRequest = outTorque * outAngularVelocity,
-			};
-		}
-
-		public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun = false)
-		{
-			IterationStatistics.Increment(this, "Requests");
-
-			Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
-
-			if (!dryRun &&
-				((DataBus.VehicleStopped && outAngularVelocity > 0) ||
-				(CurrentState.Disengaged && outTorque.IsGreater(0, 1e-3)))) {
-				Gear = 1;
-				CurrentState.TorqueConverterLocked = false;
-				LastShift = absTime;
-				CurrentState.Disengaged = false;
-			}
-
-			IResponse retVal;
-			var count = 0;
-			var loop = false;
-			if (RequestAfterGearshift) {
-				LastShift = absTime;
-				Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
-				CurrentState.PowershiftLossEnergy = ComputeShiftLosses(outTorque, outAngularVelocity);
-			} else {
-				if (PreviousState.PowershiftLossEnergy != null && PreviousState.PowershiftLossEnergy.IsGreater(0)) {
-					CurrentState.PowershiftLossEnergy = PreviousState.PowershiftLossEnergy;
-				}
-			}
-			do {
-				if (CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted)) {
-					// only when vehicle is halted or close before halting
-					retVal = RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-				} else {
-					CurrentState.Disengaged = false;
-					retVal = RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-					IdleController.Reset();
-				}
-				if (retVal is ResponseGearShift) {
-					if (ConsiderShiftLosses(_strategy.NextGear, outTorque)) {
-						retVal = new ResponseFailTimeInterval {
-							Source = this,
-							DeltaT = ModelData.PowershiftShiftTime,
-							GearboxPowerRequest =
-								outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0
-						};
-						RequestAfterGearshift = true;
-						LastShift = absTime;
-					} else {
-						loop = true;
-						Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
-						LastShift = absTime;
-					}
-				}
-			} while (loop && ++count < 2);
-
-			retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			return retVal;
-		}
-
-		private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun)
-		{
-			if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) {
-				throw new VectoSimulationException(
-					"Torque converter requested by strategy for gear without torque converter!");
-			}
-
-			var effectiveRatio = ModelData.Gears[Gear].Ratio;
-			var effectiveLossMap = ModelData.Gears[Gear].LossMap;
-			if (!CurrentState.TorqueConverterLocked) {
-				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
-				effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap;
-			}
-
-			var inAngularVelocity = outAngularVelocity * effectiveRatio;
-			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0;
-			var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
-			var inTorque = outTorque * (avgOutAngularVelocity / avgInAngularVelocity) + inTorqueLossResult.Value;
-
-			var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
-				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
-				avgOutAngularVelocity
-				: 0.SI<NewtonMeter>();
-			inTorque += inertiaTorqueLossOut / effectiveRatio;
-
-			if (CurrentState.PowershiftLossEnergy != null) {
-				var remainingShiftLossLime = ModelData.PowershiftShiftTime - (absTime - LastShift);
-				if (remainingShiftLossLime.IsGreater(0)) {
-					var aliquotEnergyLoss = CurrentState.PowershiftLossEnergy * VectoMath.Min(1.0, dt / remainingShiftLossLime);
-					var avgEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2;
-					CurrentState.PowershiftLoss = aliquotEnergyLoss / dt / avgEngineSpeed;
-					inTorque += CurrentState.PowershiftLoss;
-					CurrentState.PowershiftLossEnergy -= aliquotEnergyLoss;
-					//inTorque += CurrentState.PowershiftLossEnergy;
-				}
-			}
-
-			if (!dryRun) {
-				CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut;
-				CurrentState.TorqueLossResult = inTorqueLossResult;
-				CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-				CurrentState.Gear = Gear;
-				CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque;
-				TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque,
-					CurrentState.InAngularVelocity);
-			}
-
-			if (!CurrentState.TorqueConverterLocked) {
-				return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, dryRun);
-			}
-			var retVal = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, dryRun);
-			if (!dryRun && retVal is ResponseSuccess &&
-				_strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, Gear,
-					LastShift)) {
-				return new ResponseGearShift { Source = this };
-			}
-
-			return retVal;
-		}
-
-		private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun)
-		{
-			var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			if (dryRun) {
-				// if gearbox is disengaged the 0[W]-line is the limit for drag and full load.
-				return new ResponseDryRun {
-					Source = this,
-					GearboxPowerRequest = outTorque * avgAngularVelocity,
-					DeltaDragLoad = outTorque * avgAngularVelocity,
-					DeltaFullLoad = outTorque * avgAngularVelocity,
-				};
-			}
-			if ((outTorque * avgAngularVelocity).IsGreater(0.SI<Watt>(),
-				Constants.SimulationSettings.LineSearchTolerance)) {
-				return new ResponseOverload {
-					Source = this,
-					Delta = outTorque * avgAngularVelocity,
-					GearboxPowerRequest = outTorque * avgAngularVelocity
-				};
-			}
-
-			if ((outTorque * avgAngularVelocity).IsSmaller(0.SI<Watt>(),
-				Constants.SimulationSettings.LineSearchTolerance)) {
-				return new ResponseUnderload {
-					Source = this,
-					Delta = outTorque * avgAngularVelocity,
-					GearboxPowerRequest = outTorque * avgAngularVelocity
-				};
-			}
-
-			Log.Debug("Invoking IdleController...");
-
-			var retval = IdleController.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
-			retval.ClutchPowerRequest = 0.SI<Watt>();
-
-			// no dry-run - update state
-			var effectiveRatio = ModelData.Gears[Gear].Ratio;
-			if (!CurrentState.TorqueConverterLocked) {
-				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
-			}
-			CurrentState.SetState(0.SI<NewtonMeter>(), outAngularVelocity * effectiveRatio, outTorque,
-				outAngularVelocity);
-			CurrentState.Gear = 1;
-			CurrentState.TorqueConverterLocked = !ModelData.Gears[Gear].HasTorqueConverter;
-			CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() {
-				Extrapolated = false,
-				Value = 0.SI<NewtonMeter>()
-			};
-			TorqueConverter.Locked(DataBus.VehicleStopped ? 0.SI<NewtonMeter>() : CurrentState.InTorque, retval.EngineSpeed,
-				CurrentState.InTorque,
-				outAngularVelocity * effectiveRatio);
-
-
-			return retval;
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
-			var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
-
-			container[ModalResultField.Gear] = CurrentState.Disengaged || DataBus.VehicleStopped ? 0 : Gear;
-			container[ModalResultField.TC_Locked] = CurrentState.TorqueConverterLocked;
-			container[ModalResultField.P_gbx_loss] = CurrentState.InTorque * avgInAngularSpeed -
-													CurrentState.OutTorque * avgOutAngularSpeed;
-			container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed;
-			container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed;
-			container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLoss.DefaultIfNull(0) * avgInAngularSpeed;
-			container[ModalResultField.n_gbx_out_avg] = avgOutAngularSpeed;
-			container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			if (!CurrentState.Disengaged && CurrentState.TorqueLossResult != null &&
-				CurrentState.TorqueLossResult.Extrapolated) {
-				Log.Warn(
-					"Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}",
-					Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque,
-					ModelData.Gears[Gear].Ratio);
-				if (DataBus.ExecutionMode == ExecutionMode.Declaration) {
-					throw new VectoException(
-						"Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}",
-						Gear, CurrentState.InAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.InTorque,
-						ModelData.Gears[Gear].Ratio);
-				}
-			}
-			RequestAfterGearshift = false;
-
-			if (DataBus.VehicleStopped) {
-				CurrentState.Disengaged = true;
-			}
-
-			AdvanceState();
-
-			CurrentState.TorqueConverterLocked = PreviousState.TorqueConverterLocked;
-			CurrentState.Disengaged = PreviousState.Disengaged;
-		}
-
-		public class ATGearboxState : GearboxState
-		{
-			public bool TorqueConverterLocked;
-			public bool Disengaged = true;
-			public WattSecond PowershiftLossEnergy;
-			public NewtonMeter PowershiftLoss;
-		}
-	}
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class ATGearbox : AbstractGearbox<ATGearbox.ATGearboxState>
+	{
+		private readonly IShiftStrategy _strategy;
+		protected internal readonly TorqueConverter TorqueConverter;
+		private IIdleController _idleController;
+		protected bool RequestAfterGearshift;
+
+		public bool TorqueConverterLocked
+		{
+			get { return CurrentState.TorqueConverterLocked; }
+			set { CurrentState.TorqueConverterLocked = value; }
+		}
+
+		public ATGearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData)
+			: base(container, runData)
+		{
+			_strategy = strategy;
+			_strategy.Gearbox = this;
+			LastShift = -double.MaxValue.SI<Second>();
+			TorqueConverter = new TorqueConverter(this, _strategy, container, ModelData.TorqueConverterData,
+				runData);
+		}
+
+		public IIdleController IdleController
+		{
+			get { return _idleController; }
+			set
+			{
+				_idleController = value;
+				_idleController.RequestPort = NextComponent;
+			}
+		}
+
+		public bool Disengaged
+		{
+			get { return CurrentState.Disengaged; }
+			set { CurrentState.Disengaged = value; }
+		}
+
+		public override void Connect(ITnOutPort other)
+		{
+			base.Connect(other);
+			TorqueConverter.NextComponent = other;
+		}
+
+		public override GearInfo NextGear
+		{
+			get { return _strategy.NextGear; }
+		}
+
+		public override bool ClutchClosed(Second absTime)
+		{
+			return absTime.IsGreater(DataBus.AbsTime) ||
+					!(CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted));
+		}
+
+		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			if (CurrentState.Disengaged) {
+				Gear = _strategy.InitGear(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, outTorque,
+					outAngularVelocity);
+			}
+			var inAngularVelocity = 0.SI<PerSecond>();
+			var inTorque = 0.SI<NewtonMeter>();
+			var effectiveRatio = ModelData.Gears[Gear].Ratio;
+			var effectiveLossMap = ModelData.Gears[Gear].LossMap;
+			if (!CurrentState.TorqueConverterLocked) {
+				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
+				effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap;
+			}
+			if (!DataBus.VehicleStopped) {
+				inAngularVelocity = outAngularVelocity * effectiveRatio;
+				var torqueLossResult = effectiveLossMap.GetTorqueLoss(outAngularVelocity, outTorque);
+				CurrentState.TorqueLossResult = torqueLossResult;
+
+				inTorque = outTorque / effectiveRatio + torqueLossResult.Value;
+			}
+			if (CurrentState.Disengaged) {
+				return NextComponent.Initialize(0.SI<NewtonMeter>(), null);
+			}
+
+			if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) {
+				throw new VectoSimulationException(
+					"Torque converter requested by strategy for gear without torque converter!");
+			}
+			var response = CurrentState.TorqueConverterLocked
+				? NextComponent.Initialize(inTorque, inAngularVelocity)
+				: TorqueConverter.Initialize(inTorque, inAngularVelocity);
+
+			CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() {
+				Value = 0.SI<NewtonMeter>(),
+				Extrapolated = false
+			};
+
+			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+			PreviousState.Gear = Gear;
+			PreviousState.TorqueConverterLocked = CurrentState.TorqueConverterLocked;
+			return response;
+		}
+
+		internal ResponseDryRun Initialize(uint gear, bool torqueConverterLocked, NewtonMeter outTorque,
+			PerSecond outAngularVelocity)
+		{
+			var effectiveRatio = torqueConverterLocked
+				? ModelData.Gears[gear].Ratio
+				: ModelData.Gears[gear].TorqueConverterRatio;
+
+			var inAngularVelocity = outAngularVelocity * effectiveRatio;
+			var torqueLossResult = torqueConverterLocked
+				? ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque)
+				: ModelData.Gears[gear].TorqueConverterGearLossMap.GetTorqueLoss(outAngularVelocity, outTorque);
+
+			var inTorque = outTorque / effectiveRatio + torqueLossResult.Value;
+
+			IResponse response;
+			if (torqueConverterLocked) {
+				response = NextComponent.Initialize(inTorque, inAngularVelocity);
+			} else {
+				if (!ModelData.Gears[gear].HasTorqueConverter) {
+					throw new VectoSimulationException(
+						"Torque converter requested by strategy for gear without torque converter!");
+				}
+				response = TorqueConverter.Initialize(inTorque, inAngularVelocity);
+			}
+
+			response.Switch().
+				Case<ResponseSuccess>(). // accept
+				Case<ResponseUnderload>(). // accept
+				Case<ResponseOverload>(). // accept
+				Default(r => {
+					throw new UnexpectedResponseException("AT-Gearbox.Initialize", r);
+				});
+
+			return new ResponseDryRun {
+				Source = this,
+				EngineSpeed = response.EngineSpeed,
+				EnginePowerRequest = response.EnginePowerRequest,
+				GearboxPowerRequest = outTorque * outAngularVelocity,
+			};
+		}
+
+		public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun = false)
+		{
+			IterationStatistics.Increment(this, "Requests");
+
+			Log.Debug("AT-Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
+
+			var driveOffSpeed = DataBus.VehicleStopped && outAngularVelocity > 0;
+			var driveOffTorque = CurrentState.Disengaged && outTorque.IsGreater(0, 1e-3);
+			if (!dryRun && (driveOffSpeed || driveOffTorque)) {
+				Gear = 1;
+				CurrentState.TorqueConverterLocked = false;
+				LastShift = absTime;
+				CurrentState.Disengaged = false;
+			}
+
+			IResponse retVal;
+			var count = 0;
+			var loop = false;
+			SetPowershiftLossEnergy(absTime, dt, outTorque, outAngularVelocity);
+			do {
+				if (CurrentState.Disengaged || (DataBus.DriverBehavior == DrivingBehavior.Halted)) {
+					// only when vehicle is halted or close before halting
+					retVal = RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+				} else {
+					CurrentState.Disengaged = false;
+					retVal = RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+					IdleController.Reset();
+				}
+				if (!(retVal is ResponseGearShift)) {
+					continue;
+				}
+				if (ConsiderShiftLosses(_strategy.NextGear, outTorque)) {
+					retVal = new ResponseFailTimeInterval {
+						Source = this,
+						DeltaT = ModelData.PowershiftShiftTime,
+						GearboxPowerRequest =
+							outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0
+					};
+					RequestAfterGearshift = true;
+					LastShift = absTime;
+				} else {
+					loop = true;
+					Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
+					LastShift = absTime;
+				}
+			} while (loop && ++count < 2);
+
+			retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			return retVal;
+		}
+
+		private void SetPowershiftLossEnergy(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			if (RequestAfterGearshift) {
+				LastShift = absTime;
+				Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
+				CurrentState.PowershiftLossEnergy = ComputeShiftLosses(outTorque, outAngularVelocity);
+			} else {
+				if (PreviousState.PowershiftLossEnergy != null && PreviousState.PowershiftLossEnergy.IsGreater(0)) {
+					CurrentState.PowershiftLossEnergy = PreviousState.PowershiftLossEnergy;
+				}
+			}
+		}
+
+		private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun)
+		{
+			if (!CurrentState.TorqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) {
+				throw new VectoSimulationException(
+					"Torque converter requested by strategy for gear without torque converter!");
+			}
+
+			var effectiveRatio = ModelData.Gears[Gear].Ratio;
+			var effectiveLossMap = ModelData.Gears[Gear].LossMap;
+			if (!CurrentState.TorqueConverterLocked) {
+				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
+				effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap;
+			}
+
+			var inAngularVelocity = outAngularVelocity * effectiveRatio;
+			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0;
+			var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
+			var inTorque = outTorque * (avgOutAngularVelocity / avgInAngularVelocity) + inTorqueLossResult.Value;
+
+			var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
+				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
+				avgOutAngularVelocity
+				: 0.SI<NewtonMeter>();
+			inTorque += inertiaTorqueLossOut / effectiveRatio;
+
+			if (CurrentState.PowershiftLossEnergy != null) {
+				var remainingShiftLossLime = ModelData.PowershiftShiftTime - (absTime - LastShift);
+				if (remainingShiftLossLime.IsGreater(0)) {
+					var aliquotEnergyLoss = CurrentState.PowershiftLossEnergy * VectoMath.Min(1.0, dt / remainingShiftLossLime);
+					var avgEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2;
+					CurrentState.PowershiftLoss = aliquotEnergyLoss / dt / avgEngineSpeed;
+					inTorque += CurrentState.PowershiftLoss;
+					CurrentState.PowershiftLossEnergy -= aliquotEnergyLoss;
+					//inTorque += CurrentState.PowershiftLossEnergy;
+				}
+			}
+
+			if (!dryRun) {
+				CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut;
+				CurrentState.TorqueLossResult = inTorqueLossResult;
+				CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+				CurrentState.Gear = Gear;
+				CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque;
+				TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque,
+					CurrentState.InAngularVelocity);
+			}
+
+			if (!CurrentState.TorqueConverterLocked) {
+				return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, dryRun);
+			}
+			var retVal = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, dryRun);
+			if (!dryRun && retVal is ResponseSuccess &&
+				_strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, Gear,
+					LastShift)) {
+				return new ResponseGearShift { Source = this };
+			}
+
+			return retVal;
+		}
+
+		private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun)
+		{
+			var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			if (dryRun) {
+				// if gearbox is disengaged the 0[W]-line is the limit for drag and full load.
+				return new ResponseDryRun {
+					Source = this,
+					GearboxPowerRequest = outTorque * avgAngularVelocity,
+					DeltaDragLoad = outTorque * avgAngularVelocity,
+					DeltaFullLoad = outTorque * avgAngularVelocity,
+				};
+			}
+			if ((outTorque * avgAngularVelocity).IsGreater(0.SI<Watt>(),
+				Constants.SimulationSettings.LineSearchTolerance)) {
+				return new ResponseOverload {
+					Source = this,
+					Delta = outTorque * avgAngularVelocity,
+					GearboxPowerRequest = outTorque * avgAngularVelocity
+				};
+			}
+
+			if ((outTorque * avgAngularVelocity).IsSmaller(0.SI<Watt>(),
+				Constants.SimulationSettings.LineSearchTolerance)) {
+				return new ResponseUnderload {
+					Source = this,
+					Delta = outTorque * avgAngularVelocity,
+					GearboxPowerRequest = outTorque * avgAngularVelocity
+				};
+			}
+
+			Log.Debug("Invoking IdleController...");
+
+			var retval = IdleController.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
+			retval.ClutchPowerRequest = 0.SI<Watt>();
+
+			// no dry-run - update state
+			var effectiveRatio = ModelData.Gears[Gear].Ratio;
+			if (!CurrentState.TorqueConverterLocked) {
+				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
+			}
+			CurrentState.SetState(0.SI<NewtonMeter>(), outAngularVelocity * effectiveRatio, outTorque,
+				outAngularVelocity);
+			CurrentState.Gear = 1;
+			CurrentState.TorqueConverterLocked = !ModelData.Gears[Gear].HasTorqueConverter;
+			CurrentState.TorqueLossResult = new TransmissionLossMap.LossMapResult() {
+				Extrapolated = false,
+				Value = 0.SI<NewtonMeter>()
+			};
+			TorqueConverter.Locked(DataBus.VehicleStopped ? 0.SI<NewtonMeter>() : CurrentState.InTorque, retval.EngineSpeed,
+				CurrentState.InTorque,
+				outAngularVelocity * effectiveRatio);
+
+
+			return retval;
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
+			var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
+
+			container[ModalResultField.Gear] = CurrentState.Disengaged || DataBus.VehicleStopped ? 0 : Gear;
+			container[ModalResultField.TC_Locked] = CurrentState.TorqueConverterLocked;
+			container[ModalResultField.P_gbx_loss] = CurrentState.InTorque * avgInAngularSpeed -
+													CurrentState.OutTorque * avgOutAngularSpeed;
+			container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed;
+			container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed;
+			container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLoss.DefaultIfNull(0) * avgInAngularSpeed;
+			container[ModalResultField.n_gbx_out_avg] = avgOutAngularSpeed;
+			container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			if (!CurrentState.Disengaged && CurrentState.TorqueLossResult != null &&
+				CurrentState.TorqueLossResult.Extrapolated) {
+				Log.Warn(
+					"Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}",
+					Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque,
+					ModelData.Gears[Gear].Ratio);
+				if (DataBus.ExecutionMode == ExecutionMode.Declaration) {
+					throw new VectoException(
+						"Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}, ratio:{3}",
+						Gear, CurrentState.InAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.InTorque,
+						ModelData.Gears[Gear].Ratio);
+				}
+			}
+			RequestAfterGearshift = false;
+
+			if (DataBus.VehicleStopped) {
+				CurrentState.Disengaged = true;
+			}
+
+			AdvanceState();
+
+			CurrentState.TorqueConverterLocked = PreviousState.TorqueConverterLocked;
+			CurrentState.Disengaged = PreviousState.Disengaged;
+		}
+
+		public class ATGearboxState : GearboxState
+		{
+			public bool TorqueConverterLocked;
+			public bool Disengaged = true;
+			public WattSecond PowershiftLossEnergy;
+			public NewtonMeter PowershiftLoss;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
index d70578e50ffec17b881e327011aab48b359559a8..3031474f54c6eba9a92e7f88cb5a4ac4891e9cba 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
@@ -29,326 +29,346 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class ATShiftStrategy : BaseShiftStrategy
-	{
-		private ATGearbox _gearbox;
-		private readonly NextGearState _nextGear = new NextGearState();
-
-		public override IGearbox Gearbox
-		{
-			get { return _gearbox; }
-			set {
-				_gearbox = value as ATGearbox;
-				if (_gearbox == null) {
-					throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType());
-				}
-			}
-		}
-
-		public override GearInfo NextGear
-		{
-			get { return new GearInfo(_nextGear.Gear, _nextGear.TorqueConverterLocked); }
-		}
-
-		public ATShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {}
-
-		public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
-		{
-			if (DataBus.VehicleSpeed.IsEqual(0)) {
-				// AT always starts in first gear and TC active!
-				_gearbox.TorqueConverterLocked = false;
-				_gearbox.Disengaged = true;
-				return 1;
-			}
-			var torqueConverterLocked = true;
-			for (var gear = ModelData.Gears.Keys.Max(); gear > 1; gear--) {
-				if (_gearbox.ModelData.Gears[gear].HasTorqueConverter) {
-					torqueConverterLocked = false;
-				}
-				var response = _gearbox.Initialize(gear, torqueConverterLocked, torque, outAngularVelocity);
-
-				if (response.EngineSpeed > DataBus.EngineRatedSpeed || response.EngineSpeed < DataBus.EngineIdleSpeed) {
-					continue;
-				}
-
-				if (!IsBelowDownShiftCurve(gear, response.EnginePowerRequest / response.EngineSpeed, response.EngineSpeed)) {
-					_gearbox.TorqueConverterLocked = torqueConverterLocked;
-					_gearbox.Disengaged = false;
-					return gear;
-				}
-			}
-			// fallback: start with first gear;
-			_gearbox.TorqueConverterLocked = false;
-			_gearbox.Disengaged = false;
-			return 1;
-		}
-
-		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) {
-				_gearbox.TorqueConverterLocked = _nextGear.TorqueConverterLocked;
-				_gearbox.Disengaged = _nextGear.Disengaged;
-				_nextGear.AbsTime = null;
-				return _nextGear.Gear;
-			}
-			_nextGear.AbsTime = null;
-			return _gearbox.Gear;
-		}
-
-		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
-		{
-			throw new System.NotImplementedException("AT Shift Strategy does not support disengaging.");
-		}
-
-		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
-		{
-			// ENGAGE ---------------------------------------------------------
-			// 0 -> 1C: drive off after disengaged - engage first gear
-			if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) {
-				Log.Debug("shift required: drive off after vehicle stopped");
-				_nextGear.SetState(absTime, disengaged: false, gear: 1, tcLocked: false);
-				return true;
-			}
-
-			// DISENGAGE ------------------------------------------------------
-			// 1) _ -> 0: disengage before halting
-			var braking = DataBus.DriverBehavior == DrivingBehavior.Braking;
-			var torqueNegative = outTorque.IsSmaller(0);
-			var slowerThanDisengageSpeed =
-				DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed);
-			var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed;
-
-			// 2) L -> 0: disengage if inAngularVelocity == 0
-			var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>());
-
-			// 3) 1C -> 0: disengange when negative T_out and positive T_in
-			var gear1C = gear == 1 && !_gearbox.TorqueConverterLocked;
-			var disengageTOutNegativeAndTInPositive = DataBus.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) &&
-													inTorque.IsGreater(0);
-
-			var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C &&
-												inAngularVelocity.IsSmallerOrEqual(DataBus.EngineIdleSpeed);
-
-			if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero ||
-				disengageTOutNegativeAndTInPositive) {
-				_nextGear.SetState(absTime, disengaged: true, gear: 1, tcLocked: false);
-				return true;
-			}
-
-			// EMERGENCY SHIFTS ---------------------------------------
-			// Emergency Downshift: if lower than engine idle speed
-			if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
-				Log.Debug("engine speed would fall below idle speed - shift down");
-				Downshift(absTime, gear);
-				return true;
-			}
-			// Emergency Upshift: if higher than engine rated speed
-			if (inAngularVelocity.IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? DataBus.EngineRatedSpeed)) {
-				// check if upshift is possible
-				if (!ModelData.Gears.ContainsKey(gear + 1)) {
-					return false;
-				}
-				Log.Debug("engine speed would be above max speed / rated speed - shift up");
-				Upshift(absTime, gear);
-				return true;
-			}
-
-			// UPSHIFT --------------------------------------------------------
-			if (CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
-				lastShiftTime)) {
-				return true;
-			}
-
-			// DOWNSHIFT ------------------------------------------------------
-			if (CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
-				lastShiftTime)) {
-				return true;
-			}
-
-			return false;
-		}
-
-		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
-		private bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
-		{
-			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime);
-			if (!shiftTimeReached) {
-				return false;
-			}
-
-			var currentGear = ModelData.Gears[gear];
-
-			if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) {
-				// UPSHIFT - General Rule
-				// L -> L+1 
-				// C -> L
-				var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear;
-				if (!ModelData.Gears.ContainsKey(nextGear)) {
-					return false;
-				}
-
-				var nextEngineSpeed = outAngularVelocity * ModelData.Gears[nextGear].Ratio;
-				if (nextEngineSpeed.IsEqual(0)) {
-					return false;
-				}
-
-				var currentEnginePower = inTorque * inAngularVelocity;
-				var nextEngineTorque = currentEnginePower / nextEngineSpeed;
-				var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked);
-
-				var minAccelerationReachable = true;
-				if (!DataBus.VehicleSpeed.IsEqual(0)) {
-					var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity);
-					var minAcceleration = _gearbox.TorqueConverterLocked
-						? ModelData.UpshiftMinAcceleration
-						: ModelData.TorqueConverterData.CLUpshiftMinAcceleration;
-					minAcceleration = VectoMath.Min(minAcceleration, DataBus.DriverAcceleration);
-					minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
-				}
-
-				if (isAboveUpShift && minAccelerationReachable) {
-					Upshift(absTime, gear);
-					return true;
-				}
-			}
-
-			// UPSHIFT - Special rule for 1C -> 2C
-			if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) &&
-				ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) {
-				// C -> C+1
-				var nextGear = ModelData.Gears[gear + 1];
-				var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio;
-				var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad()));
-
-				var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio;
-				var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio;
-				var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGearboxInTorque, nextGearboxInSpeed);
-
-				var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed);
-
-				var reachableAcceleration = EstimateAccelerationForGear(gear + 1, outAngularVelocity);
-				var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration,
-					DataBus.DriverAcceleration);
-				var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
-
-				if (engineSpeedOverMin && minAccelerationReachable) {
-					Upshift(absTime, gear);
-					return true;
-				}
-			}
-			return false;
-		}
-
-		/// <summary>
-		/// Tests if the operating point is above (right of) the up-shift curve.
-		/// </summary>
-		/// <param name="gear">The gear.</param>
-		/// <param name="inTorque">The in torque.</param>
-		/// <param name="inEngineSpeed">The in engine speed.</param>
-		/// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param>
-		/// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns>
-		private bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed,
-			bool torqueConverterLocked)
-		{
-			var shiftPolygon = torqueConverterLocked
-				? ModelData.Gears[gear].ShiftPolygon
-				: ModelData.Gears[gear].TorqueConverterShiftPolygon;
-
-			return gear < ModelData.Gears.Keys.Max() && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
-		}
-
-		private void Upshift(Second absTime, uint gear)
-		{
-			// C -> L: switch from torque converter to locked gear
-			if (!_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasLockedGear) {
-				_nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: true);
-				return;
-			}
-
-			// L -> L+1
-			// C -> C+1
-			if (ModelData.Gears.ContainsKey(gear + 1)) {
-				_nextGear.SetState(absTime, disengaged: false, gear: gear + 1, tcLocked: _gearbox.TorqueConverterLocked);
-				return;
-			}
-
-			// C -> L+1 -- not allowed!!
-			throw new VectoSimulationException(
-				"ShiftStrategy wanted to shift up, but current gear has active torque converter (C) but no locked gear (no L) and shifting directly to (L) is not allowed.");
-		}
-
-		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
-		private bool CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
-		{
-			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime);
-
-			if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) {
-				Downshift(absTime, gear);
-				return true;
-			}
-
-			return false;
-		}
-
-		/// <summary>
-		/// Tests if the operating point is below (left of) the down-shift curve.
-		/// </summary>
-		/// <param name="gear">The gear.</param>
-		/// <param name="inTorque">The in torque.</param>
-		/// <param name="inEngineSpeed">The in engine speed.</param>
-		/// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns>
-		private bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
-		{
-			return gear > 1 && ModelData.Gears[gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed);
-		}
-
-		private void Downshift(Second absTime, uint gear)
-		{
-			// L -> C
-			if (_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasTorqueConverter) {
-				_nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: false);
-				return;
-			}
-
-			// L -> L-1
-			// C -> C-1
-			if (ModelData.Gears.ContainsKey(gear - 1)) {
-				_nextGear.SetState(absTime, disengaged: false, gear: gear - 1, tcLocked: _gearbox.TorqueConverterLocked);
-				return;
-			}
-
-			// L -> 0 -- not allowed!!
-			throw new VectoSimulationException(
-				"ShiftStrategy wanted to shift down but current gear is locked (L) and has no torque converter (C) and disenganging directly from (L) is not allowed.");
-		}
-
-		private class NextGearState
-		{
-			public Second AbsTime;
-			public bool Disengaged;
-			public uint Gear;
-			public bool TorqueConverterLocked;
-
-			public void SetState(Second absTime, bool disengaged, uint gear, bool tcLocked)
-			{
-				AbsTime = absTime;
-				Disengaged = disengaged;
-				Gear = gear;
-				TorqueConverterLocked = tcLocked;
-			}
-		}
-	}
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class ATShiftStrategy : BaseShiftStrategy
+	{
+		private ATGearbox _gearbox;
+		private readonly NextGearState _nextGear = new NextGearState();
+
+		public override IGearbox Gearbox
+		{
+			get { return _gearbox; }
+			set
+			{
+				_gearbox = value as ATGearbox;
+				if (_gearbox == null) {
+					throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType());
+				}
+			}
+		}
+
+		public override GearInfo NextGear
+		{
+			get { return new GearInfo(_nextGear.Gear, _nextGear.TorqueConverterLocked); }
+		}
+
+		public ATShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {}
+
+		public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
+		{
+			if (DataBus.VehicleSpeed.IsEqual(0)) {
+				// AT always starts in first gear and TC active!
+				_gearbox.TorqueConverterLocked = false;
+				_gearbox.Disengaged = true;
+				return 1;
+			}
+			var torqueConverterLocked = true;
+			for (var gear = ModelData.Gears.Keys.Max(); gear > 1; gear--) {
+				if (_gearbox.ModelData.Gears[gear].HasTorqueConverter) {
+					torqueConverterLocked = false;
+				}
+				var response = _gearbox.Initialize(gear, torqueConverterLocked, torque, outAngularVelocity);
+
+				if (response.EngineSpeed > DataBus.EngineRatedSpeed || response.EngineSpeed < DataBus.EngineIdleSpeed) {
+					continue;
+				}
+
+				if (!IsBelowDownShiftCurve(gear, response.EnginePowerRequest / response.EngineSpeed, response.EngineSpeed)) {
+					_gearbox.TorqueConverterLocked = torqueConverterLocked;
+					_gearbox.Disengaged = false;
+					return gear;
+				}
+			}
+			// fallback: start with first gear;
+			_gearbox.TorqueConverterLocked = false;
+			_gearbox.Disengaged = false;
+			return 1;
+		}
+
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) {
+				_gearbox.TorqueConverterLocked = _nextGear.TorqueConverterLocked;
+				_gearbox.Disengaged = _nextGear.Disengaged;
+				_nextGear.AbsTime = null;
+				return _nextGear.Gear;
+			}
+			_nextGear.AbsTime = null;
+			return _gearbox.Gear;
+		}
+
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		{
+			throw new System.NotImplementedException("AT Shift Strategy does not support disengaging.");
+		}
+
+		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+		{
+			// ENGAGE ---------------------------------------------------------
+			// 0 -> 1C: drive off after disengaged - engage first gear
+			if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) {
+				Log.Debug("shift required: drive off after vehicle stopped");
+				_nextGear.SetState(absTime, disengaged: false, gear: 1, tcLocked: false);
+				return true;
+			}
+
+			// DISENGAGE ------------------------------------------------------
+			// 1) _ -> 0: disengage before halting
+			var braking = DataBus.DriverBehavior == DrivingBehavior.Braking;
+			var torqueNegative = outTorque.IsSmaller(0);
+			var slowerThanDisengageSpeed =
+				DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ATGearboxDisengageWhenHaltingSpeed);
+			var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed;
+
+			// 2) L -> 0: disengage if inAngularVelocity == 0
+			var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>());
+
+			// 3) 1C -> 0: disengange when negative T_out and positive T_in
+			var gear1C = gear == 1 && !_gearbox.TorqueConverterLocked;
+			var disengageTOutNegativeAndTInPositive = DataBus.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) &&
+													inTorque.IsGreater(0);
+
+			var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C &&
+												inAngularVelocity.IsSmallerOrEqual(DataBus.EngineIdleSpeed);
+
+			if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero ||
+				disengageTOutNegativeAndTInPositive) {
+				_nextGear.SetState(absTime, disengaged: true, gear: 1, tcLocked: false);
+				return true;
+			}
+
+			// EMERGENCY SHIFTS ---------------------------------------
+			// Emergency Downshift: if lower than engine idle speed
+			if (inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+				Log.Debug("engine speed would fall below idle speed - shift down");
+				Downshift(absTime, gear);
+				return true;
+			}
+			// Emergency Upshift: if higher than engine rated speed
+			if (inAngularVelocity.IsGreaterOrEqual(ModelData.Gears[gear].MaxSpeed ?? DataBus.EngineRatedSpeed)) {
+				// check if upshift is possible
+				if (!ModelData.Gears.ContainsKey(gear + 1)) {
+					return false;
+				}
+				Log.Debug("engine speed would be above max speed / rated speed - shift up");
+				Upshift(absTime, gear);
+				return true;
+			}
+
+			// UPSHIFT --------------------------------------------------------
+			if (CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
+				lastShiftTime)) {
+				return true;
+			}
+
+			// DOWNSHIFT ------------------------------------------------------
+			if (CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
+				lastShiftTime)) {
+				return true;
+			}
+
+			return false;
+		}
+
+		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
+		private bool CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+		{
+			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime);
+			if (!shiftTimeReached) {
+				return false;
+			}
+
+			var currentGear = ModelData.Gears[gear];
+
+			if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) {
+				if (CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear)) {
+					return true;
+				}
+			}
+
+			// UPSHIFT - Special rule for 1C -> 2C
+			if (!_gearbox.TorqueConverterLocked && ModelData.Gears.ContainsKey(gear + 1) &&
+				ModelData.Gears[gear + 1].HasTorqueConverter && outAngularVelocity.IsGreater(0)) {
+				if (CheckUpshiftTcTc(absTime, outTorque, outAngularVelocity, gear, currentGear)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private bool CheckUpshiftTcTc(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, uint gear,
+			GearData currentGear)
+		{
+// C -> C+1
+			var nextGear = ModelData.Gears[gear + 1];
+			var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio;
+			var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineN80hSpeed - 150.RPMtoRad()));
+
+			var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio;
+			var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio;
+			var tcOperatingPoint = _gearbox.TorqueConverter.FindOperatingPoint(nextGearboxInTorque, nextGearboxInSpeed);
+
+			var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed);
+
+			var reachableAcceleration = EstimateAccelerationForGear(gear + 1, outAngularVelocity);
+			var minAcceleration = VectoMath.Min(ModelData.TorqueConverterData.CCUpshiftMinAcceleration,
+				DataBus.DriverAcceleration);
+			var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
+
+			if (engineSpeedOverMin && minAccelerationReachable) {
+				Upshift(absTime, gear);
+				return true;
+			}
+			return false;
+		}
+
+		private bool CheckUpshiftToLocked(Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, uint gear)
+		{
+// UPSHIFT - General Rule
+			// L -> L+1 
+			// C -> L
+			var nextGear = _gearbox.TorqueConverterLocked ? gear + 1 : gear;
+			if (!ModelData.Gears.ContainsKey(nextGear)) {
+				return true;
+			}
+
+			var nextEngineSpeed = outAngularVelocity * ModelData.Gears[nextGear].Ratio;
+			if (nextEngineSpeed.IsEqual(0)) {
+				return true;
+			}
+
+			var currentEnginePower = inTorque * inAngularVelocity;
+			var nextEngineTorque = currentEnginePower / nextEngineSpeed;
+			var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked);
+
+			var minAccelerationReachable = true;
+			if (!DataBus.VehicleSpeed.IsEqual(0)) {
+				var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity);
+				var minAcceleration = _gearbox.TorqueConverterLocked
+					? ModelData.UpshiftMinAcceleration
+					: ModelData.TorqueConverterData.CLUpshiftMinAcceleration;
+				minAcceleration = VectoMath.Min(minAcceleration, DataBus.DriverAcceleration);
+				minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
+			}
+
+			if (isAboveUpShift && minAccelerationReachable) {
+				Upshift(absTime, gear);
+				return true;
+			}
+			return false;
+		}
+
+		/// <summary>
+		/// Tests if the operating point is above (right of) the up-shift curve.
+		/// </summary>
+		/// <param name="gear">The gear.</param>
+		/// <param name="inTorque">The in torque.</param>
+		/// <param name="inEngineSpeed">The in engine speed.</param>
+		/// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param>
+		/// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns>
+		private bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed,
+			bool torqueConverterLocked)
+		{
+			var shiftPolygon = torqueConverterLocked
+				? ModelData.Gears[gear].ShiftPolygon
+				: ModelData.Gears[gear].TorqueConverterShiftPolygon;
+
+			return gear < ModelData.Gears.Keys.Max() && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
+		}
+
+		private void Upshift(Second absTime, uint gear)
+		{
+			// C -> L: switch from torque converter to locked gear
+			if (!_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasLockedGear) {
+				_nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: true);
+				return;
+			}
+
+			// L -> L+1
+			// C -> C+1
+			if (ModelData.Gears.ContainsKey(gear + 1)) {
+				_nextGear.SetState(absTime, disengaged: false, gear: gear + 1, tcLocked: _gearbox.TorqueConverterLocked);
+				return;
+			}
+
+			// C -> L+1 -- not allowed!!
+			throw new VectoSimulationException(
+				"ShiftStrategy wanted to shift up, but current gear has active torque converter (C) but no locked gear (no L) and shifting directly to (L) is not allowed.");
+		}
+
+		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
+		private bool CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+		{
+			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(ModelData.ShiftTime);
+
+			if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) {
+				Downshift(absTime, gear);
+				return true;
+			}
+
+			return false;
+		}
+
+		/// <summary>
+		/// Tests if the operating point is below (left of) the down-shift curve.
+		/// </summary>
+		/// <param name="gear">The gear.</param>
+		/// <param name="inTorque">The in torque.</param>
+		/// <param name="inEngineSpeed">The in engine speed.</param>
+		/// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns>
+		private bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		{
+			return gear > 1 && ModelData.Gears[gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed);
+		}
+
+		private void Downshift(Second absTime, uint gear)
+		{
+			// L -> C
+			if (_gearbox.TorqueConverterLocked && ModelData.Gears[gear].HasTorqueConverter) {
+				_nextGear.SetState(absTime, disengaged: false, gear: gear, tcLocked: false);
+				return;
+			}
+
+			// L -> L-1
+			// C -> C-1
+			if (ModelData.Gears.ContainsKey(gear - 1)) {
+				_nextGear.SetState(absTime, disengaged: false, gear: gear - 1, tcLocked: _gearbox.TorqueConverterLocked);
+				return;
+			}
+
+			// L -> 0 -- not allowed!!
+			throw new VectoSimulationException(
+				"ShiftStrategy wanted to shift down but current gear is locked (L) and has no torque converter (C) and disenganging directly from (L) is not allowed.");
+		}
+
+		private class NextGearState
+		{
+			public Second AbsTime;
+			public bool Disengaged;
+			public uint Gear;
+			public bool TorqueConverterLocked;
+
+			public void SetState(Second absTime, bool disengaged, uint gear, bool tcLocked)
+			{
+				AbsTime = absTime;
+				Disengaged = disengaged;
+				Gear = gear;
+				TorqueConverterLocked = tcLocked;
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
index 8609584f951d3d9cdcdd94031ff90b85f557cc59..1a001d4de84453d4148a1428e7867cbb8f9c4a8c 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CycleGearbox.cs
@@ -29,506 +29,504 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState>
-	{
-		/// <summary>
-		/// True if gearbox is disengaged (no gear is set).
-		/// </summary>
-		protected internal Second Disengaged;
-
-		protected bool? TorqueConverterActive;
-
-		protected internal readonly TorqueConverter TorqueConverter;
-
-		public CycleGearbox(IVehicleContainer container, VectoRunData runData)
-			: base(container, runData)
-		{
-			if (!ModelData.Type.AutomaticTransmission()) {
-				return;
-			}
-			var strategy = new CycleShiftStrategy(ModelData, null);
-			TorqueConverter = new TorqueConverter(this, strategy, container, ModelData.TorqueConverterData, runData);
-			if (TorqueConverter == null) {
-				throw new VectoException("Torque Converter required for AT transmission!");
-			}
-		}
-
-		public override void Connect(ITnOutPort other)
-		{
-			base.Connect(other);
-			if (TorqueConverter != null) {
-				TorqueConverter.NextComponent = other;
-			}
-		}
-
-		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			var dt = Constants.SimulationSettings.TargetTimeInterval;
-
-			Gear = DataBus.CycleData.LeftSample.Gear;
-			TorqueConverterActive = DataBus.CycleData.LeftSample.TorqueConverterActive;
-
-			if (TorqueConverter != null && TorqueConverterActive == null) {
-				throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!");
-			}
-
-			var inAngularVelocity = DataBus.EngineIdleSpeed;
-			var inTorque = 0.SI<NewtonMeter>();
-			IResponse response;
-
-			if (Gear != 0) {
-				inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
-				var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
-				CurrentState.TorqueLossResult = inTorqueLossResult;
-				inTorque = outTorque / ModelData.Gears[Gear].Ratio + inTorqueLossResult.Value;
-
-				var torqueLossInertia = outAngularVelocity.IsEqual(0)
-					? 0.SI<NewtonMeter>()
-					: Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) /
-					inAngularVelocity;
-
-				inTorque += torqueLossInertia;
-
-				response = TorqueConverterActive != null && TorqueConverterActive.Value && TorqueConverter != null
-					? TorqueConverter.Initialize(inTorque, inAngularVelocity)
-					: NextComponent.Initialize(inTorque, inAngularVelocity);
-			} else {
-				response = NextComponent.Initialize(inTorque, inAngularVelocity);
-			}
-			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-			PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>();
-			PreviousState.Gear = Gear;
-
-			response.GearboxPowerRequest = inTorque * inAngularVelocity;
-			return response;
-		}
-
-		/// <summary>
-		/// Requests the Gearbox to deliver torque and angularVelocity
-		/// </summary>
-		/// <returns>
-		/// <list type="bullet">
-		/// <item><description>ResponseDryRun</description></item>
-		/// <item><description>ResponseOverload</description></item>
-		/// <item><description>ResponseGearshift</description></item>
-		/// </list>
-		/// </returns>
-		public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun = false)
-		{
-			Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
-			var gear = GetGearFromCycle();
-
-			TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking
-				? DataBus.CycleData.LeftSample.TorqueConverterActive
-				: DataBus.CycleData.RightSample.TorqueConverterActive;
-
-			if (TorqueConverter != null && TorqueConverterActive == null) {
-				throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!");
-			}
-			if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) {
-				throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear);
-			}
-
-			// mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run
-			// mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_*
-			var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted
-				//|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1))
-				? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun)
-				: RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-
-			retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2;
-			return retVal;
-		}
-
-		private uint GetGearFromCycle()
-		{
-			return DataBus.DriverBehavior == DrivingBehavior.Braking
-				? DataBus.CycleData.LeftSample.Gear
-				: DataBus.CycleData.RightSample.Gear;
-		}
-
-		/// <summary>
-		/// Handles requests when a gear is engaged
-		/// </summary>
-		/// <param name="absTime"></param>
-		/// <param name="dt"></param>
-		/// <param name="outTorque"></param>
-		/// <param name="outAngularVelocity"></param>
-		/// <param name="dryRun"></param>
-		/// <returns></returns>
-		private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun)
-		{
-			Disengaged = null;
-
-			Gear = GetGearFromCycle();
-
-			var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value;
-
-			var effectiveRatio = ModelData.Gears[Gear].Ratio;
-			var effectiveLossMap = ModelData.Gears[Gear].LossMap;
-			if (!torqueConverterLocked) {
-				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
-				effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap;
-			}
-
-			if (effectiveLossMap == null || double.IsNaN(effectiveRatio)) {
-				throw new VectoSimulationException("Ratio or loss-map for gear {0}{1} invalid. Please check input data", Gear,
-					torqueConverterLocked ? "L" : "C");
-			}
-
-			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
-			CurrentState.TorqueLossResult = inTorqueLossResult;
-			var inTorque = outTorque / effectiveRatio + inTorqueLossResult.Value;
-			CurrentState.TorqueLossResult = inTorqueLossResult;
-
-			if (!torqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) {
-				throw new VectoSimulationException("Torque converter requested by cycle for gear without torque converter!");
-			}
-
-			var inAngularVelocity = outAngularVelocity * effectiveRatio;
-
-			// TODO: MQ 20170111 - disabled this check, caused more problems than it actually solved... -- re-think
-			//if (!dryRun && ModelData.Type.AutomaticTransmission() && torqueConverterLocked &&
-			//	inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed) && !dryRun) {
-			//	Log.Error(
-			//		"ERROR: EngineSpeed is lower than Idlespeed in Measuredspeed-Cycle with given Gear (Automatic Transmission). AbsTime: {0}, Gear: {1} TC-Active: {2}, EngineSpeed: {3}",
-			//		absTime, Gear, !torqueConverterLocked, inAngularVelocity.AsRPM);
-			//	return new ResponseEngineSpeedTooLow { Source = this, EngineSpeed = inAngularVelocity };
-			//}
-
-			if (!inAngularVelocity.IsEqual(0)) {
-				// MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side
-				CurrentState.InertiaTorqueLossOut =
-					Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
-					avgOutAngularVelocity;
-				inTorque += CurrentState.InertiaTorqueLossOut / effectiveRatio;
-			} else {
-				CurrentState.InertiaTorqueLossOut = 0.SI<NewtonMeter>();
-			}
-			if (Gear != PreviousState.Gear &&
-				ConsiderShiftLosses(new GearInfo(Gear, torqueConverterLocked), outTorque)) {
-				CurrentState.PowershiftLosses = ComputeShiftLosses(outTorque, outAngularVelocity);
-			}
-			if (CurrentState.PowershiftLosses != null) {
-				var averageEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2;
-				inTorque += CurrentState.PowershiftLosses / dt / averageEngineSpeed;
-			}
-			if (dryRun) {
-				if (TorqueConverter != null && !torqueConverterLocked) {
-					return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true);
-				}
-				// mk 2016-12-13
-				//if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
-				//	//Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear,
-				//	//	DataBus.VehicleSpeed);
-				//	Gear = 0;
-				//	return RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-				//}
-				var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true);
-				dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
-				return dryRunResponse;
-			}
-
-			CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque;
-
-
-			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-			CurrentState.Gear = Gear;
-			// end critical section
-
-			if (TorqueConverter != null && !torqueConverterLocked) {
-				CurrentState.TorqueConverterActive = true;
-				return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity);
-			}
-			// mk 2016-12-13
-			//if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
-			//	Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear,
-			//		DataBus.VehicleSpeed);
-			//	Gear = 0;
-			//	return RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-			//}
-			if (TorqueConverter != null) {
-				TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque,
-					CurrentState.InAngularVelocity);
-			}
-			var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity);
-			response.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
-			return response;
-		}
-
-		/// <summary>
-		/// Handles Requests when no gear is disengaged
-		/// </summary>
-		/// <param name="absTime"></param>
-		/// <param name="dt"></param>
-		/// <param name="outTorque"></param>
-		/// <param name="outAngularVelocity"></param>
-		/// <param name="dryRun"></param>
-		/// <returns></returns>
-		private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun)
-		{
-			if (Disengaged == null) {
-				Disengaged = absTime;
-			}
-
-			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			if (dryRun) {
-				// if gearbox is disengaged the 0-line is the limit for drag and full load
-				return new ResponseDryRun {
-					Source = this,
-					GearboxPowerRequest = outTorque * avgOutAngularVelocity,
-					DeltaDragLoad = outTorque * avgOutAngularVelocity,
-					DeltaFullLoad = outTorque * avgOutAngularVelocity,
-				};
-			}
-
-			if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) &&
-				!outAngularVelocity.IsEqual(0)) {
-				return new ResponseOverload {
-					Source = this,
-					Delta = outTorque * avgOutAngularVelocity,
-					GearboxPowerRequest = outTorque * avgOutAngularVelocity
-				};
-			}
-
-			if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
-				return new ResponseUnderload {
-					Source = this,
-					Delta = outTorque * avgOutAngularVelocity,
-					GearboxPowerRequest = outTorque * avgOutAngularVelocity
-				};
-			}
-
-
-			//var motoringSpeed = DataBus.EngineIdleSpeed;
-			//var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
-			//if (!(disengagedResponse is ResponseSuccess)) {
-			//	motoringSpeed = DataBus.EngineSpeed;
-			//	if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) {
-			//		var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true);
-			//		try {
-			//			motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad,
-			//				Constants.SimulationSettings.EngineIdlingSearchInterval,
-			//				getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
-			//				evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true),
-			//				criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value());
-			//		} catch (VectoException) {
-			//			Log.Warn("CycleGearbox could not find motoring speed for disengaged state.");
-			//		}
-			//		motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed);
-			//	}
-			//	disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed);
-			//}
-			IResponse disengagedResponse;
-			if (GearboxType.AutomaticTransmission()) {
-				disengagedResponse = EngineIdleRequest(absTime, dt);
-			} else {
-				disengagedResponse = NextGear.Gear > 0
-					? NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(),
-						outAngularVelocity * ModelData.Gears[NextGear.Gear].Ratio)
-					: EngineIdleRequest(absTime, dt);
-			}
-			if (TorqueConverter != null) {
-				if (DataBus.VehicleStopped) {
-					TorqueConverter.Locked(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, CurrentState.InTorque,
-						outAngularVelocity);
-				} else {
-					TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed, CurrentState.InTorque,
-						disengagedResponse.EngineSpeed);
-				}
-			}
-			disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
-			CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity);
-			CurrentState.Gear = Gear;
-
-			return disengagedResponse;
-		}
-
-		private IResponse EngineIdleRequest(Second absTime, Second dt)
-		{
-			var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
-			if (disengagedResponse is ResponseSuccess) {
-				return disengagedResponse;
-			}
-			var motoringSpeed = DataBus.EngineSpeed;
-			if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) {
-				var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true);
-				try {
-					motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad,
-						Constants.SimulationSettings.EngineIdlingSearchInterval,
-						getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
-						evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true),
-						criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value());
-				} catch (VectoException) {
-					Log.Warn("CycleGearbox could not find motoring speed for disengaged state.");
-				}
-				motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed);
-			}
-			disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed);
-			return disengagedResponse;
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
-			var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
-			container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear;
-			container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed;
-			container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed;
-			container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed;
-			container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity +
-														CurrentState.OutAngularVelocity) / 2.0;
-			container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
-
-			if (ModelData.Type.AutomaticTransmission()) {
-				container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive;
-				container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLosses == null
-					? 0.SI<Watt>()
-					: CurrentState.PowershiftLosses * avgInAngularSpeed;
-			}
-			// torque converter fields are written by TorqueConverter (if present), called from Vehicle container 
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			if (Gear != 0) {
-				if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) {
-					Log.Warn(
-						"Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}",
-						Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque);
-					if (DataBus.ExecutionMode == ExecutionMode.Declaration) {
-						throw new VectoException(
-							"Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}",
-							Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque);
-					}
-				}
-			}
-			base.DoCommitSimulationStep();
-		}
-
-		#region ICluchInfo
-
-		public override GearInfo NextGear
-		{
-			get {
-				if (Disengaged == null) {
-					return new GearInfo(Gear, !TorqueConverterActive ?? true);
-				}
-				var future = DataBus.LookAhead(ModelData.TractionInterruption * 5);
-				var nextGear = 0u;
-				var torqueConverterLocked = false;
-				foreach (var entry in future) {
-					if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) {
-						// vehicle is stopped, no next gear, engine should go to idle
-						break;
-					}
-					if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) {
-						// vehicle is stopped, no next gear, engine should go to idle
-						break;
-					}
-					if (entry.Gear == 0) {
-						continue;
-					}
-					nextGear = entry.Gear;
-					torqueConverterLocked = !entry.TorqueConverterActive ?? false;
-					break;
-				}
-				return new GearInfo(nextGear, torqueConverterLocked);
-			}
-		}
-
-		public override Second TractionInterruption
-		{
-			get {
-				if (Disengaged == null) {
-					return ModelData.TractionInterruption;
-				}
-				var future = DataBus.LookAhead(ModelData.TractionInterruption * 5);
-				foreach (var entry in future) {
-					if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) {
-						// vehicle is stopped, no next gear, engine should go to idle
-						break;
-					}
-					if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) {
-						// vehicle is stopped, no next gear, engine should go to idle
-						break;
-					}
-					if (entry.Gear == 0) {
-						continue;
-					}
-					return entry.Time - Disengaged;
-				}
-				return ModelData.TractionInterruption;
-			}
-		}
-
-		public override bool ClutchClosed(Second absTime)
-		{
-			return (DataBus.DriverBehavior == DrivingBehavior.Braking
-				? DataBus.CycleData.LeftSample.Gear
-				: DataBus.CycleData.RightSample.Gear) != 0;
-		}
-
-		#endregion
-
-		public class CycleGearboxState : GearboxState
-		{
-			public bool TorqueConverterActive;
-			public WattSecond PowershiftLosses { get; set; }
-		}
-
-		public class CycleShiftStrategy : BaseShiftStrategy
-		{
-			public CycleShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {}
-
-			public override IGearbox Gearbox { get; set; }
-
-			public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-				NewtonMeter inTorque,
-				PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
-			{
-				return false;
-			}
-
-			public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
-			{
-				throw new System.NotImplementedException();
-			}
-
-			public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-			{
-				throw new System.NotImplementedException();
-			}
-
-			public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
-			{
-				throw new System.NotImplementedException();
-			}
-
-			public override GearInfo NextGear
-			{
-				get { throw new System.NotImplementedException(); }
-			}
-		}
-	}
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class CycleGearbox : AbstractGearbox<CycleGearbox.CycleGearboxState>
+	{
+		/// <summary>
+		/// True if gearbox is disengaged (no gear is set).
+		/// </summary>
+		protected internal Second Disengaged;
+
+		protected bool? TorqueConverterActive;
+
+		protected internal readonly TorqueConverter TorqueConverter;
+
+		public CycleGearbox(IVehicleContainer container, VectoRunData runData)
+			: base(container, runData)
+		{
+			if (!ModelData.Type.AutomaticTransmission()) {
+				return;
+			}
+			var strategy = new CycleShiftStrategy(ModelData, null);
+			TorqueConverter = new TorqueConverter(this, strategy, container, ModelData.TorqueConverterData, runData);
+			if (TorqueConverter == null) {
+				throw new VectoException("Torque Converter required for AT transmission!");
+			}
+		}
+
+		public override void Connect(ITnOutPort other)
+		{
+			base.Connect(other);
+			if (TorqueConverter != null) {
+				TorqueConverter.NextComponent = other;
+			}
+		}
+
+		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			var dt = Constants.SimulationSettings.TargetTimeInterval;
+
+			Gear = DataBus.CycleData.LeftSample.Gear;
+			TorqueConverterActive = DataBus.CycleData.LeftSample.TorqueConverterActive;
+
+			if (TorqueConverter != null && TorqueConverterActive == null) {
+				throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!");
+			}
+
+			var inAngularVelocity = DataBus.EngineIdleSpeed;
+			var inTorque = 0.SI<NewtonMeter>();
+			IResponse response;
+
+			if (Gear != 0) {
+				inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
+				var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
+				CurrentState.TorqueLossResult = inTorqueLossResult;
+				inTorque = outTorque / ModelData.Gears[Gear].Ratio + inTorqueLossResult.Value;
+
+				var torqueLossInertia = outAngularVelocity.IsEqual(0)
+					? 0.SI<NewtonMeter>()
+					: Formulas.InertiaPower(inAngularVelocity, PreviousState.InAngularVelocity, ModelData.Inertia, dt) /
+					inAngularVelocity;
+
+				inTorque += torqueLossInertia;
+
+				response = TorqueConverterActive != null && TorqueConverterActive.Value && TorqueConverter != null
+					? TorqueConverter.Initialize(inTorque, inAngularVelocity)
+					: NextComponent.Initialize(inTorque, inAngularVelocity);
+			} else {
+				response = NextComponent.Initialize(inTorque, inAngularVelocity);
+			}
+			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+			PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>();
+			PreviousState.Gear = Gear;
+
+			response.GearboxPowerRequest = inTorque * inAngularVelocity;
+			return response;
+		}
+
+		/// <summary>
+		/// Requests the Gearbox to deliver torque and angularVelocity
+		/// </summary>
+		/// <returns>
+		/// <list type="bullet">
+		/// <item><description>ResponseDryRun</description></item>
+		/// <item><description>ResponseOverload</description></item>
+		/// <item><description>ResponseGearshift</description></item>
+		/// </list>
+		/// </returns>
+		public override IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun = false)
+		{
+			Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
+			var gear = GetGearFromCycle();
+
+			TorqueConverterActive = DataBus.DriverBehavior == DrivingBehavior.Braking
+				? DataBus.CycleData.LeftSample.TorqueConverterActive
+				: DataBus.CycleData.RightSample.TorqueConverterActive;
+
+			if (TorqueConverter != null && TorqueConverterActive == null) {
+				throw new VectoSimulationException("Driving cycle does not contain information about TorqueConverter!");
+			}
+			if (gear != 0 && !ModelData.Gears.ContainsKey(gear)) {
+				throw new VectoSimulationException("Requested Gear {0} from driving cycle is not available", gear);
+			}
+
+			// mk 2016-11-30: added additional check for outAngularVelocity due to failing test: MeasuredSpeed_Gear_AT_PS_Run
+			// mq 2016-12-16: changed check to vehicle halted due to failing test: MeasuredSpeed_Gear_AT_*
+			var retVal = gear == 0 || DataBus.DriverBehavior == DrivingBehavior.Halted
+				//|| (outAngularVelocity.IsSmallerOrEqual(0, 1) && outTorque.IsSmallerOrEqual(0, 1))
+				? RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun)
+				: RequestEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+
+			retVal.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2;
+			return retVal;
+		}
+
+		private uint GetGearFromCycle()
+		{
+			return DataBus.DriverBehavior == DrivingBehavior.Braking
+				? DataBus.CycleData.LeftSample.Gear
+				: DataBus.CycleData.RightSample.Gear;
+		}
+
+		/// <summary>
+		/// Handles requests when a gear is engaged
+		/// </summary>
+		/// <param name="absTime"></param>
+		/// <param name="dt"></param>
+		/// <param name="outTorque"></param>
+		/// <param name="outAngularVelocity"></param>
+		/// <param name="dryRun"></param>
+		/// <returns></returns>
+		private IResponse RequestEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun)
+		{
+			Disengaged = null;
+
+			Gear = GetGearFromCycle();
+
+			var torqueConverterLocked = TorqueConverterActive == null || !TorqueConverterActive.Value;
+
+			var effectiveRatio = ModelData.Gears[Gear].Ratio;
+			var effectiveLossMap = ModelData.Gears[Gear].LossMap;
+			if (!torqueConverterLocked) {
+				effectiveRatio = ModelData.Gears[Gear].TorqueConverterRatio;
+				effectiveLossMap = ModelData.Gears[Gear].TorqueConverterGearLossMap;
+			}
+
+			CheckModelData(effectiveLossMap, effectiveRatio, torqueConverterLocked);
+
+			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			var inTorqueLossResult = effectiveLossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
+			CurrentState.TorqueLossResult = inTorqueLossResult;
+			var inTorque = outTorque / effectiveRatio + inTorqueLossResult.Value;
+			CurrentState.TorqueLossResult = inTorqueLossResult;
+			var inAngularVelocity = outAngularVelocity * effectiveRatio;
+
+			CurrentState.InertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
+				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
+				avgOutAngularVelocity
+				: 0.SI<NewtonMeter>();
+			inTorque += CurrentState.InertiaTorqueLossOut / effectiveRatio;
+			if (Gear != PreviousState.Gear &&
+				ConsiderShiftLosses(new GearInfo(Gear, torqueConverterLocked), outTorque)) {
+				CurrentState.PowershiftLosses = ComputeShiftLosses(outTorque, outAngularVelocity);
+			}
+			if (CurrentState.PowershiftLosses != null) {
+				var averageEngineSpeed = (DataBus.EngineSpeed + outAngularVelocity * ModelData.Gears[Gear].Ratio) / 2;
+				inTorque += CurrentState.PowershiftLosses / dt / averageEngineSpeed;
+			}
+			if (dryRun) {
+				var dryRunResponse = HandleDryRunRequest(absTime, dt, torqueConverterLocked, inTorque, inAngularVelocity);
+				dryRunResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
+				return dryRunResponse;
+			}
+
+			CurrentState.TransmissionTorqueLoss = inTorque * effectiveRatio - outTorque;
+
+			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+			CurrentState.Gear = Gear;
+			// end critical section
+
+			if (TorqueConverter != null && !torqueConverterLocked) {
+				CurrentState.TorqueConverterActive = true;
+				return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity);
+			}
+			// mk 2016-12-13
+			//if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+			//	Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear,
+			//		DataBus.VehicleSpeed);
+			//	Gear = 0;
+			//	return RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+			//}
+			if (TorqueConverter != null) {
+				TorqueConverter.Locked(CurrentState.InTorque, CurrentState.InAngularVelocity, CurrentState.InTorque,
+					CurrentState.InAngularVelocity);
+			}
+			var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity);
+			response.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
+			return response;
+		}
+
+		private void CheckModelData(TransmissionLossMap effectiveLossMap, double effectiveRatio, bool torqueConverterLocked)
+		{
+			if (effectiveLossMap == null || double.IsNaN(effectiveRatio)) {
+				throw new VectoSimulationException("Ratio or loss-map for gear {0}{1} invalid. Please check input data", Gear,
+					torqueConverterLocked ? "L" : "C");
+			}
+			if (!torqueConverterLocked && !ModelData.Gears[Gear].HasTorqueConverter) {
+				throw new VectoSimulationException("Torque converter requested by cycle for gear without torque converter!");
+			}
+		}
+
+		private IResponse HandleDryRunRequest(Second absTime, Second dt, bool torqueConverterLocked, NewtonMeter inTorque,
+			PerSecond inAngularVelocity)
+		{
+			if (TorqueConverter != null && !torqueConverterLocked) {
+				return TorqueConverter.Request(absTime, dt, inTorque, inAngularVelocity, true);
+			}
+			// mk 2016-12-13
+			//if (outTorque.IsSmaller(0) && inAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+			//	//Log.Warn("engine speed would fall below idle speed - disengage! gear from cycle: {0}, vehicle speed: {1}", Gear,
+			//	//	DataBus.VehicleSpeed);
+			//	Gear = 0;
+			//	return RequestDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+			//}
+			return NextComponent.Request(absTime, dt, inTorque, inAngularVelocity, true);
+		}
+
+		/// <summary>
+		/// Handles Requests when no gear is disengaged
+		/// </summary>
+		/// <param name="absTime"></param>
+		/// <param name="dt"></param>
+		/// <param name="outTorque"></param>
+		/// <param name="outAngularVelocity"></param>
+		/// <param name="dryRun"></param>
+		/// <returns></returns>
+		private IResponse RequestDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun)
+		{
+			if (Disengaged == null) {
+				Disengaged = absTime;
+			}
+
+			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			if (dryRun) {
+				// if gearbox is disengaged the 0-line is the limit for drag and full load
+				return new ResponseDryRun {
+					Source = this,
+					GearboxPowerRequest = outTorque * avgOutAngularVelocity,
+					DeltaDragLoad = outTorque * avgOutAngularVelocity,
+					DeltaFullLoad = outTorque * avgOutAngularVelocity,
+				};
+			}
+
+			if ((outTorque * avgOutAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance) &&
+				!outAngularVelocity.IsEqual(0)) {
+				return new ResponseOverload {
+					Source = this,
+					Delta = outTorque * avgOutAngularVelocity,
+					GearboxPowerRequest = outTorque * avgOutAngularVelocity
+				};
+			}
+
+			if ((outTorque * avgOutAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
+				return new ResponseUnderload {
+					Source = this,
+					Delta = outTorque * avgOutAngularVelocity,
+					GearboxPowerRequest = outTorque * avgOutAngularVelocity
+				};
+			}
+
+
+			//var motoringSpeed = DataBus.EngineIdleSpeed;
+			//var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
+			//if (!(disengagedResponse is ResponseSuccess)) {
+			//	motoringSpeed = DataBus.EngineSpeed;
+			//	if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) {
+			//		var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true);
+			//		try {
+			//			motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad,
+			//				Constants.SimulationSettings.EngineIdlingSearchInterval,
+			//				getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
+			//				evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true),
+			//				criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value());
+			//		} catch (VectoException) {
+			//			Log.Warn("CycleGearbox could not find motoring speed for disengaged state.");
+			//		}
+			//		motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed);
+			//	}
+			//	disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed);
+			//}
+			IResponse disengagedResponse;
+			if (GearboxType.AutomaticTransmission()) {
+				disengagedResponse = EngineIdleRequest(absTime, dt);
+			} else {
+				disengagedResponse = NextGear.Gear > 0
+					? NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(),
+						outAngularVelocity * ModelData.Gears[NextGear.Gear].Ratio)
+					: EngineIdleRequest(absTime, dt);
+			}
+			if (TorqueConverter != null) {
+				if (DataBus.VehicleStopped) {
+					TorqueConverter.Locked(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, CurrentState.InTorque,
+						outAngularVelocity);
+				} else {
+					TorqueConverter.Locked(CurrentState.InTorque, disengagedResponse.EngineSpeed, CurrentState.InTorque,
+						disengagedResponse.EngineSpeed);
+				}
+			}
+			disengagedResponse.GearboxPowerRequest = outTorque * avgOutAngularVelocity;
+			CurrentState.SetState(0.SI<NewtonMeter>(), disengagedResponse.EngineSpeed, 0.SI<NewtonMeter>(), outAngularVelocity);
+			CurrentState.Gear = Gear;
+
+			return disengagedResponse;
+		}
+
+		private IResponse EngineIdleRequest(Second absTime, Second dt)
+		{
+			var disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), DataBus.EngineIdleSpeed);
+			if (disengagedResponse is ResponseSuccess) {
+				return disengagedResponse;
+			}
+			var motoringSpeed = DataBus.EngineSpeed;
+			if (motoringSpeed.IsGreater(DataBus.EngineIdleSpeed)) {
+				var first = (ResponseDryRun)NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed, true);
+				try {
+					motoringSpeed = SearchAlgorithm.Search(motoringSpeed, first.DeltaDragLoad,
+						Constants.SimulationSettings.EngineIdlingSearchInterval,
+						getYValue: result => ((ResponseDryRun)result).DeltaDragLoad,
+						evaluateFunction: n => NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), n, true),
+						criterion: result => ((ResponseDryRun)result).DeltaDragLoad.Value());
+				} catch (VectoException) {
+					Log.Warn("CycleGearbox could not find motoring speed for disengaged state.");
+				}
+				motoringSpeed = motoringSpeed.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineSpeed);
+			}
+			disengagedResponse = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), motoringSpeed);
+			return disengagedResponse;
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
+			var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
+			container[ModalResultField.Gear] = Disengaged != null ? 0 : Gear;
+			container[ModalResultField.P_gbx_loss] = CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed;
+			container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed;
+			container[ModalResultField.P_gbx_in] = CurrentState.InTorque * avgInAngularSpeed;
+			container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity +
+														CurrentState.OutAngularVelocity) / 2.0;
+			container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
+
+			if (ModelData.Type.AutomaticTransmission()) {
+				container[ModalResultField.TC_Locked] = !CurrentState.TorqueConverterActive;
+				container[ModalResultField.P_gbx_shift_loss] = CurrentState.PowershiftLosses == null
+					? 0.SI<Watt>()
+					: CurrentState.PowershiftLosses * avgInAngularSpeed;
+			}
+			// torque converter fields are written by TorqueConverter (if present), called from Vehicle container 
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			if (Gear != 0) {
+				if (CurrentState.TorqueLossResult != null && CurrentState.TorqueLossResult.Extrapolated) {
+					Log.Warn(
+						"Gear {0} LossMap data was extrapolated: range for loss map is not sufficient: n:{1}, torque:{2}",
+						Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque);
+					if (DataBus.ExecutionMode == ExecutionMode.Declaration) {
+						throw new VectoException(
+							"Gear {0} LossMap data was extrapolated in Declaration Mode: range for loss map is not sufficient: n:{1}, torque:{2}",
+							Gear, CurrentState.OutAngularVelocity.ConvertTo().Rounds.Per.Minute, CurrentState.OutTorque);
+					}
+				}
+			}
+			base.DoCommitSimulationStep();
+		}
+
+		#region ICluchInfo
+
+		public override GearInfo NextGear
+		{
+			get
+			{
+				if (Disengaged == null) {
+					return new GearInfo(Gear, !TorqueConverterActive ?? true);
+				}
+				var future = DataBus.LookAhead(ModelData.TractionInterruption * 5);
+				var nextGear = 0u;
+				var torqueConverterLocked = false;
+				foreach (var entry in future) {
+					if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) {
+						// vehicle is stopped, no next gear, engine should go to idle
+						break;
+					}
+					if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) {
+						// vehicle is stopped, no next gear, engine should go to idle
+						break;
+					}
+					if (entry.Gear == 0) {
+						continue;
+					}
+					nextGear = entry.Gear;
+					torqueConverterLocked = !entry.TorqueConverterActive ?? false;
+					break;
+				}
+				return new GearInfo(nextGear, torqueConverterLocked);
+			}
+		}
+
+		public override Second TractionInterruption
+		{
+			get
+			{
+				if (Disengaged == null) {
+					return ModelData.TractionInterruption;
+				}
+				var future = DataBus.LookAhead(ModelData.TractionInterruption * 5);
+				foreach (var entry in future) {
+					if (entry.VehicleTargetSpeed != null && entry.VehicleTargetSpeed.IsEqual(0)) {
+						// vehicle is stopped, no next gear, engine should go to idle
+						break;
+					}
+					if (entry.WheelAngularVelocity != null && entry.WheelAngularVelocity.IsEqual(0)) {
+						// vehicle is stopped, no next gear, engine should go to idle
+						break;
+					}
+					if (entry.Gear == 0) {
+						continue;
+					}
+					return entry.Time - Disengaged;
+				}
+				return ModelData.TractionInterruption;
+			}
+		}
+
+		public override bool ClutchClosed(Second absTime)
+		{
+			return (DataBus.DriverBehavior == DrivingBehavior.Braking
+				? DataBus.CycleData.LeftSample.Gear
+				: DataBus.CycleData.RightSample.Gear) != 0;
+		}
+
+		#endregion
+
+		public class CycleGearboxState : GearboxState
+		{
+			public bool TorqueConverterActive;
+			public WattSecond PowershiftLosses { get; set; }
+		}
+
+		public class CycleShiftStrategy : BaseShiftStrategy
+		{
+			public CycleShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {}
+
+			public override IGearbox Gearbox { get; set; }
+
+			public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+				NewtonMeter inTorque,
+				PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+			{
+				return false;
+			}
+
+			public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
+			{
+				throw new System.NotImplementedException();
+			}
+
+			public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+			{
+				throw new System.NotImplementedException();
+			}
+
+			public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+			{
+				throw new System.NotImplementedException();
+			}
+
+			public override GearInfo NextGear
+			{
+				get { throw new System.NotImplementedException(); }
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
index 485e4be47eed6f39d59f07d33d94fb529f1ed29c..ef9a330dd311e476ccfb5f151d7e5331f3416a22 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DefaultDriverStrategy.cs
@@ -33,6 +33,7 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Configuration;
@@ -130,42 +131,52 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				}
 			} else {
 				// update action distance for current 'next action'
-				if (Driver.DataBus.VehicleSpeed > NextDrivingAction.NextTargetSpeed) {
-					var brakingDistance = Driver.ComputeDecelerationDistance(NextDrivingAction.NextTargetSpeed) + BrakingSafetyMargin;
-					switch (NextDrivingAction.Action) {
-						case DrivingBehavior.Coasting:
-							//var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.NextTargetSpeed);
-							var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.CycleEntry);
-							NextDrivingAction.CoastingStartDistance = NextDrivingAction.TriggerDistance - coastingDistance;
-							NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance;
-							break;
-						case DrivingBehavior.Braking:
-							NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance;
-							NextDrivingAction.CoastingStartDistance = double.MaxValue.SI<Meter>();
-							break;
-						default:
-							throw new ArgumentOutOfRangeException();
-					}
-				}
+				UpdateDistancesForCurrentNextAction();
 
-				if (nextAction != null) {
-					if (nextAction.HasEqualTrigger(NextDrivingAction)) {
-						// if the action changes and the vehicle has not yet exceeded the action distance => update the action
-						// otherwise do nothing, NextDrivingAction's action distance has already been updated
-						if (nextAction.Action != NextDrivingAction.Action && nextAction.ActionDistance > currentDistance) {
-							NextDrivingAction = nextAction;
-						}
-					} else {
-						// hmm, we've got a new action that is closer to what we got before?
-						if (nextAction.ActionDistance < NextDrivingAction.ActionDistance) {
-							NextDrivingAction = nextAction;
-						}
+				SetNextDrivingAction(currentDistance, nextAction);
+			}
+			Log.Debug("Next Driving Action: {0}", NextDrivingAction);
+		}
+
+		private void SetNextDrivingAction(Meter currentDistance, DrivingBehaviorEntry nextAction)
+		{
+			if (nextAction != null) {
+				if (nextAction.HasEqualTrigger(NextDrivingAction)) {
+					// if the action changes and the vehicle has not yet exceeded the action distance => update the action
+					// otherwise do nothing, NextDrivingAction's action distance has already been updated
+					if (nextAction.Action != NextDrivingAction.Action && nextAction.ActionDistance > currentDistance) {
+						NextDrivingAction = nextAction;
 					}
 				} else {
-					NextDrivingAction = null;
+					// hmm, we've got a new action that is closer to what we got before?
+					if (nextAction.ActionDistance < NextDrivingAction.ActionDistance) {
+						NextDrivingAction = nextAction;
+					}
+				}
+			} else {
+				NextDrivingAction = null;
+			}
+		}
+
+		private void UpdateDistancesForCurrentNextAction()
+		{
+			if (Driver.DataBus.VehicleSpeed > NextDrivingAction.NextTargetSpeed) {
+				var brakingDistance = Driver.ComputeDecelerationDistance(NextDrivingAction.NextTargetSpeed) + BrakingSafetyMargin;
+				switch (NextDrivingAction.Action) {
+					case DrivingBehavior.Coasting:
+						//var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.NextTargetSpeed);
+						var coastingDistance = ComputeCoastingDistance(Driver.DataBus.VehicleSpeed, NextDrivingAction.CycleEntry);
+						NextDrivingAction.CoastingStartDistance = NextDrivingAction.TriggerDistance - coastingDistance;
+						NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance;
+						break;
+					case DrivingBehavior.Braking:
+						NextDrivingAction.BrakingStartDistance = NextDrivingAction.TriggerDistance - brakingDistance;
+						NextDrivingAction.CoastingStartDistance = double.MaxValue.SI<Meter>();
+						break;
+					default:
+						throw new ArgumentOutOfRangeException();
 				}
 			}
-			Log.Debug("Next Driving Action: {0}", NextDrivingAction);
 		}
 
 		protected internal DrivingBehaviorEntry GetNextDrivingAction(Meter ds)
@@ -184,51 +195,58 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				var nextTargetSpeed = OverspeedAllowed(entry.VehicleTargetSpeed)
 					? entry.VehicleTargetSpeed + Driver.DriverData.OverSpeedEcoRoll.OverSpeed
 					: entry.VehicleTargetSpeed;
-				if (nextTargetSpeed < currentSpeed) {
-					var action = DrivingBehavior.Braking;
-					var coastingDistance = ComputeCoastingDistance(currentSpeed, entry);
-					var brakingDistance = Driver.ComputeDecelerationDistance(nextTargetSpeed) + BrakingSafetyMargin;
-
-					if (!Driver.DriverData.LookAheadCoasting.Enabled || coastingDistance < 0) {
-						Log.Debug(
-							"adding 'Braking' starting at distance {0}. brakingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}",
-							entry.Distance - brakingDistance, brakingDistance, entry.Distance, nextTargetSpeed);
-						coastingDistance = brakingDistance;
-					} else {
-						//var coastingDistance = ComputeCoastingDistance(currentSpeed, nextTargetSpeed);
-						if (currentSpeed > Driver.DriverData.LookAheadCoasting.MinSpeed) {
-							action = DrivingBehavior.Coasting;
-
-							Log.Debug(
-								"adding 'Coasting' starting at distance {0}. coastingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}",
-								entry.Distance - coastingDistance, coastingDistance, entry.Distance, nextTargetSpeed);
-						} else {
-							coastingDistance = -1.SI<Meter>();
-						}
-					}
-					nextActions.Add(
-						new DrivingBehaviorEntry {
-							Action = action,
-							CoastingStartDistance = entry.Distance - coastingDistance,
-							BrakingStartDistance = entry.Distance - brakingDistance,
-							TriggerDistance = entry.Distance,
-							NextTargetSpeed = nextTargetSpeed,
-							CycleEntry = entry,
-						});
+				if (nextTargetSpeed >= currentSpeed) {
+					// acceleration is not relevant
+					continue;
 				}
+				nextActions.Add(GetDrivingBehaviorEntry(nextTargetSpeed, currentSpeed, entry));
 			}
 			if (!nextActions.Any()) {
 				return null;
 			}
 			var nextBrakingAction = nextActions.OrderBy(x => x.BrakingStartDistance).First();
 			var nextCoastingAction = nextActions.OrderBy(x => x.CoastingStartDistance).First();
-			if (nextBrakingAction.TriggerDistance.IsEqual(nextCoastingAction.TriggerDistance)) {
-				// its the same trigger, use it
-				return nextCoastingAction;
-			}
+
+			return nextBrakingAction.TriggerDistance.IsEqual(nextCoastingAction.TriggerDistance)
+				? nextCoastingAction
+				: nextBrakingAction;
 
 			// MQ: 27.5.2016 remark: one could set the coasting distance to the closest coasting distance as found above to start coasting a little bit earlier.
-			return nextBrakingAction;
+		}
+
+		private DrivingBehaviorEntry GetDrivingBehaviorEntry(MeterPerSecond nextTargetSpeed, MeterPerSecond currentSpeed,
+			DrivingCycleData.DrivingCycleEntry entry)
+		{
+			var action = DrivingBehavior.Braking;
+
+			var brakingDistance = Driver.ComputeDecelerationDistance(nextTargetSpeed) + BrakingSafetyMargin;
+			var coastingDistance = ComputeCoastingDistance(currentSpeed, entry);
+			if (!Driver.DriverData.LookAheadCoasting.Enabled || coastingDistance < 0) {
+				Log.Debug(
+					"adding 'Braking' starting at distance {0}. brakingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}",
+					entry.Distance - brakingDistance, brakingDistance, entry.Distance, nextTargetSpeed);
+				coastingDistance = brakingDistance;
+			} else {
+				//var coastingDistance = ComputeCoastingDistance(currentSpeed, nextTargetSpeed);
+				if (currentSpeed > Driver.DriverData.LookAheadCoasting.MinSpeed) {
+					action = DrivingBehavior.Coasting;
+
+					Log.Debug(
+						"adding 'Coasting' starting at distance {0}. coastingDistance: {1}, triggerDistance: {2}, nextTargetSpeed: {3}",
+						entry.Distance - coastingDistance, coastingDistance, entry.Distance, nextTargetSpeed);
+				} else {
+					coastingDistance = -1.SI<Meter>();
+				}
+			}
+			var nextEntry = new DrivingBehaviorEntry {
+				Action = action,
+				CoastingStartDistance = entry.Distance - coastingDistance,
+				BrakingStartDistance = entry.Distance - brakingDistance,
+				TriggerDistance = entry.Distance,
+				NextTargetSpeed = nextTargetSpeed,
+				CycleEntry = entry,
+			};
+			return nextEntry;
 		}
 
 		protected internal virtual Meter ComputeCoastingDistance(MeterPerSecond vehicleSpeed,
@@ -383,96 +401,122 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				velocity += DriverData.OverSpeedEcoRoll.OverSpeed;
 			}
 			if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
-				// drive along
-				IResponse first;
-				if (DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed) &&
-					DataBus.VehicleSpeed.IsEqual(targetVelocity)) {
-					first = Driver.DrivingActionCoast(absTime, ds, velocity, gradient);
-					debug.Add(new { action = "Coast", first });
-					if (first is ResponseSuccess && first.Acceleration < 0) {
-						first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
-						debug.Add(new { action = "Coast:(Success & Acc<0) -> Accelerate", first });
-					}
-				} else {
-					first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
-					debug.Add(new { action = "Accelerate", first });
-				}
+				return HandleRequestEngaged(absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocity, debug);
+			} else {
+				return HandleRequestDisengaged(absTime, ds, gradient, velocity, debug);
+			}
+		}
 
-				var second = first;
-				first.Switch().
-					Case<ResponseUnderload>(r => {
-						if (DataBus.VehicleSpeed.IsGreater(0) && DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed)) {
-							second = Driver.DrivingActionCoast(absTime, ds, velocity, gradient);
-							debug.Add(new { action = "first:(Underload & Overspeed)-> Coast", second });
-							if (second is ResponseUnderload || second is ResponseSpeedLimitExceeded) {
-								second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
-								debug.Add(new {
-									action = "second:(Underload|SpeedLimitExceeded) -> Brake",
-									second
-								});
-							}
-							if (second is ResponseEngineSpeedTooHigh) {
-								second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, second);
-								debug.Add(new {
-									action = "second:(EngineSpeedTooHigh|SpeedLimitExceeded) -> Brake with reduced acceleration",
-									second
-								});
-							}
-						} else {
-							second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
-							debug.Add(new { action = "first:(Underload & !Overspeed) -> Brake", second });
-						}
-					});
-
-				var third = second;
-
-				second.Switch().
-					Case<ResponseGearShift>(r => {
-						third = Driver.DrivingActionRoll(absTime, ds, velocity, gradient);
-						debug.Add(new { action = "second: GearShift -> Roll", third });
-						third.Switch().
-							Case<ResponseUnderload>(() => {
-								// overload may happen if driver limits acceleration when rolling downhill
-								third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
-								debug.Add(new { action = "third:Underload -> Brake", third });
-							}).
-							Case<ResponseSpeedLimitExceeded>(() => {
-								third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
-								debug.Add(new { action = "third:SpeedLimitExceeded -> Brake", third });
-							});
-					}).
-					Case<ResponseOverload>(r => {
-						third = Driver.DrivingActionCoast(absTime, ds, velocity, gradient);
-						debug.Add(new { action = "second:Overload -> Coast", third });
-					});
+		private IResponse HandleRequestDisengaged(Second absTime, Meter ds, Radian gradient, MeterPerSecond velocity,
+			DebugData debug)
+		{
+			if (DataBus.VehicleSpeed.IsSmallerOrEqual(0.SI<MeterPerSecond>())) {
+				// the clutch is disengaged, and the vehicle stopped - we can't perform a roll action. wait for the clutch to be engaged
+				// todo mk 2016-08-23: is this still needed?
+				var remainingShiftTime = Constants.SimulationSettings.TargetTimeInterval;
+				while (!DataBus.ClutchClosed(absTime + remainingShiftTime)) {
+					remainingShiftTime += Constants.SimulationSettings.TargetTimeInterval;
+				}
+				return new ResponseFailTimeInterval {
+					Source = this,
+					DeltaT = remainingShiftTime,
+				};
+			}
+			var response = Driver.DrivingActionRoll(absTime, ds, velocity, gradient);
+			debug.Add(new { action = "ClutchOpen -> Roll", response });
+			response.Switch().
+				Case<ResponseUnderload>(r => {
+					response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, r);
+					debug.Add(new { action = "Roll:Underload -> Brake", response });
+				})
+				.Case<ResponseSpeedLimitExceeded>(() => {
+					response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
+					debug.Add(new { action = "Roll:SpeedLimitExceeded -> Brake", response });
+				});
+			return response;
+		}
 
-				return third;
-			} else {
-				if (DataBus.VehicleSpeed.IsSmallerOrEqual(0.SI<MeterPerSecond>())) {
-					// the clutch is disengaged, and the vehicle stopped - we can't perform a roll action. wait for the clutch to be engaged
-					// todo mk 2016-08-23: is this still needed?
-					var remainingShiftTime = Constants.SimulationSettings.TargetTimeInterval;
-					while (!DataBus.ClutchClosed(absTime + remainingShiftTime)) {
-						remainingShiftTime += Constants.SimulationSettings.TargetTimeInterval;
+		private IResponse HandleRequestEngaged(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient,
+			bool prohibitOverspeed, MeterPerSecond velocity, DebugData debug)
+		{
+			// drive along
+			var first = FirstAccelerateOrCoast(absTime, ds, targetVelocity, gradient, prohibitOverspeed, velocity, debug);
+
+			var second = first;
+			first.Switch().
+				Case<ResponseUnderload>(r => {
+					if (DataBus.VehicleSpeed.IsGreater(0) && DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed)) {
+						second = Driver.DrivingActionCoast(absTime, ds, velocity, gradient);
+						debug.Add(new { action = "first:(Underload & Overspeed)-> Coast", second });
+						second = HandleCoastAfterUnderloadWithOverspeed(absTime, ds, gradient, velocity, debug, second);
+					} else {
+						second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
+						debug.Add(new { action = "first:(Underload & !Overspeed) -> Brake", second });
 					}
-					return new ResponseFailTimeInterval {
-						Source = this,
-						DeltaT = remainingShiftTime,
-					};
+				});
+
+			var third = second;
+
+			second.Switch().
+				Case<ResponseGearShift>(r => {
+					third = Driver.DrivingActionRoll(absTime, ds, velocity, gradient);
+					debug.Add(new { action = "second: GearShift -> Roll", third });
+					third.Switch().
+						Case<ResponseUnderload>(() => {
+							// overload may happen if driver limits acceleration when rolling downhill
+							third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
+							debug.Add(new { action = "third:Underload -> Brake", third });
+						}).
+						Case<ResponseSpeedLimitExceeded>(() => {
+							third = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
+							debug.Add(new { action = "third:SpeedLimitExceeded -> Brake", third });
+						});
+				}).
+				Case<ResponseOverload>(r => {
+					third = Driver.DrivingActionCoast(absTime, ds, velocity, gradient);
+					debug.Add(new { action = "second:Overload -> Coast", third });
+				});
+
+			return third;
+		}
+
+		private IResponse HandleCoastAfterUnderloadWithOverspeed(Second absTime, Meter ds, Radian gradient,
+			MeterPerSecond velocity, DebugData debug, IResponse second)
+		{
+			if (second is ResponseUnderload || second is ResponseSpeedLimitExceeded) {
+				second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
+				debug.Add(new {
+					action = "second:(Underload|SpeedLimitExceeded) -> Brake",
+					second
+				});
+			}
+			if (second is ResponseEngineSpeedTooHigh) {
+				second = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, second);
+				debug.Add(new {
+					action = "second:(EngineSpeedTooHigh|SpeedLimitExceeded) -> Brake with reduced acceleration",
+					second
+				});
+			}
+			return second;
+		}
+
+		private IResponse FirstAccelerateOrCoast(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient,
+			bool prohibitOverspeed, MeterPerSecond velocity, DebugData debug)
+		{
+			IResponse first;
+			if (DriverStrategy.OverspeedAllowed(targetVelocity, prohibitOverspeed) &&
+				DataBus.VehicleSpeed.IsEqual(targetVelocity)) {
+				first = Driver.DrivingActionCoast(absTime, ds, velocity, gradient);
+				debug.Add(new { action = "Coast", first });
+				if (first is ResponseSuccess && first.Acceleration < 0) {
+					first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
+					debug.Add(new { action = "Coast:(Success & Acc<0) -> Accelerate", first });
 				}
-				var response = Driver.DrivingActionRoll(absTime, ds, velocity, gradient);
-				debug.Add(new { action = "ClutchOpen -> Roll", response });
-				response.Switch().
-					Case<ResponseUnderload>(r => {
-						response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient, r);
-						debug.Add(new { action = "Roll:Underload -> Brake", response });
-					})
-					.Case<ResponseSpeedLimitExceeded>(() => {
-						response = Driver.DrivingActionBrake(absTime, ds, velocity, gradient);
-						debug.Add(new { action = "Roll:SpeedLimitExceeded -> Brake", response });
-					});
-				return response;
+			} else {
+				first = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
+				debug.Add(new { action = "Accelerate", first });
 			}
+			return first;
 		}
 
 		protected override IResponse CheckRequestDoesNotExceedNextAction(Second absTime, Meter ds,
@@ -536,7 +580,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected override IResponse DoHandleRequest(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient,
 			bool prohibitOverspeed = false)
 		{
-			IResponse response = null;
 			if (DataBus.VehicleSpeed <= DriverStrategy.BrakeTrigger.NextTargetSpeed) {
 				return HandleTargetspeedReached(absTime, ds, targetVelocity, gradient);
 			}
@@ -546,137 +589,218 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 								DefaultDriverStrategy.BrakingSafetyMargin;
 			DriverStrategy.BrakeTrigger.BrakingStartDistance = DriverStrategy.BrakeTrigger.TriggerDistance - brakingDistance;
 			if (Phase == BrakingPhase.Coast) {
-				var nextBrakeAction = DriverStrategy.GetNextDrivingAction(ds);
-				if (nextBrakeAction != null && !DriverStrategy.BrakeTrigger.TriggerDistance.IsEqual(nextBrakeAction.TriggerDistance) &&
-					nextBrakeAction.BrakingStartDistance.IsSmaller(DriverStrategy.BrakeTrigger.BrakingStartDistance)) {
-					DriverStrategy.BrakeTrigger = nextBrakeAction;
-					Log.Debug("setting brake trigger to new trigger: trigger distance: {0}, start braking @ {1}",
-						nextBrakeAction.TriggerDistance, nextBrakeAction.BrakingStartDistance);
-				}
-
-				Log.Debug("start braking @ {0}", DriverStrategy.BrakeTrigger.BrakingStartDistance);
-				var remainingDistanceToBrake = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance;
-				var estimatedTimeInterval = remainingDistanceToBrake / DataBus.VehicleSpeed;
-				if (estimatedTimeInterval.IsSmaller(Constants.SimulationSettings.LowerBoundTimeInterval) ||
-					currentDistance + Constants.SimulationSettings.DriverActionDistanceTolerance >
-					DriverStrategy.BrakeTrigger.BrakingStartDistance) {
-					Phase = BrakingPhase.Brake;
-					Log.Debug("Switching to BRAKE Phase. currentDistance: {0}", currentDistance);
-				} else {
-					if ((currentDistance + ds).IsGreater(DriverStrategy.BrakeTrigger.BrakingStartDistance)) {
-						return new ResponseDrivingCycleDistanceExceeded() {
-							//Source = this,
-							MaxDistance = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance
-						};
-					}
-				}
-				if (DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast) {
-					Phase = BrakingPhase.Brake;
-					Log.Debug("Switching to BRAKE Phase. currentDistance: {0}  v: {1}", currentDistance,
-						DataBus.VehicleSpeed);
+				var resp = CheckSwitchingToBraking(ds, currentDistance);
+				if (resp != null) {
+					return resp;
 				}
 			}
 			switch (Phase) {
 				case BrakingPhase.Coast:
-					Driver.DriverBehavior = DrivingBehavior.Coasting;
+					return DoCoast(absTime, ds, targetVelocity, gradient, currentDistance);
+				case BrakingPhase.Brake:
+					return DoBrake(absTime, ds, targetVelocity, gradient, brakingDistance, currentDistance);
+				default:
+					throw new VectoException("Invalid Phase in DriverModeBrake");
+			}
+		}
+
+		private IResponse DoBrake(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient,
+			Meter brakingDistance, Meter currentDistance)
+		{
+			IResponse response;
+			Log.Debug("Phase: BRAKE. breaking distance: {0} start braking @ {1}", brakingDistance,
+				DriverStrategy.BrakeTrigger.BrakingStartDistance);
+			if (DriverStrategy.BrakeTrigger.BrakingStartDistance.IsSmaller(currentDistance,
+				Constants.SimulationSettings.DriverActionDistanceTolerance / 2)) {
+				Log.Info("Expected Braking Deceleration could not be reached! {0}",
+					DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance);
+			}
+			var targetDistance = DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast
+				? DriverStrategy.BrakeTrigger.TriggerDistance
+				: null;
+			if (targetDistance == null && DriverStrategy.BrakeTrigger.NextTargetSpeed.IsEqual(0.SI<MeterPerSecond>())) {
+				targetDistance = DriverStrategy.BrakeTrigger.TriggerDistance - DefaultDriverStrategy.BrakingSafetyMargin;
+			}
+			Driver.DriverBehavior = DrivingBehavior.Braking;
+			response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+				gradient, targetDistance: targetDistance);
+			response.Switch().
+				Case<ResponseOverload>(r => {
+					Log.Info(
+						"Brake -> Got OverloadResponse during brake action - desired deceleration could not be reached! response: {0}",
+						r);
+					if (!DataBus.ClutchClosed(absTime)) {
+						Log.Info("Brake -> Overload -> Clutch is open - Trying roll action");
+						response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
+					} else {
+						Log.Info("Brake -> Overload -> Clutch is closed - Trying brake action again");
+						DataBus.BrakePower = 0.SI<Watt>();
+						response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient,
+							targetDistance: targetDistance);
+						response.Switch().
+							Case<ResponseOverload>(r1 => {
+								Log.Info("Brake -> Overload -> 2nd Brake -> Overload -> Trying accelerate action");
+								response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+								response.Switch().Case<ResponseGearShift>(
+									rs => {
+										Log.Info("Brake -> Overload -> 2nd Brake -> Accelerate -> Got GearShift response, performing roll action");
+										response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+									});
+							});
+					}
+				}).
+				Case<ResponseGearShift>(r => {
+					Log.Info("Brake -> Got GearShift response, performing roll action + brakes");
+					//response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+					DataBus.BrakePower = 0.SI<Watt>();
+					response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+						gradient, targetDistance: targetDistance);
+				});
+			return response;
+		}
+
+		private IResponse DoCoast(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient,
+			Meter currentDistance)
+		{
+			IResponse response;
+			Driver.DriverBehavior = DrivingBehavior.Coasting;
+			response = DataBus.ClutchClosed(absTime)
+				? Driver.DrivingActionCoast(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient)
+				: Driver.DrivingActionRoll(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient);
+			response.Switch().
+				Case<ResponseUnderload>(r => {
+					// coast would decelerate more than driver's max deceleration => issue brakes to decelerate with driver's max deceleration
+					response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+						gradient, r);
+					if ((DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance).IsSmallerOrEqual(
+						Constants.SimulationSettings.DriverActionDistanceTolerance)) {
+						Phase = BrakingPhase.Brake;
+					}
+				}).
+				Case<ResponseOverload>(r => {
+					// limiting deceleration while coast may result in an overload => issue brakes to decelerate with driver's max deceleration
 					response = DataBus.ClutchClosed(absTime)
-						? Driver.DrivingActionCoast(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient)
-						: Driver.DrivingActionRoll(absTime, ds, VectoMath.Max(targetVelocity, DataBus.VehicleSpeed), gradient);
+						? Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient)
+						: Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
+					//Phase = BrakingPhase.Brake;
+				}).
+				Case<ResponseDrivingCycleDistanceExceeded>(r => {
+					if (!ds.IsEqual(r.MaxDistance)) {
+						// distance has been reduced due to vehicle stop in coast/roll action => use brake action to get exactly to the stop-distance
+						// TODO what if no gear is enaged (and we need driveline power to get to the stop-distance?
+						response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+					}
+				}).
+				Case<ResponseGearShift>(r => {
+					response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
+				}).
+				Case<ResponseEngineSpeedTooHigh>(r => {
+					response = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r);
+				});
+			// handle the SpeedLimitExceeded Response separately in case it occurs in one of the requests in the second try
+			response.Switch().
+				Case<ResponseSpeedLimitExceeded>(() => {
+					response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
+						gradient);
+					if (response is ResponseOverload && !DataBus.ClutchClosed(absTime)) {
+						response = Driver.DrivingActionRoll(absTime, ds, DataBus.VehicleSpeed, gradient);
+					}
+				});
+			return response;
+		}
+
+		private IResponse CheckSwitchingToBraking(Meter ds, Meter currentDistance)
+		{
+			var nextBrakeAction = DriverStrategy.GetNextDrivingAction(ds);
+			if (nextBrakeAction != null && !DriverStrategy.BrakeTrigger.TriggerDistance.IsEqual(nextBrakeAction.TriggerDistance) &&
+				nextBrakeAction.BrakingStartDistance.IsSmaller(DriverStrategy.BrakeTrigger.BrakingStartDistance)) {
+				DriverStrategy.BrakeTrigger = nextBrakeAction;
+				Log.Debug("setting brake trigger to new trigger: trigger distance: {0}, start braking @ {1}",
+					nextBrakeAction.TriggerDistance, nextBrakeAction.BrakingStartDistance);
+			}
+
+			Log.Debug("start braking @ {0}", DriverStrategy.BrakeTrigger.BrakingStartDistance);
+			var remainingDistanceToBrake = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance;
+			var estimatedTimeInterval = remainingDistanceToBrake / DataBus.VehicleSpeed;
+			if (estimatedTimeInterval.IsSmaller(Constants.SimulationSettings.LowerBoundTimeInterval) ||
+				currentDistance + Constants.SimulationSettings.DriverActionDistanceTolerance >
+				DriverStrategy.BrakeTrigger.BrakingStartDistance) {
+				Phase = BrakingPhase.Brake;
+				Log.Debug("Switching to BRAKE Phase. currentDistance: {0}", currentDistance);
+			} else {
+				if ((currentDistance + ds).IsGreater(DriverStrategy.BrakeTrigger.BrakingStartDistance)) {
+					return new ResponseDrivingCycleDistanceExceeded() {
+						//Source = this,
+						MaxDistance = DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance
+					};
+				}
+			}
+			if (DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast) {
+				Phase = BrakingPhase.Brake;
+				Log.Debug("Switching to BRAKE Phase. currentDistance: {0}  v: {1}", currentDistance,
+					DataBus.VehicleSpeed);
+			}
+			return null;
+		}
+
+		private IResponse HandleTargetspeedReached(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
+		{
+			var response = TargetSpeedReachedDriveAlong(absTime, ds, targetVelocity, gradient);
+			//var i = 0;
+			//do {
+			response.Switch().
+				Case<ResponseGearShift>(() => {
+					response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
 					response.Switch().
 						Case<ResponseUnderload>(r => {
-							// coast would decelerate more than driver's max deceleration => issue brakes to decelerate with driver's max deceleration
+							// under-load may happen if driver limits acceleration when rolling downhill
 							response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
 								gradient, r);
-							if ((DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance).IsSmallerOrEqual(
-								Constants.SimulationSettings.DriverActionDistanceTolerance)) {
-								Phase = BrakingPhase.Brake;
-							}
-						}).
-						Case<ResponseOverload>(r => {
-							// limiting deceleration while coast may result in an overload => issue brakes to decelerate with driver's max deceleration
-							response = DataBus.ClutchClosed(absTime)
-								? Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient)
-								: Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
-							//Phase = BrakingPhase.Brake;
 						}).
-						Case<ResponseDrivingCycleDistanceExceeded>(r => {
-							if (!ds.IsEqual(r.MaxDistance)) {
-								// distance has been reduced due to vehicle stop in coast/roll action => use brake action to get exactly to the stop-distance
-								// TODO what if no gear is enaged (and we need driveline power to get to the stop-distance?
-								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-							}
-						}).
-						Case<ResponseGearShift>(r => { response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient); }).
-						Case<ResponseEngineSpeedTooHigh>(r => {
-							response = Driver.DrivingActionBrake(absTime, ds, targetVelocity, gradient, r);
-						});
-					// handle the SpeedLimitExceeded Response separately in case it occurs in one of the requests in the second try
-					response.Switch().
 						Case<ResponseSpeedLimitExceeded>(() => {
 							response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
 								gradient);
-							if (response is ResponseOverload && !DataBus.ClutchClosed(absTime)) {
-								response = Driver.DrivingActionRoll(absTime, ds, DataBus.VehicleSpeed, gradient);
-							}
 						});
-					break;
-				case BrakingPhase.Brake:
-
-					Log.Debug("Phase: BRAKE. breaking distance: {0} start braking @ {1}", brakingDistance,
-						DriverStrategy.BrakeTrigger.BrakingStartDistance);
-					if (DriverStrategy.BrakeTrigger.BrakingStartDistance.IsSmaller(currentDistance,
-						Constants.SimulationSettings.DriverActionDistanceTolerance / 2)) {
-						Log.Info("Expected Braking Deceleration could not be reached! {0}",
-							DriverStrategy.BrakeTrigger.BrakingStartDistance - currentDistance);
-					}
-					var targetDistance = DataBus.VehicleSpeed < Constants.SimulationSettings.MinVelocityForCoast
-						? DriverStrategy.BrakeTrigger.TriggerDistance
-						: null;
-					if (targetDistance == null && DriverStrategy.BrakeTrigger.NextTargetSpeed.IsEqual(0.SI<MeterPerSecond>())) {
-						targetDistance = DriverStrategy.BrakeTrigger.TriggerDistance - DefaultDriverStrategy.BrakingSafetyMargin;
-					}
-					Driver.DriverBehavior = DrivingBehavior.Braking;
-					response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-						gradient, targetDistance: targetDistance);
+				}).
+				Case<ResponseSpeedLimitExceeded>(() => {
+					response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
+						gradient);
+				}).
+				Case<ResponseUnderload>(r => {
+					//response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
+					//	gradient, r);
+					response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval,
+						gradient, r);
 					response.Switch().
-						Case<ResponseOverload>(r => {
-							Log.Info(
-								"Brake -> Got OverloadResponse during brake action - desired deceleration could not be reached! response: {0}",
-								r);
-							if (!DataBus.ClutchClosed(absTime)) {
-								Log.Info("Brake -> Overload -> Clutch is open - Trying roll action");
-								response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
-							} else {
-								Log.Info("Brake -> Overload -> Clutch is closed - Trying brake action again");
-								DataBus.BrakePower = 0.SI<Watt>();
-								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient,
-									targetDistance: targetDistance);
-								response.Switch().
-									Case<ResponseOverload>(r1 => {
-										Log.Info("Brake -> Overload -> 2nd Brake -> Overload -> Trying accelerate action");
-										response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-										response.Switch().Case<ResponseGearShift>(
-											rs => {
-												Log.Info("Brake -> Overload -> 2nd Brake -> Accelerate -> Got GearShift response, performing roll action");
-												response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-											});
-									});
-							}
-						}).
-						Case<ResponseGearShift>(r => {
-							Log.Info("Brake -> Got GearShift response, performing roll action + brakes");
-							//response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+						Case<ResponseGearShift>(() => {
 							DataBus.BrakePower = 0.SI<Watt>();
 							response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-								gradient, targetDistance: targetDistance);
+								gradient, r);
+						}).
+						Case<ResponseOverload>(() => {
+							DataBus.BrakePower = 0.SI<Watt>();
+							if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
+								if (DataBus.VehicleSpeed.IsGreater(0)) {
+									response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+								} else {
+									if (RetryDistanceExceeded) {
+										response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
+									} else {
+										RetryDistanceExceeded = true;
+										response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
+									}
+								}
+							} else {
+								response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
+							}
 						});
-					break;
-			}
-
+				});
+			//} while (!(response is ResponseSuccess) && i++ < 3);
 			return response;
 		}
 
-		private IResponse HandleTargetspeedReached(Second absTime, Meter ds, MeterPerSecond targetVelocity, Radian gradient)
+		private IResponse TargetSpeedReachedDriveAlong(Second absTime, Meter ds, MeterPerSecond targetVelocity,
+			Radian gradient)
 		{
 			IResponse response;
 			if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
@@ -687,62 +811,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 						response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
 					} else {
 						RetryDistanceExceeded = true;
-						return new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
+						response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
 					}
 				}
 			} else {
 				response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
 			}
-			var i = 0;
-			do {
-				response.Switch().
-					Case<ResponseGearShift>(() => {
-						response = Driver.DrivingActionRoll(absTime, ds, targetVelocity, gradient);
-						response.Switch().
-							Case<ResponseUnderload>(r => {
-								// under-load may happen if driver limits acceleration when rolling downhill
-								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-									gradient, r);
-							}).
-							Case<ResponseSpeedLimitExceeded>(() => {
-								response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
-									gradient);
-							});
-					}).
-					Case<ResponseSpeedLimitExceeded>(() => {
-						response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed,
-							gradient);
-					}).
-					Case<ResponseUnderload>(r => {
-						//response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-						//	gradient, r);
-						response = Driver.DrivingActionBrake(absTime, ds, DataBus.VehicleSpeed + r.Acceleration * r.SimulationInterval,
-							gradient, r);
-						response.Switch().
-							Case<ResponseGearShift>(() => {
-								DataBus.BrakePower = 0.SI<Watt>();
-								response = Driver.DrivingActionBrake(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed,
-									gradient, r);
-							}).
-							Case<ResponseOverload>(() => {
-								DataBus.BrakePower = 0.SI<Watt>();
-								if (DataBus.GearboxType.AutomaticTransmission() || DataBus.ClutchClosed(absTime)) {
-									if (DataBus.VehicleSpeed.IsGreater(0)) {
-										response = Driver.DrivingActionAccelerate(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-									} else {
-										if (RetryDistanceExceeded) {
-											response = Driver.DrivingActionAccelerate(absTime, ds, targetVelocity, gradient);
-										} else {
-											RetryDistanceExceeded = true;
-											response = new ResponseDrivingCycleDistanceExceeded() { MaxDistance = ds / 2 };
-										}
-									}
-								} else {
-									response = Driver.DrivingActionRoll(absTime, ds, DriverStrategy.BrakeTrigger.NextTargetSpeed, gradient);
-								}
-							});
-					});
-			} while (!(response is ResponseSuccess) && i++ < 3); 
 			return response;
 		}
 
@@ -790,7 +864,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public Meter ActionDistance
 		{
-			get {
+			get
+			{
 				return VectoMath.Min(CoastingStartDistance ?? double.MaxValue.SI<Meter>(),
 					BrakingStartDistance ?? double.MaxValue.SI<Meter>());
 			}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
index 207f17c59015785251f2b258189b341a30a84534..4abc435139bc42eba92e5b12bdc463a4610a1771 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
@@ -29,525 +29,539 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	/// <summary>
-	///     Class representing one Distance Based Driving Cycle
-	/// </summary>
-	public sealed class DistanceBasedDrivingCycle : StatefulProviderComponent
-		<DistanceBasedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDrivingCycleInPort, IDrivingCycleOutPort>,
-		IDrivingCycle, ISimulationOutPort, IDrivingCycleInPort, IDisposable
-	{
-		private const double LookaheadTimeSafetyMargin = 1.5;
-		internal readonly IDrivingCycleData Data;
-		internal readonly DrivingCycleEnumerator CycleIntervalIterator;
-		private bool _intervalProlonged;
-		internal IdleControllerSwitcher IdleController;
-
-		private DrivingCycleData.DrivingCycleEntry Left
-		{
-			get { return CycleIntervalIterator.LeftSample; }
-		}
-
-		private DrivingCycleData.DrivingCycleEntry Right
-		{
-			get { return CycleIntervalIterator.RightSample; }
-		}
-
-		public DistanceBasedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container)
-		{
-			Data = cycle;
-			CycleIntervalIterator = new DrivingCycleEnumerator(Data);
-			CycleStartDistance = Data.Entries.Count > 0 ? Data.Entries.First().Distance : 0.SI<Meter>();
-
-			var first = Data.Entries.First();
-			PreviousState = new DrivingCycleState {
-				AbsTime = 0.SI<Second>(),
-				WaitTime = 0.SI<Second>(),
-				Distance = first.Distance,
-				Altitude = first.Altitude,
-			};
-			CurrentState = PreviousState.Clone();
-		}
-
-		public IResponse Initialize()
-		{
-			if (Left.VehicleTargetSpeed.IsEqual(0)) {
-				var retVal = NextComponent.Initialize(DataBus.StartSpeed,
-					Left.RoadGradient, DataBus.StartAcceleration);
-				if (!(retVal is ResponseSuccess)) {
-					throw new UnexpectedResponseException("DistanceBasedDrivingCycle.Initialize: Couldn't find start gear.", retVal);
-				}
-			}
-
-			return NextComponent.Initialize(Left.VehicleTargetSpeed,
-				Left.RoadGradient);
-		}
-
-		public IResponse Request(Second absTime, Second dt)
-		{
-			throw new NotImplementedException("Distance Based Driving Cycle does not support time requests.");
-		}
-
-		public IResponse Request(Second absTime, Meter ds)
-		{
-			if (Left.Distance.IsEqual(PreviousState.Distance.Value())) {
-				// we are exactly on an entry in the cycle.
-				var stopTime = Left.PTOActive && IdleController != null
-					? Left.StoppingTime + IdleController.Duration
-					: Left.StoppingTime;
-
-				if (stopTime.IsGreater(0) && PreviousState.WaitTime.IsSmaller(stopTime)) {
-					// stop for certain time unless we've already waited long enough ...
-
-					// we are stopping: ensure that velocity is 0.
-					if (!Left.VehicleTargetSpeed.IsEqual(0)) {
-						Log.Warn("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}",
-							Left.StoppingTime, Left.VehicleTargetSpeed);
-						throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!");
-					}
-					var dt = GetStopTimeInterval();
-					if (dt == null) {
-						CurrentState.WaitPhase++;
-						dt = GetStopTimeInterval();
-					}
-					CurrentState.Response = DriveTimeInterval(absTime, dt);
-					return CurrentState.Response;
-				}
-			}
-			if (CycleIntervalIterator.LastEntry && PreviousState.Distance.IsEqual(Right.Distance)) {
-				CurrentState.Response = new ResponseCycleFinished();
-				return CurrentState.Response;
-			}
-
-			var nextSpeedChange = GetSpeedChangeWithinSimulationInterval(ds);
-			if (nextSpeedChange == null || ds.IsSmallerOrEqual(nextSpeedChange - PreviousState.Distance)) {
-				if (nextSpeedChange == null || DataBus.VehicleSpeed.IsEqual(0.SI<MeterPerSecond>())) {
-					CurrentState.Response = DriveDistance(absTime, ds);
-					return CurrentState.Response;
-				}
-				var remainingDistance = nextSpeedChange - PreviousState.Distance - ds;
-				var estimatedRemainingTime = remainingDistance / DataBus.VehicleSpeed;
-				if (_intervalProlonged || remainingDistance.IsEqual(0.SI<Meter>()) ||
-					estimatedRemainingTime.IsGreater(Constants.SimulationSettings.LowerBoundTimeInterval)) {
-					CurrentState.Response = DriveDistance(absTime, ds);
-					return CurrentState.Response;
-				}
-				Log.Debug("Extending distance by {0} to next sample point. ds: {1} new ds: {2}", remainingDistance, ds,
-					nextSpeedChange - PreviousState.Distance);
-				_intervalProlonged = true;
-				CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
-					Source = this,
-					MaxDistance = nextSpeedChange - PreviousState.Distance
-				};
-				return CurrentState.Response;
-			}
-			// only drive until next sample point in cycle with speed change
-			Log.Debug("Limiting distance to next sample point {0}",
-				Right.Distance - PreviousState.Distance);
-			CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
-				Source = this,
-				MaxDistance = nextSpeedChange - PreviousState.Distance
-			};
-			return CurrentState.Response;
-		}
-
-		private Second GetStopTimeInterval()
-		{
-			if (!Left.PTOActive || IdleController == null) {
-				return Left.StoppingTime.IsGreater(3 * Constants.SimulationSettings.TargetTimeInterval)
-					? GetStopTimeIntervalThreePhases()
-					: Left.StoppingTime;
-			}
-			if (Left.StoppingTime.IsGreater(6 * Constants.SimulationSettings.TargetTimeInterval)) {
-				// 7 phases
-				return GetStopTimeIntervalSevenPhasesPTO();
-			}
-			if (Left.StoppingTime.IsGreater(0)) {
-				// 3 phases
-				return GetStopTimeIntervalThreePhasesPTO();
-			}
-			// we have a pto cycle without stopping time.
-			IdleController.ActivatePTO();
-			return IdleController.GetNextCycleTime();
-		}
-
-		private Second GetStopTimeIntervalThreePhases()
-		{
-			switch (CurrentState.WaitPhase) {
-				case 1:
-				case 3:
-					CurrentState.WaitPhase++;
-					return Constants.SimulationSettings.TargetTimeInterval;
-				case 2:
-					CurrentState.WaitPhase++;
-					return Left.StoppingTime - 2 * Constants.SimulationSettings.TargetTimeInterval;
-			}
-			return null;
-		}
-
-		private Second GetStopTimeIntervalThreePhasesPTO()
-		{
-			switch (CurrentState.WaitPhase) {
-				case 1:
-				case 3:
-					CurrentState.WaitPhase++;
-					IdleController.ActivateIdle();
-					PTOActive = false;
-					return Left.StoppingTime / 2;
-				case 2:
-					PTOActive = true;
-					IdleController.ActivatePTO();
-					return IdleController.GetNextCycleTime();
-			}
-			return null;
-		}
-
-		private Second GetStopTimeIntervalSevenPhasesPTO()
-		{
-			switch (CurrentState.WaitPhase) {
-				case 1:
-				case 5:
-					CurrentState.WaitPhase++;
-					IdleController.ActivateIdle();
-					PTOActive = false;
-					return Constants.SimulationSettings.TargetTimeInterval;
-				case 3:
-				case 7:
-					CurrentState.WaitPhase++;
-					return Constants.SimulationSettings.TargetTimeInterval;
-				case 2:
-				case 6:
-					CurrentState.WaitPhase++;
-					return Left.StoppingTime / 2 - 2 * Constants.SimulationSettings.TargetTimeInterval;
-				case 4:
-					PTOActive = true;
-					IdleController.ActivatePTO();
-					return IdleController.GetNextCycleTime();
-			}
-			return null;
-		}
-
-		private IResponse DriveTimeInterval(Second absTime, Second dt)
-		{
-			CurrentState.AbsTime = absTime;
-			CurrentState.WaitTime = PreviousState.WaitTime + dt;
-			CurrentState.Gradient = ComputeGradient(0.SI<Meter>());
-			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
-
-			return NextComponent.Request(absTime, dt, Left.VehicleTargetSpeed, CurrentState.Gradient);
-		}
-
-		private IResponse DriveDistance(Second absTime, Meter ds)
-		{
-			var nextSpeedChanges = LookAhead(Constants.SimulationSettings.BrakeNextTargetDistance);
-			if (nextSpeedChanges.Count > 0 && !CurrentState.RequestToNextSamplePointDone) {
-				CurrentState.RequestToNextSamplePointDone = true;
-				Log.Debug("current distance is close to the next speed change: {0}",
-					nextSpeedChanges.First().Distance - PreviousState.Distance);
-				return new ResponseDrivingCycleDistanceExceeded {
-					Source = this,
-					MaxDistance = Constants.SimulationSettings.BrakeNextTargetDistance
-				};
-			}
-
-			CurrentState.WaitPhase = 0;
-			//CurrentState.Distance = PreviousState.Distance + ds;
-			CurrentState.SimulationDistance = ds;
-			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
-			CurrentState.Gradient = ComputeGradient(ds);
-
-			var retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
-			retVal.Switch()
-				.Case<ResponseFailTimeInterval>(
-					r => {
-						retVal = NextComponent.Request(absTime, r.DeltaT, 0.SI<MeterPerSecond>(), CurrentState.Gradient);
-						retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
-					});
-			CurrentState.AbsTime = absTime;
-			if (retVal is ResponseSuccess) {
-				CurrentState.Distance = PreviousState.Distance + retVal.SimulationDistance;
-			}
-			return retVal;
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			container[ModalResultField.dist] = CurrentState.Distance; // (CurrentState.Distance + PreviousState.Distance) / 2.0;
-			container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
-			container[ModalResultField.v_targ] = CurrentState.VehicleTargetSpeed;
-			container[ModalResultField.grad] = (Math.Tan(CurrentState.Gradient.Value()) * 100).SI<Scalar>();
-			container[ModalResultField.altitude] = CurrentState.Altitude;
-
-			if (IdleController != null) {
-				IdleController.CommitSimulationStep(container);
-			}
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			if (!(CurrentState.Response is ResponseSuccess)) {
-				throw new VectoSimulationException("Previous request did not succeed!");
-			}
-
-			PreviousState = CurrentState;
-			CurrentState = CurrentState.Clone();
-			_intervalProlonged = false;
-
-			var stopTime = Left.PTOActive && IdleController != null
-				? Left.StoppingTime + IdleController.Duration
-				: Left.StoppingTime;
-
-			if (!stopTime.IsEqual(0) && stopTime.IsEqual(PreviousState.WaitTime)) {
-				// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
-				if (IdleController != null) {
-					IdleController.ActivateIdle();
-				}
-				CycleIntervalIterator.MoveNext();
-			}
-
-			stopTime = Left.PTOActive && IdleController != null ? Left.StoppingTime + IdleController.Duration : Left.StoppingTime;
-
-			// separately test for equality and greater than to have tolerance for equality comparison
-			if (stopTime.IsEqual(0)) {
-				while (stopTime.IsEqual(0) && CurrentState.Distance.IsGreaterOrEqual(Right.Distance) &&
-						!CycleIntervalIterator.LastEntry) {
-					// we have reached the end of the current interval in the cycle, move on...
-					CycleIntervalIterator.MoveNext();
-
-					stopTime = Left.PTOActive && IdleController != null
-						? Left.StoppingTime + IdleController.Duration
-						: Left.StoppingTime;
-				}
-			} else {
-				if (stopTime.IsEqual(PreviousState.WaitTime)) {
-					// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
-					if (IdleController != null) {
-						IdleController.ActivateIdle();
-					}
-					CycleIntervalIterator.MoveNext();
-				}
-			}
-		}
-
-		private Radian ComputeGradient(Meter ds)
-		{
-			var cycleIterator = CycleIntervalIterator.Clone();
-			while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && !cycleIterator.LastEntry) {
-				cycleIterator.MoveNext();
-			}
-			var leftSamplePoint = cycleIterator.LeftSample;
-			var rightSamplePoint = cycleIterator.RightSample;
-
-			if (leftSamplePoint.Distance.IsEqual(rightSamplePoint.Distance)) {
-				return leftSamplePoint.RoadGradient;
-			}
-			if (ds.IsEqual(0.SI<Meter>())) {
-				return leftSamplePoint.RoadGradient;
-			}
-			CurrentState.Altitude = VectoMath.Interpolate(leftSamplePoint.Distance, rightSamplePoint.Distance,
-				leftSamplePoint.Altitude, rightSamplePoint.Altitude, PreviousState.Distance + ds);
-
-			var gradient = VectoMath.InclinationToAngle(((CurrentState.Altitude - PreviousState.Altitude) /
-														ds).Value());
-			//return 0.SI<Radian>();
-			return gradient;
-		}
-
-		private Meter GetSpeedChangeWithinSimulationInterval(Meter ds)
-		{
-			var leftSamplePoint = Left;
-			var cycleIterator = CycleIntervalIterator.Clone();
-
-			do {
-				if (!leftSamplePoint.VehicleTargetSpeed.IsEqual(cycleIterator.RightSample.VehicleTargetSpeed)) {
-					return cycleIterator.RightSample.Distance;
-				}
-			} while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && cycleIterator.MoveNext());
-			if (cycleIterator.LastEntry) {
-				return cycleIterator.RightSample.Distance;
-			}
-			return null;
-		}
-
-		/// <summary>
-		/// Progress of the distance in the driving cycle.
-		/// </summary>
-		public double Progress
-		{
-			get {
-				return Data.Entries.Count > 0
-					? (CurrentState.Distance.Value() - Data.Entries.First().Distance.Value()) /
-					(Data.Entries.Last().Distance.Value() - Data.Entries.First().Distance.Value())
-					: 0;
-			}
-		}
-
-		public Meter CycleStartDistance { get; internal set; }
-
-		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance)
-		{
-			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
-
-			var cycleIterator = CycleIntervalIterator.Clone();
-			var velocity = cycleIterator.LeftSample.VehicleTargetSpeed;
-
-			do {
-				if (cycleIterator.RightSample.VehicleTargetSpeed.IsEqual(velocity)) {
-					continue;
-				}
-				var lookaheadEntry = retVal.Find(x => x.Distance == cycleIterator.RightSample.Distance);
-				if (lookaheadEntry != null) {
-					// an entry may occur twice when vehicle stops (one entry with v=0 and the other with drive on after stop)
-					// only use the one with min. speed
-					if (cycleIterator.RightSample.VehicleTargetSpeed < lookaheadEntry.VehicleTargetSpeed) {
-						retVal.Remove(lookaheadEntry);
-						retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
-					}
-				} else {
-					retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
-				}
-				velocity = cycleIterator.RightSample.VehicleTargetSpeed;
-				if (velocity.IsEqual(0.KMPHtoMeterPerSecond())) {
-					// do not look beyond vehicle stop
-					break;
-				}
-			} while (cycleIterator.MoveNext() && cycleIterator.RightSample.Distance < PreviousState.Distance + lookaheadDistance);
-			if (retVal.Count > 0) {
-				retVal = retVal.Where(x => x.Distance <= PreviousState.Distance + lookaheadDistance).ToList();
-				retVal.Sort((x, y) => x.Distance.CompareTo(y.Distance));
-			}
-			return retVal;
-		}
-
-		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
-		{
-			return LookAhead(LookaheadTimeSafetyMargin * DataBus.VehicleSpeed * time);
-		}
-
-		public void FinishSimulation()
-		{
-			Data.Finish();
-		}
-
-		public CycleData CycleData
-		{
-			get {
-				return new CycleData {
-					AbsTime = CurrentState.AbsTime,
-					AbsDistance = CurrentState.Distance,
-					LeftSample = Left,
-					RightSample = CycleIntervalIterator.RightSample
-				};
-			}
-		}
-
-		public bool PTOActive { get; private set; }
-
-		public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
-		{
-			var absDistance = CurrentState.Distance + distance;
-			var myIterator = CycleIntervalIterator.Clone();
-
-			if (absDistance > Data.Entries.Last().Distance) {
-				return ExtrapolateCycleEntry(absDistance, Data.Entries.Last());
-			}
-			while (myIterator.RightSample.Distance < absDistance) {
-				myIterator.MoveNext();
-			}
-
-			return InterpolateCycleEntry(absDistance, myIterator.RightSample);
-		}
-
-		private DrivingCycleData.DrivingCycleEntry InterpolateCycleEntry(Meter absDistance,
-			DrivingCycleData.DrivingCycleEntry lookahead)
-		{
-			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
-				Distance = absDistance,
-				Altitude = VectoMath.Interpolate(CurrentState.Distance, lookahead.Distance, CurrentState.Altitude,
-					lookahead.Altitude, absDistance)
-			};
-
-			retVal.RoadGradient =
-				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
-
-			return retVal;
-		}
-
-		private DrivingCycleData.DrivingCycleEntry ExtrapolateCycleEntry(Meter absDistance,
-			DrivingCycleData.DrivingCycleEntry lookahead)
-		{
-			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
-				Distance = absDistance,
-				Altitude = lookahead.Altitude + lookahead.RoadGradient * (absDistance - lookahead.Distance),
-			};
-
-			retVal.RoadGradient =
-				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
-
-			return retVal;
-		}
-
-		public Meter Altitude
-		{
-			get { return PreviousState.Altitude; }
-		}
-
-		public sealed class DrivingCycleState
-		{
-			public DrivingCycleState Clone()
-			{
-				return new DrivingCycleState {
-					AbsTime = AbsTime,
-					Distance = Distance,
-					VehicleTargetSpeed = VehicleTargetSpeed,
-					Altitude = Altitude,
-					WaitPhase = WaitPhase,
-					// WaitTime is not cloned on purpose!
-					WaitTime = 0.SI<Second>(),
-					Response = null
-				};
-			}
-
-			public Second AbsTime;
-
-			public Meter Distance;
-
-			public Second WaitTime;
-
-			public uint WaitPhase;
-
-			public MeterPerSecond VehicleTargetSpeed;
-
-			public Meter Altitude;
-
-			public Radian Gradient;
-
-			public IResponse Response;
-
-			public bool RequestToNextSamplePointDone;
-
-			public Meter SimulationDistance;
-		}
-
-		public void Dispose()
-		{
-			CycleIntervalIterator.Dispose();
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	/// <summary>
+	///     Class representing one Distance Based Driving Cycle
+	/// </summary>
+	public sealed class DistanceBasedDrivingCycle : StatefulProviderComponent
+		<DistanceBasedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDrivingCycleInPort, IDrivingCycleOutPort>,
+		IDrivingCycle, ISimulationOutPort, IDrivingCycleInPort, IDisposable
+	{
+		private const double LookaheadTimeSafetyMargin = 1.5;
+		internal readonly IDrivingCycleData Data;
+		internal readonly DrivingCycleEnumerator CycleIntervalIterator;
+		private bool _intervalProlonged;
+		internal IdleControllerSwitcher IdleController;
+
+		private DrivingCycleData.DrivingCycleEntry Left
+		{
+			get { return CycleIntervalIterator.LeftSample; }
+		}
+
+		private DrivingCycleData.DrivingCycleEntry Right
+		{
+			get { return CycleIntervalIterator.RightSample; }
+		}
+
+		public DistanceBasedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container)
+		{
+			Data = cycle;
+			CycleIntervalIterator = new DrivingCycleEnumerator(Data);
+			CycleStartDistance = Data.Entries.Count > 0 ? Data.Entries.First().Distance : 0.SI<Meter>();
+
+			var first = Data.Entries.First();
+			PreviousState = new DrivingCycleState {
+				AbsTime = 0.SI<Second>(),
+				WaitTime = 0.SI<Second>(),
+				Distance = first.Distance,
+				Altitude = first.Altitude,
+			};
+			CurrentState = PreviousState.Clone();
+		}
+
+		public IResponse Initialize()
+		{
+			if (Left.VehicleTargetSpeed.IsEqual(0)) {
+				var retVal = NextComponent.Initialize(DataBus.StartSpeed,
+					Left.RoadGradient, DataBus.StartAcceleration);
+				if (!(retVal is ResponseSuccess)) {
+					throw new UnexpectedResponseException("DistanceBasedDrivingCycle.Initialize: Couldn't find start gear.", retVal);
+				}
+			}
+
+			return NextComponent.Initialize(Left.VehicleTargetSpeed,
+				Left.RoadGradient);
+		}
+
+		public IResponse Request(Second absTime, Second dt)
+		{
+			throw new NotImplementedException("Distance Based Driving Cycle does not support time requests.");
+		}
+
+		public IResponse Request(Second absTime, Meter ds)
+		{
+			if (Left.Distance.IsEqual(PreviousState.Distance.Value())) {
+				var response = DoFirstSimulationInterval(absTime);
+				if (response != null) {
+					return response;
+				}
+			}
+			if (CycleIntervalIterator.LastEntry && PreviousState.Distance.IsEqual(Right.Distance)) {
+				CurrentState.Response = new ResponseCycleFinished();
+				return CurrentState.Response;
+			}
+
+			var nextSpeedChange = GetSpeedChangeWithinSimulationInterval(ds);
+			if (nextSpeedChange == null || ds.IsSmallerOrEqual(nextSpeedChange - PreviousState.Distance)) {
+				if (nextSpeedChange == null || DataBus.VehicleSpeed.IsEqual(0.SI<MeterPerSecond>())) {
+					CurrentState.Response = DriveDistance(absTime, ds);
+					return CurrentState.Response;
+				}
+				var remainingDistance = nextSpeedChange - PreviousState.Distance - ds;
+				var estimatedRemainingTime = remainingDistance / DataBus.VehicleSpeed;
+				if (_intervalProlonged || remainingDistance.IsEqual(0.SI<Meter>()) ||
+					estimatedRemainingTime.IsGreater(Constants.SimulationSettings.LowerBoundTimeInterval)) {
+					CurrentState.Response = DriveDistance(absTime, ds);
+					return CurrentState.Response;
+				}
+				Log.Debug("Extending distance by {0} to next sample point. ds: {1} new ds: {2}", remainingDistance, ds,
+					nextSpeedChange - PreviousState.Distance);
+				_intervalProlonged = true;
+				CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
+					Source = this,
+					MaxDistance = nextSpeedChange - PreviousState.Distance
+				};
+				return CurrentState.Response;
+			}
+			// only drive until next sample point in cycle with speed change
+			Log.Debug("Limiting distance to next sample point {0}",
+				Right.Distance - PreviousState.Distance);
+			CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
+				Source = this,
+				MaxDistance = nextSpeedChange - PreviousState.Distance
+			};
+			return CurrentState.Response;
+		}
+
+		private IResponse DoFirstSimulationInterval(Second absTime)
+		{
+// we are exactly on an entry in the cycle.
+			var stopTime = Left.PTOActive && IdleController != null
+				? Left.StoppingTime + IdleController.Duration
+				: Left.StoppingTime;
+
+			if (stopTime.IsGreater(0) && PreviousState.WaitTime.IsSmaller(stopTime)) {
+				// stop for certain time unless we've already waited long enough ...
+
+				// we are stopping: ensure that velocity is 0.
+				if (!Left.VehicleTargetSpeed.IsEqual(0)) {
+					Log.Warn("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}",
+						Left.StoppingTime, Left.VehicleTargetSpeed);
+					throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!");
+				}
+				var dt = GetStopTimeInterval();
+				if (dt == null) {
+					CurrentState.WaitPhase++;
+					dt = GetStopTimeInterval();
+				}
+				CurrentState.Response = DriveTimeInterval(absTime, dt);
+				return CurrentState.Response;
+			}
+			return null;
+		}
+
+		private Second GetStopTimeInterval()
+		{
+			if (!Left.PTOActive || IdleController == null) {
+				return Left.StoppingTime.IsGreater(3 * Constants.SimulationSettings.TargetTimeInterval)
+					? GetStopTimeIntervalThreePhases()
+					: Left.StoppingTime;
+			}
+			if (Left.StoppingTime.IsGreater(6 * Constants.SimulationSettings.TargetTimeInterval)) {
+				// 7 phases
+				return GetStopTimeIntervalSevenPhasesPTO();
+			}
+			if (Left.StoppingTime.IsGreater(0)) {
+				// 3 phases
+				return GetStopTimeIntervalThreePhasesPTO();
+			}
+			// we have a pto cycle without stopping time.
+			IdleController.ActivatePTO();
+			return IdleController.GetNextCycleTime();
+		}
+
+		private Second GetStopTimeIntervalThreePhases()
+		{
+			switch (CurrentState.WaitPhase) {
+				case 1:
+				case 3:
+					CurrentState.WaitPhase++;
+					return Constants.SimulationSettings.TargetTimeInterval;
+				case 2:
+					CurrentState.WaitPhase++;
+					return Left.StoppingTime - 2 * Constants.SimulationSettings.TargetTimeInterval;
+			}
+			return null;
+		}
+
+		private Second GetStopTimeIntervalThreePhasesPTO()
+		{
+			switch (CurrentState.WaitPhase) {
+				case 1:
+				case 3:
+					CurrentState.WaitPhase++;
+					IdleController.ActivateIdle();
+					PTOActive = false;
+					return Left.StoppingTime / 2;
+				case 2:
+					PTOActive = true;
+					IdleController.ActivatePTO();
+					return IdleController.GetNextCycleTime();
+			}
+			return null;
+		}
+
+		private Second GetStopTimeIntervalSevenPhasesPTO()
+		{
+			switch (CurrentState.WaitPhase) {
+				case 1:
+				case 5:
+					CurrentState.WaitPhase++;
+					IdleController.ActivateIdle();
+					PTOActive = false;
+					return Constants.SimulationSettings.TargetTimeInterval;
+				case 3:
+				case 7:
+					CurrentState.WaitPhase++;
+					return Constants.SimulationSettings.TargetTimeInterval;
+				case 2:
+				case 6:
+					CurrentState.WaitPhase++;
+					return Left.StoppingTime / 2 - 2 * Constants.SimulationSettings.TargetTimeInterval;
+				case 4:
+					PTOActive = true;
+					IdleController.ActivatePTO();
+					return IdleController.GetNextCycleTime();
+			}
+			return null;
+		}
+
+		private IResponse DriveTimeInterval(Second absTime, Second dt)
+		{
+			CurrentState.AbsTime = absTime;
+			CurrentState.WaitTime = PreviousState.WaitTime + dt;
+			CurrentState.Gradient = ComputeGradient(0.SI<Meter>());
+			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
+
+			return NextComponent.Request(absTime, dt, Left.VehicleTargetSpeed, CurrentState.Gradient);
+		}
+
+		private IResponse DriveDistance(Second absTime, Meter ds)
+		{
+			var nextSpeedChanges = LookAhead(Constants.SimulationSettings.BrakeNextTargetDistance);
+			if (nextSpeedChanges.Count > 0 && !CurrentState.RequestToNextSamplePointDone) {
+				CurrentState.RequestToNextSamplePointDone = true;
+				Log.Debug("current distance is close to the next speed change: {0}",
+					nextSpeedChanges.First().Distance - PreviousState.Distance);
+				return new ResponseDrivingCycleDistanceExceeded {
+					Source = this,
+					MaxDistance = Constants.SimulationSettings.BrakeNextTargetDistance
+				};
+			}
+
+			CurrentState.WaitPhase = 0;
+			//CurrentState.Distance = PreviousState.Distance + ds;
+			CurrentState.SimulationDistance = ds;
+			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
+			CurrentState.Gradient = ComputeGradient(ds);
+
+			var retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
+			retVal.Switch()
+				.Case<ResponseFailTimeInterval>(
+					r => {
+						retVal = NextComponent.Request(absTime, r.DeltaT, 0.SI<MeterPerSecond>(), CurrentState.Gradient);
+						retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
+					});
+			CurrentState.AbsTime = absTime;
+			if (retVal is ResponseSuccess) {
+				CurrentState.Distance = PreviousState.Distance + retVal.SimulationDistance;
+			}
+			return retVal;
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			container[ModalResultField.dist] = CurrentState.Distance; // (CurrentState.Distance + PreviousState.Distance) / 2.0;
+			container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
+			container[ModalResultField.v_targ] = CurrentState.VehicleTargetSpeed;
+			container[ModalResultField.grad] = (Math.Tan(CurrentState.Gradient.Value()) * 100).SI<Scalar>();
+			container[ModalResultField.altitude] = CurrentState.Altitude;
+
+			if (IdleController != null) {
+				IdleController.CommitSimulationStep(container);
+			}
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			if (!(CurrentState.Response is ResponseSuccess)) {
+				throw new VectoSimulationException("Previous request did not succeed!");
+			}
+
+			PreviousState = CurrentState;
+			CurrentState = CurrentState.Clone();
+			_intervalProlonged = false;
+
+			// @@@quam TODO: duplicate code  - same as below!
+			//var stopTime = Left.PTOActive && IdleController != null
+			//	? Left.StoppingTime + IdleController.Duration
+			//	: Left.StoppingTime;
+
+			//if (!stopTime.IsEqual(0) && stopTime.IsEqual(PreviousState.WaitTime)) {
+			//	// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
+			//	if (IdleController != null) {
+			//		IdleController.ActivateIdle();
+			//	}
+			//	CycleIntervalIterator.MoveNext();
+			//}
+
+			var stopTime = Left.PTOActive && IdleController != null
+				? Left.StoppingTime + IdleController.Duration
+				: Left.StoppingTime;
+
+			// separately test for equality and greater than to have tolerance for equality comparison
+			if (stopTime.IsEqual(0)) {
+				while (stopTime.IsEqual(0) && CurrentState.Distance.IsGreaterOrEqual(Right.Distance) &&
+						!CycleIntervalIterator.LastEntry) {
+					// we have reached the end of the current interval in the cycle, move on...
+					CycleIntervalIterator.MoveNext();
+
+					stopTime = Left.PTOActive && IdleController != null
+						? Left.StoppingTime + IdleController.Duration
+						: Left.StoppingTime;
+				}
+			} else {
+				if (stopTime.IsEqual(PreviousState.WaitTime)) {
+					// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
+					if (IdleController != null) {
+						IdleController.ActivateIdle();
+					}
+					CycleIntervalIterator.MoveNext();
+				}
+			}
+		}
+
+		private Radian ComputeGradient(Meter ds)
+		{
+			var cycleIterator = CycleIntervalIterator.Clone();
+			while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && !cycleIterator.LastEntry) {
+				cycleIterator.MoveNext();
+			}
+			var leftSamplePoint = cycleIterator.LeftSample;
+			var rightSamplePoint = cycleIterator.RightSample;
+
+			if (leftSamplePoint.Distance.IsEqual(rightSamplePoint.Distance)) {
+				return leftSamplePoint.RoadGradient;
+			}
+			if (ds.IsEqual(0.SI<Meter>())) {
+				return leftSamplePoint.RoadGradient;
+			}
+			CurrentState.Altitude = VectoMath.Interpolate(leftSamplePoint.Distance, rightSamplePoint.Distance,
+				leftSamplePoint.Altitude, rightSamplePoint.Altitude, PreviousState.Distance + ds);
+
+			var gradient = VectoMath.InclinationToAngle(((CurrentState.Altitude - PreviousState.Altitude) /
+														ds).Value());
+			//return 0.SI<Radian>();
+			return gradient;
+		}
+
+		private Meter GetSpeedChangeWithinSimulationInterval(Meter ds)
+		{
+			var leftSamplePoint = Left;
+			var cycleIterator = CycleIntervalIterator.Clone();
+
+			do {
+				if (!leftSamplePoint.VehicleTargetSpeed.IsEqual(cycleIterator.RightSample.VehicleTargetSpeed)) {
+					return cycleIterator.RightSample.Distance;
+				}
+			} while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && cycleIterator.MoveNext());
+			if (cycleIterator.LastEntry) {
+				return cycleIterator.RightSample.Distance;
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// Progress of the distance in the driving cycle.
+		/// </summary>
+		public double Progress
+		{
+			get
+			{
+				return Data.Entries.Count > 0
+					? (CurrentState.Distance.Value() - Data.Entries.First().Distance.Value()) /
+					(Data.Entries.Last().Distance.Value() - Data.Entries.First().Distance.Value())
+					: 0;
+			}
+		}
+
+		public Meter CycleStartDistance { get; internal set; }
+
+		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance)
+		{
+			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
+
+			var cycleIterator = CycleIntervalIterator.Clone();
+			var velocity = cycleIterator.LeftSample.VehicleTargetSpeed;
+
+			do {
+				if (cycleIterator.RightSample.VehicleTargetSpeed.IsEqual(velocity)) {
+					continue;
+				}
+				var lookaheadEntry = retVal.Find(x => x.Distance == cycleIterator.RightSample.Distance);
+				if (lookaheadEntry != null) {
+					// an entry may occur twice when vehicle stops (one entry with v=0 and the other with drive on after stop)
+					// only use the one with min. speed
+					if (cycleIterator.RightSample.VehicleTargetSpeed < lookaheadEntry.VehicleTargetSpeed) {
+						retVal.Remove(lookaheadEntry);
+						retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
+					}
+				} else {
+					retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
+				}
+				velocity = cycleIterator.RightSample.VehicleTargetSpeed;
+				if (velocity.IsEqual(0.KMPHtoMeterPerSecond())) {
+					// do not look beyond vehicle stop
+					break;
+				}
+			} while (cycleIterator.MoveNext() && cycleIterator.RightSample.Distance < PreviousState.Distance + lookaheadDistance);
+			if (retVal.Count > 0) {
+				retVal = retVal.Where(x => x.Distance <= PreviousState.Distance + lookaheadDistance).ToList();
+				retVal.Sort((x, y) => x.Distance.CompareTo(y.Distance));
+			}
+			return retVal;
+		}
+
+		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
+		{
+			return LookAhead(LookaheadTimeSafetyMargin * DataBus.VehicleSpeed * time);
+		}
+
+		public void FinishSimulation()
+		{
+			Data.Finish();
+		}
+
+		public CycleData CycleData
+		{
+			get
+			{
+				return new CycleData {
+					AbsTime = CurrentState.AbsTime,
+					AbsDistance = CurrentState.Distance,
+					LeftSample = Left,
+					RightSample = CycleIntervalIterator.RightSample
+				};
+			}
+		}
+
+		public bool PTOActive { get; private set; }
+
+		public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
+		{
+			var absDistance = CurrentState.Distance + distance;
+			var myIterator = CycleIntervalIterator.Clone();
+
+			if (absDistance > Data.Entries.Last().Distance) {
+				return ExtrapolateCycleEntry(absDistance, Data.Entries.Last());
+			}
+			while (myIterator.RightSample.Distance < absDistance) {
+				myIterator.MoveNext();
+			}
+
+			return InterpolateCycleEntry(absDistance, myIterator.RightSample);
+		}
+
+		private DrivingCycleData.DrivingCycleEntry InterpolateCycleEntry(Meter absDistance,
+			DrivingCycleData.DrivingCycleEntry lookahead)
+		{
+			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
+				Distance = absDistance,
+				Altitude = VectoMath.Interpolate(CurrentState.Distance, lookahead.Distance, CurrentState.Altitude,
+					lookahead.Altitude, absDistance)
+			};
+
+			retVal.RoadGradient =
+				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
+
+			return retVal;
+		}
+
+		private DrivingCycleData.DrivingCycleEntry ExtrapolateCycleEntry(Meter absDistance,
+			DrivingCycleData.DrivingCycleEntry lookahead)
+		{
+			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
+				Distance = absDistance,
+				Altitude = lookahead.Altitude + lookahead.RoadGradient * (absDistance - lookahead.Distance),
+			};
+
+			retVal.RoadGradient =
+				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
+
+			return retVal;
+		}
+
+		public Meter Altitude
+		{
+			get { return PreviousState.Altitude; }
+		}
+
+		public sealed class DrivingCycleState
+		{
+			public DrivingCycleState Clone()
+			{
+				return new DrivingCycleState {
+					AbsTime = AbsTime,
+					Distance = Distance,
+					VehicleTargetSpeed = VehicleTargetSpeed,
+					Altitude = Altitude,
+					WaitPhase = WaitPhase,
+					// WaitTime is not cloned on purpose!
+					WaitTime = 0.SI<Second>(),
+					Response = null
+				};
+			}
+
+			public Second AbsTime;
+
+			public Meter Distance;
+
+			public Second WaitTime;
+
+			public uint WaitPhase;
+
+			public MeterPerSecond VehicleTargetSpeed;
+
+			public Meter Altitude;
+
+			public Radian Gradient;
+
+			public IResponse Response;
+
+			public bool RequestToNextSamplePointDone;
+
+			public Meter SimulationDistance;
+		}
+
+		public void Dispose()
+		{
+			CycleIntervalIterator.Dispose();
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs
index cecf32836f9773c7399efb08d54627d8efbc3888..424e42675af0b118fa62556b85e7a1cc3d86777b 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/MeasuredSpeedDrivingCycle.cs
@@ -29,337 +29,358 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	/// <summary>
-	/// Driving Cycle for the Measured Speed Gear driving cycle.
-	/// </summary>
-	public class MeasuredSpeedDrivingCycle :
-		StatefulProviderComponent
-			<MeasuredSpeedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDriverDemandInPort, IDriverDemandOutPort>,
-		IDriverInfo, IDrivingCycleInfo, IMileageCounter, IDriverDemandInProvider, IDriverDemandInPort, ISimulationOutProvider,
-		ISimulationOutPort
-	{
-		public class DrivingCycleState
-		{
-			public DrivingCycleState Clone()
-			{
-				return new DrivingCycleState {
-					Distance = Distance,
-				};
-			}
-
-			public Meter Distance;
-			public Meter SimulationDistance;
-			public MeterPerSquareSecond Acceleration;
-		}
-
-		protected readonly IDrivingCycleData Data;
-
-		protected internal readonly DrivingCycleEnumerator CycleIterator;
-
-		protected Second AbsTime { get; set; }
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class.
-		/// </summary>
-		/// <param name="container">The container.</param>
-		/// <param name="cycle">The cycle.</param>
-		public MeasuredSpeedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle)
-			: base(container)
-		{
-			Data = cycle;
-			CycleIterator = new DrivingCycleEnumerator(cycle);
-
-			PreviousState = new DrivingCycleState {
-				Distance = 0.SI<Meter>(),
-			};
-			CurrentState = PreviousState.Clone();
-		}
-
-		public IResponse Initialize()
-		{
-			var first = Data.Entries.First();
-
-			AbsTime = first.Time;
-
-			var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient);
-			if (!(response is ResponseSuccess)) {
-				throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle: Couldn't find start gear.", response);
-			}
-
-			response.AbsTime = AbsTime;
-			return response;
-		}
-
-		public IResponse Request(Second absTime, Meter ds)
-		{
-			Log.Fatal("MeasuredSpeed Cycle can not handle distance request.");
-			throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request.");
-		}
-
-		public virtual IResponse Request(Second absTime, Second dt)
-		{
-			var debug = new DebugData();
-
-			// cycle finished
-			if (CycleIterator.LastEntry && absTime >= CycleIterator.RightSample.Time) {
-				return new ResponseCycleFinished { AbsTime = absTime, Source = this };
-			}
-
-			if (CycleIterator.RightSample == null) {
-				throw new VectoException("Exceeding cycle!");
-			}
-			// interval exceeded
-			if ((absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
-				return new ResponseFailTimeInterval {
-					AbsTime = absTime,
-					Source = this,
-					DeltaT = CycleIterator.RightSample.Time - absTime
-				};
-			}
-
-			// calc acceleration from speed diff vehicle to cycle
-			var targetSpeed = CycleIterator.RightSample.VehicleTargetSpeed;
-			if (targetSpeed.IsEqual(0.KMPHtoMeterPerSecond(), 0.5.KMPHtoMeterPerSecond())) {
-				targetSpeed = 0.KMPHtoMeterPerSecond();
-			}
-			var deltaV = targetSpeed - DataBus.VehicleSpeed;
-			var deltaT = CycleIterator.RightSample.Time - CycleIterator.LeftSample.Time;
-
-			if (DataBus.VehicleSpeed.IsSmaller(0)) {
-				throw new VectoSimulationException("vehicle velocity is smaller than zero");
-			}
-
-			if (deltaT.IsSmaller(0)) {
-				throw new VectoSimulationException("deltaT is smaller than zero");
-			}
-
-			var acceleration = deltaV / deltaT;
-			var gradient = CycleIterator.LeftSample.RoadGradient;
-			DriverAcceleration = acceleration;
-			DriverBehavior = acceleration < 0
-				? DriverBehavior = DrivingBehavior.Braking
-				: DriverBehavior = DrivingBehavior.Driving;
-			if (DataBus.VehicleStopped && acceleration.IsEqual(0)) {
-				DriverBehavior = DrivingBehavior.Halted;
-			}
-
-			IResponse response;
-			var responseCount = 0;
-			do {
-				response = NextComponent.Request(absTime, dt, acceleration, gradient);
-				debug.Add(response);
-				response.Switch()
-					.Case<ResponseGearShift>(() => response = NextComponent.Request(absTime, dt, acceleration, gradient))
-					.Case<ResponseUnderload>(r => {
-						var acceleration1 = acceleration;
-						DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta,
-							getYValue: result => DataBus.ClutchClosed(absTime)
-								? ((ResponseDryRun)result).DeltaDragLoad
-								: ((ResponseDryRun)result).GearboxPowerRequest,
-							evaluateFunction: x => {
-								DataBus.BrakePower = x;
-								return NextComponent.Request(absTime, dt, acceleration1, gradient, true);
-							},
-							criterion: y => DataBus.ClutchClosed(absTime)
-								? ((ResponseDryRun)y).DeltaDragLoad.Value()
-								: ((ResponseDryRun)y).GearboxPowerRequest.Value());
-						Log.Info(
-							"Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}",
-							absTime, dt, acceleration, gradient, DataBus.BrakePower);
-
-						if (DataBus.BrakePower.IsSmaller(0)) {
-							Log.Info(
-								"BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
-								absTime, dt, acceleration, gradient, DataBus.BrakePower);
-							DataBus.BrakePower = 0.SI<Watt>();
-							acceleration = SearchAlgorithm.Search(acceleration, r.Delta,
-								Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
-								getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
-								evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
-								criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value());
-						}
-
-						response = NextComponent.Request(absTime, dt, acceleration, gradient);
-					})
-					.Case<ResponseOverload>(r => {
-						if (DataBus.ClutchClosed(absTime)) {
-							acceleration = SearchAlgorithm.Search(acceleration, r.Delta,
-								Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
-								getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
-								evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
-								criterion:
-									y => ((ResponseDryRun)y).DeltaFullLoad.Value());
-							Log.Info(
-								"Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
-								absTime, dt, acceleration, gradient);
-						} else {
-							DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta,
-								getYValue: result => DataBus.ClutchClosed(absTime)
-									? ((ResponseDryRun)result).DeltaDragLoad
-									: ((ResponseDryRun)result).GearboxPowerRequest,
-								evaluateFunction: x => {
-									DataBus.BrakePower = x;
-									return NextComponent.Request(absTime, dt, acceleration, gradient, true);
-								},
-								criterion: y => DataBus.ClutchClosed(absTime)
-									? ((ResponseDryRun)y).DeltaDragLoad.Value()
-									: ((ResponseDryRun)y).GearboxPowerRequest.Value());
-							Log.Info(
-								"Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}",
-								absTime, dt, acceleration, gradient, DataBus.BrakePower);
-
-							if (DataBus.BrakePower.IsSmaller(0)) {
-								Log.Info(
-									"BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
-									absTime, dt, acceleration, gradient, DataBus.BrakePower);
-								DataBus.BrakePower = 0.SI<Watt>();
-								acceleration = SearchAlgorithm.Search(acceleration, r.Delta,
-									Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
-									getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
-									evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
-									criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value());
-							}
-						}
-						response = NextComponent.Request(absTime, dt, acceleration, gradient);
-					})
-					.Case<ResponseEngineSpeedTooHigh>(r => {
-						acceleration = SearchAlgorithm.Search(acceleration, r.DeltaEngineSpeed,
-							Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
-							getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed,
-							evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
-							criterion:
-								y => ((ResponseDryRun)y).DeltaEngineSpeed.Value());
-						Log.Info(
-							"Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
-							absTime, dt, acceleration, gradient);
-					})
-					.Case<ResponseFailTimeInterval>(r => { dt = r.DeltaT; })
-					.Case<ResponseSuccess>()
-					.Default(
-						r => { throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle received an unexpected response.", r); });
-			} while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10));
-
-			AbsTime = absTime + dt;
-
-			response.SimulationInterval = dt;
-			response.Acceleration = acceleration;
-			debug.Add(response);
-
-			CurrentState.SimulationDistance = acceleration / 2 * dt * dt + DataBus.VehicleSpeed * dt;
-			if (CurrentState.SimulationDistance.IsSmaller(0)) {
-				throw new VectoSimulationException(
-					"MeasuredSpeed: Simulation Distance must not be negative. Driving Backward is not allowed.");
-			}
-
-			CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance;
-			CurrentState.Acceleration = acceleration;
-
-			return response;
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			container[ModalResultField.dist] = CurrentState.Distance;
-			container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
-			container[ModalResultField.v_targ] = CycleIterator.LeftSample.VehicleTargetSpeed;
-			container[ModalResultField.grad] = CycleIterator.LeftSample.RoadGradientPercent;
-			container[ModalResultField.altitude] = CycleIterator.LeftSample.Altitude;
-			container[ModalResultField.acc] = CurrentState.Acceleration;
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			if ((CycleIterator.RightSample == null) || AbsTime.IsGreaterOrEqual(CycleIterator.RightSample.Time)) {
-				CycleIterator.MoveNext();
-			}
-			AdvanceState();
-		}
-
-		public double Progress
-		{
-			get { return AbsTime == null ? 0 : AbsTime.Value() / Data.Entries.Last().Time.Value(); }
-		}
-
-		public CycleData CycleData
-		{
-			get {
-				return new CycleData {
-					AbsTime = CycleIterator.LeftSample.Time,
-					AbsDistance = null,
-					LeftSample = CycleIterator.LeftSample,
-					RightSample = CycleIterator.RightSample,
-				};
-			}
-		}
-
-		public bool PTOActive
-		{
-			get { return false; }
-		}
-
-		public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
-		{
-			return new DrivingCycleData.DrivingCycleEntry(CycleIterator.RightSample);
-			//throw new System.NotImplementedException();
-		}
-
-		public Meter Altitude
-		{
-			get { return CycleIterator.LeftSample.Altitude; }
-		}
-
-		public Meter CycleStartDistance
-		{
-			get { return 0.SI<Meter>(); }
-		}
-
-		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance)
-		{
-			throw new NotImplementedException();
-		}
-
-		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
-		{
-			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
-
-			var iterator = CycleIterator.Clone();
-			do {
-				retVal.Add(iterator.RightSample);
-			} while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time);
-
-			return retVal;
-		}
-
-		public void FinishSimulation()
-		{
-			Data.Finish();
-		}
-
-		public DrivingBehavior DriverBehavior { get; internal set; }
-
-		public MeterPerSquareSecond DriverAcceleration { get; protected set; }
-
-		public Meter Distance
-		{
-			get { return CurrentState.Distance; }
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	/// <summary>
+	/// Driving Cycle for the Measured Speed Gear driving cycle.
+	/// </summary>
+	public class MeasuredSpeedDrivingCycle :
+		StatefulProviderComponent
+			<MeasuredSpeedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDriverDemandInPort, IDriverDemandOutPort>,
+		IDriverInfo, IDrivingCycleInfo, IMileageCounter, IDriverDemandInProvider, IDriverDemandInPort, ISimulationOutProvider,
+		ISimulationOutPort
+	{
+		public class DrivingCycleState
+		{
+			public DrivingCycleState Clone()
+			{
+				return new DrivingCycleState {
+					Distance = Distance,
+				};
+			}
+
+			public Meter Distance;
+			public Meter SimulationDistance;
+			public MeterPerSquareSecond Acceleration;
+		}
+
+		protected readonly IDrivingCycleData Data;
+
+		protected internal readonly DrivingCycleEnumerator CycleIterator;
+
+		protected Second AbsTime { get; set; }
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="PowertrainDrivingCycle"/> class.
+		/// </summary>
+		/// <param name="container">The container.</param>
+		/// <param name="cycle">The cycle.</param>
+		public MeasuredSpeedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle)
+			: base(container)
+		{
+			Data = cycle;
+			CycleIterator = new DrivingCycleEnumerator(cycle);
+
+			PreviousState = new DrivingCycleState {
+				Distance = 0.SI<Meter>(),
+			};
+			CurrentState = PreviousState.Clone();
+		}
+
+		public IResponse Initialize()
+		{
+			var first = Data.Entries.First();
+
+			AbsTime = first.Time;
+
+			var response = NextComponent.Initialize(first.VehicleTargetSpeed, first.RoadGradient);
+			if (!(response is ResponseSuccess)) {
+				throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle: Couldn't find start gear.", response);
+			}
+
+			response.AbsTime = AbsTime;
+			return response;
+		}
+
+		public IResponse Request(Second absTime, Meter ds)
+		{
+			Log.Fatal("MeasuredSpeed Cycle can not handle distance request.");
+			throw new VectoSimulationException("MeasuredSpeed Cycle can not handle distance request.");
+		}
+
+		public virtual IResponse Request(Second absTime, Second dt)
+		{
+			var debug = new DebugData();
+
+			// cycle finished
+			if (CycleIterator.LastEntry && absTime >= CycleIterator.RightSample.Time) {
+				return new ResponseCycleFinished { AbsTime = absTime, Source = this };
+			}
+
+			if (CycleIterator.RightSample == null) {
+				throw new VectoException("Exceeding cycle!");
+			}
+			// interval exceeded
+			if ((absTime + dt).IsGreater(CycleIterator.RightSample.Time)) {
+				return new ResponseFailTimeInterval {
+					AbsTime = absTime,
+					Source = this,
+					DeltaT = CycleIterator.RightSample.Time - absTime
+				};
+			}
+
+			// calc acceleration from speed diff vehicle to cycle
+			var targetSpeed = CycleIterator.RightSample.VehicleTargetSpeed;
+			if (targetSpeed.IsEqual(0.KMPHtoMeterPerSecond(), 0.5.KMPHtoMeterPerSecond())) {
+				targetSpeed = 0.KMPHtoMeterPerSecond();
+			}
+			var deltaV = targetSpeed - DataBus.VehicleSpeed;
+			var deltaT = CycleIterator.RightSample.Time - CycleIterator.LeftSample.Time;
+
+			if (DataBus.VehicleSpeed.IsSmaller(0)) {
+				throw new VectoSimulationException("vehicle velocity is smaller than zero");
+			}
+
+			if (deltaT.IsSmaller(0)) {
+				throw new VectoSimulationException("deltaT is smaller than zero");
+			}
+
+			var acceleration = deltaV / deltaT;
+			var gradient = CycleIterator.LeftSample.RoadGradient;
+			DriverAcceleration = acceleration;
+			DriverBehavior = acceleration < 0
+				? DriverBehavior = DrivingBehavior.Braking
+				: DriverBehavior = DrivingBehavior.Driving;
+			if (DataBus.VehicleStopped && acceleration.IsEqual(0)) {
+				DriverBehavior = DrivingBehavior.Halted;
+			}
+
+			IResponse response;
+			var responseCount = 0;
+			do {
+				response = NextComponent.Request(absTime, dt, acceleration, gradient);
+				debug.Add(response);
+				response.Switch()
+					.Case<ResponseGearShift>(() => response = NextComponent.Request(absTime, dt, acceleration, gradient))
+					.Case<ResponseUnderload>(r => {
+						response = HandleUnderload(absTime, dt, r, gradient, ref acceleration);
+					})
+					.Case<ResponseOverload>(r => {
+						response = HandleOverload(absTime, dt, r, gradient, ref acceleration);
+					})
+					.Case<ResponseEngineSpeedTooHigh>(r => {
+						acceleration = SearchAlgorithm.Search(acceleration, r.DeltaEngineSpeed,
+							Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
+							getYValue: result => ((ResponseDryRun)result).DeltaEngineSpeed,
+							evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
+							criterion:
+								y => ((ResponseDryRun)y).DeltaEngineSpeed.Value());
+						Log.Info(
+							"Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
+							absTime, dt, acceleration, gradient);
+					})
+					.Case<ResponseFailTimeInterval>(r => {
+						dt = r.DeltaT;
+					})
+					.Case<ResponseSuccess>()
+					.Default(
+						r => {
+							throw new UnexpectedResponseException("MeasuredSpeedDrivingCycle received an unexpected response.", r);
+						});
+			} while (!(response is ResponseSuccess || response is ResponseFailTimeInterval) && (++responseCount < 10));
+
+			AbsTime = absTime + dt;
+
+			response.SimulationInterval = dt;
+			response.Acceleration = acceleration;
+			debug.Add(response);
+
+			CurrentState.SimulationDistance = acceleration / 2 * dt * dt + DataBus.VehicleSpeed * dt;
+			if (CurrentState.SimulationDistance.IsSmaller(0)) {
+				throw new VectoSimulationException(
+					"MeasuredSpeed: Simulation Distance must not be negative. Driving Backward is not allowed.");
+			}
+
+			CurrentState.Distance = CurrentState.SimulationDistance + PreviousState.Distance;
+			CurrentState.Acceleration = acceleration;
+
+			return response;
+		}
+
+		private IResponse HandleUnderload(Second absTime, Second dt, ResponseUnderload r,
+			Radian gradient, ref MeterPerSquareSecond acceleration)
+		{
+			MeterPerSquareSecond acc = acceleration;
+			DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta,
+				getYValue: result => DataBus.ClutchClosed(absTime)
+					? ((ResponseDryRun)result).DeltaDragLoad
+					: ((ResponseDryRun)result).GearboxPowerRequest,
+				evaluateFunction: x => {
+					DataBus.BrakePower = x;
+					return NextComponent.Request(absTime, dt, acc, gradient, true);
+				},
+				criterion: y => DataBus.ClutchClosed(absTime)
+					? ((ResponseDryRun)y).DeltaDragLoad.Value()
+					: ((ResponseDryRun)y).GearboxPowerRequest.Value());
+			Log.Info(
+				"Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}",
+				absTime, dt, acceleration, gradient, DataBus.BrakePower);
+
+			if (DataBus.BrakePower.IsSmaller(0)) {
+				Log.Info(
+					"BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
+					absTime, dt, acceleration, gradient, DataBus.BrakePower);
+				DataBus.BrakePower = 0.SI<Watt>();
+				acceleration = SearchAlgorithm.Search(acceleration, r.Delta,
+					Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
+					getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
+					evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
+					criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value());
+			}
+
+			var response = NextComponent.Request(absTime, dt, acceleration, gradient);
+			return response;
+		}
+
+		private IResponse HandleOverload(Second absTime, Second dt, ResponseOverload r, Radian gradient,
+			ref MeterPerSquareSecond acceleration)
+		{
+			IResponse response;
+			if (DataBus.ClutchClosed(absTime)) {
+				acceleration = SearchAlgorithm.Search(acceleration, r.Delta,
+					Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
+					getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
+					evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
+					criterion:
+						y => ((ResponseDryRun)y).DeltaFullLoad.Value());
+				Log.Info(
+					"Found operating point for driver acceleration. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
+					absTime, dt, acceleration, gradient);
+			} else {
+				var acc = acceleration;
+				DataBus.BrakePower = SearchAlgorithm.Search(DataBus.BrakePower, r.Delta, -r.Delta,
+					getYValue: result => DataBus.ClutchClosed(absTime)
+						? ((ResponseDryRun)result).DeltaDragLoad
+						: ((ResponseDryRun)result).GearboxPowerRequest,
+					evaluateFunction: x => {
+						DataBus.BrakePower = x;
+						return NextComponent.Request(absTime, dt, acc, gradient, true);
+					},
+					criterion: y => DataBus.ClutchClosed(absTime)
+						? ((ResponseDryRun)y).DeltaDragLoad.Value()
+						: ((ResponseDryRun)y).GearboxPowerRequest.Value());
+				Log.Info(
+					"Found operating point for braking. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}, BrakePower: {4}",
+					absTime, dt, acceleration, gradient, DataBus.BrakePower);
+
+				if (DataBus.BrakePower.IsSmaller(0)) {
+					Log.Info(
+						"BrakePower was negative: {4}. Setting to 0 and searching for acceleration operating point. absTime: {0}, dt: {1}, acceleration: {2}, gradient: {3}",
+						absTime, dt, acceleration, gradient, DataBus.BrakePower);
+					DataBus.BrakePower = 0.SI<Watt>();
+					acceleration = SearchAlgorithm.Search(acceleration, r.Delta,
+						Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
+						getYValue: result => ((ResponseDryRun)result).DeltaFullLoad,
+						evaluateFunction: x => NextComponent.Request(absTime, dt, x, gradient, true),
+						criterion: y => ((ResponseDryRun)y).DeltaFullLoad.Value());
+				}
+			}
+			response = NextComponent.Request(absTime, dt, acceleration, gradient);
+			return response;
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			container[ModalResultField.dist] = CurrentState.Distance;
+			container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
+			container[ModalResultField.v_targ] = CycleIterator.LeftSample.VehicleTargetSpeed;
+			container[ModalResultField.grad] = CycleIterator.LeftSample.RoadGradientPercent;
+			container[ModalResultField.altitude] = CycleIterator.LeftSample.Altitude;
+			container[ModalResultField.acc] = CurrentState.Acceleration;
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			if ((CycleIterator.RightSample == null) || AbsTime.IsGreaterOrEqual(CycleIterator.RightSample.Time)) {
+				CycleIterator.MoveNext();
+			}
+			AdvanceState();
+		}
+
+		public double Progress
+		{
+			get { return AbsTime == null ? 0 : AbsTime.Value() / Data.Entries.Last().Time.Value(); }
+		}
+
+		public CycleData CycleData
+		{
+			get
+			{
+				return new CycleData {
+					AbsTime = CycleIterator.LeftSample.Time,
+					AbsDistance = null,
+					LeftSample = CycleIterator.LeftSample,
+					RightSample = CycleIterator.RightSample,
+				};
+			}
+		}
+
+		public bool PTOActive
+		{
+			get { return false; }
+		}
+
+		public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
+		{
+			return new DrivingCycleData.DrivingCycleEntry(CycleIterator.RightSample);
+			//throw new System.NotImplementedException();
+		}
+
+		public Meter Altitude
+		{
+			get { return CycleIterator.LeftSample.Altitude; }
+		}
+
+		public Meter CycleStartDistance
+		{
+			get { return 0.SI<Meter>(); }
+		}
+
+		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance)
+		{
+			throw new NotImplementedException();
+		}
+
+		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
+		{
+			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
+
+			var iterator = CycleIterator.Clone();
+			do {
+				retVal.Add(iterator.RightSample);
+			} while (iterator.MoveNext() && iterator.RightSample.Time < AbsTime + time);
+
+			return retVal;
+		}
+
+		public void FinishSimulation()
+		{
+			Data.Finish();
+		}
+
+		public DrivingBehavior DriverBehavior { get; internal set; }
+
+		public MeterPerSquareSecond DriverAcceleration { get; protected set; }
+
+		public Meter Distance
+		{
+			get { return CurrentState.Distance; }
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
index 38be1b2c9df90d7169955c1815aa4a6a1febbf5a..f539a4a6bd4627c91271dcae73ac3e0249daade3 100644
--- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
@@ -29,346 +29,342 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Data;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-
-// ReSharper disable MemberCanBePrivate.Global  -- used by API!
-
-namespace TUGraz.VectoCore.OutputData
-{
-	public delegate void WriteSumData(IModalDataContainer data);
-
-	/// <summary>
-	/// Class for the sum file in vecto.
-	/// </summary>
-	public class SummaryDataContainer : LoggingObject, IDisposable
-	{
-		// ReSharper disable InconsistentNaming
-		public const string INTERNAL_PREFIX = "INTERNAL";
-		public const string SORT = INTERNAL_PREFIX + " Sorting";
-		public const string JOB = "Job [-]";
-		public const string INPUTFILE = "Input File [-]";
-		public const string CYCLE = "Cycle [-]";
-		public const string STATUS = "Status";
-		public const string CURB_MASS = "Chassis curb mass [kg]";
-		public const string LOADING = "Loading [kg]";
-
-		public const string VEHICLE_MANUFACTURER = "Vehicle manufacturer [-]";
-		public const string VIN_NUMBER = "VIN number";
-		public const string VEHICLE_MODEL = "Vehicle model [-]";
-
-		public const string ENGINE_MANUFACTURER = "Engine manufacturer [-]";
-		public const string ENGINE_MODEL = "Engine model [-]";
-		public const string ENGINE_FUEL_TYPE = "Engine fuel type [-]";
-		public const string ENGINE_WHTC_URBAN = "Engine WHTCUrban";
-		public const string ENGINE_WHTC_RURAL = "Engine WHTCRural";
-		public const string ENGINE_WHTC_MOTORWAY = "Engine WHTCMotorway";
-		public const string ENGINE_BF_COLD_HOT = "Engine BFColdHot";
-		public const string ENGINE_CF_REG_PER = "Engine CFRegPer";
-		public const string ENGINE_ACTUAL_CORRECTION_FACTOR = "Engine actual CF";
-		public const string ENGINE_RATED_POWER = "Engine rated power [kW]";
-		public const string ENGINE_IDLING_SPEED = "Engine idling speed [rpm]";
-		public const string ENGINE_RATED_SPEED = "Engine rated speed [rpm]";
-		public const string ENGINE_DISPLACEMENT = "Engine displacement [ccm]";
-
-		public const string ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER = "total RRC [-]";
-		public const string ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER = "weighted RRC w/o trailer [-]";
-
-		public const string GEARBOX_MANUFACTURER = "Gearbox manufacturer [-]";
-		public const string GEARBOX_MODEL = "Gearbox model [-]";
-		public const string GEARBOX_TYPE = "Gearbox type [-]";
-		public const string GEAR_RATIO_FIRST_GEAR = "Gear ratio first gear [-]";
-		public const string GEAR_RATIO_LAST_GEAR = "Gear ratio last gear [-]";
-
-		public const string TORQUECONVERTER_MANUFACTURER = "Torque converter manufacturer [-]";
-		public const string TORQUECONVERTER_MODEL = "Torque converter model [-]";
-
-		public const string RETARDER_MANUFACTURER = "Retarder manufacturer [-]";
-		public const string RETARDER_MODEL = "Retarder model [-]";
-		public const string RETARDER_TYPE = "Retarder type [-]";
-
-		public const string ANGLEDRIVE_MANUFACTURER = "Angledrive manufacturer [-]";
-		public const string ANGLEDRIVE_MODEL = "Angledrive model [-]";
-		public const string ANGLEDRIVE_RATIO = "Angledrive ratio [-]";
-
-		public const string AXLE_MANUFACTURER = "Axle manufacturer [-]";
-		public const string AXLE_MODEL = "Axle model [-]";
-		public const string AXLE_RATIO = "Axle gear ratio [-]";
-
-		public const string AUX_TECH_FORMAT = "Auxiliary technology {0} [-]";
-
-		public const string HDV_CO2_VEHICLE_CLASS = "HDV CO2 vehicle class [-]";
-		public const string TOTAL_VEHICLE_MASS = "Total vehicle mass [kg]";
-		public const string CD_x_A = "CdxA [m²]";
-		//public const string ROLLING_RESISTANCE_COEFFICIENT = "weighed RRC [-]";
-		public const string R_DYN = "r_dyn [m]";
-
-		public const string CARGO_VOLUME = "Cargo Volume [m³]";
-		public const string TIME = "time [s]";
-		public const string DISTANCE = "distance [km]";
-		public const string SPEED = "speed [km/h]";
-		public const string ALTITUDE_DELTA = "altitudeDelta [m]";
-
-		public const string FCMAP_H = "FC-Map [g/h]";
-		public const string FCMAP_KM = "FC-Map [g/km]";
-		public const string FCAUXC_H = "FC-AUXc [g/h]";
-		public const string FCAUXC_KM = "FC-AUXc [g/km]";
-		public const string FCWHTCC_H = "FC-WHTCc [g/h]";
-		public const string FCWHTCC_KM = "FC-WHTCc [g/km]";
-		public const string FCAAUX_H = "FC-AAUX [g/h]";
-		public const string FCAAUX_KM = "FC-AAUX [g/km]";
-
-		public const string FCFINAL_H = "FC-Final [g/h]";
-		public const string FCFINAL_KM = "FC-Final [g/km]";
-		public const string FCFINAL_LITERPER100KM = "FC-Final [l/100km]";
-		public const string FCFINAL_LITERPER100TKM = "FC-Final [l/100tkm]";
-		public const string FCFINAL_LiterPer100M3KM = "FC-Final [l/100m³km]";
-
-		public const string CO2_KM = "CO2 [g/km]";
-		public const string CO2_TKM = "CO2 [g/tkm]";
-		public const string CO2_M3KM = "CO2 [g/m³km]";
-
-		public const string P_WHEEL_POS = "P_wheel_in_pos [kW]";
-		public const string P_FCMAP_POS = "P_fcmap_pos [kW]";
-
-		public const string E_FORMAT = "E_{0} [kWh]";
-		public const string E_AUX_FORMAT = "E_aux_{0} [kWh]";
-		public const string E_AUX = "E_aux_sum [kWh]";
-
-		public const string E_AIR = "E_air [kWh]";
-		public const string E_ROLL = "E_roll [kWh]";
-		public const string E_GRAD = "E_grad [kWh]";
-		public const string E_VEHICLE_INERTIA = "E_vehi_inertia [kWh]";
-		public const string E_POWERTRAIN_INERTIA = "E_powertrain_inertia [kWh]";
-		public const string E_BRAKE = "E_brake [kWh]";
-		public const string E_GBX_LOSS = "E_gbx_loss [kWh]";
-		public const string E_SHIFT_LOSS = "E_shift_loss [kWh]";
-		public const string E_AXL_LOSS = "E_axl_loss [kWh]";
-		public const string E_RET_LOSS = "E_ret_loss [kWh]";
-		public const string E_TC_LOSS = "E_tc_loss [kWh]";
-		public const string E_ANGLE_LOSS = "E_angle_loss [kWh]";
-		public const string E_CLUTCH_LOSS = "E_clutch_loss [kWh]";
-		public const string E_FCMAP_POS = "E_fcmap_pos [kWh]";
-		public const string E_FCMAP_NEG = "E_fcmap_neg [kWh]";
-
-		public const string ACC = "a [m/s^2]";
-		public const string ACC_POS = "a_pos [m/s^2]";
-		public const string ACC_NEG = "a_neg [m/s^2]";
-
-		public const string ACC_TIMESHARE = "AccelerationTimeShare [%]";
-		public const string DEC_TIMESHARE = "DecelerationTimeShare [%]";
-		public const string CRUISE_TIMESHARE = "CruiseTimeShare [%]";
-		public const string STOP_TIMESHARE = "StopTimeShare [%]";
-
-		public const string MAX_SPEED = "max. speed [km/h";
-		public const string MAX_ACCELERATION = "max. acc [m/s²]";
-		public const string MAX_DECELERATION = "max. dec [m/s²]";
-		public const string AVG_ENGINE_SPEED = "n_eng_avg [rpm]";
-		public const string MAX_ENGINE_SPEED = "n_eng_max [rpm]";
-		public const string NUM_GEARSHIFTS = "gear shifts [-]";
-		public const string ENGINE_FULL_LOAD_TIME_SHARE = "Engine max. Load time share [%]";
-		public const string COASTING_TIME_SHARE = "CoastingTimeShare [%]";
-		public const string BRAKING_TIME_SHARE = "BrakingTImeShare [%]";
-
-		public const string TIME_SHARE_PER_GEAR_FORMAT = "Gear {0} TimeShare [%]";
-
-		// ReSharper restore InconsistentNaming
-
-		internal readonly DataTable Table;
-		private readonly ISummaryWriter _sumWriter;
-
-
-		protected SummaryDataContainer() {}
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="SummaryDataContainer"/> class.
-		/// </summary>
-		/// <param name="writer"></param>
-		public SummaryDataContainer(ISummaryWriter writer)
-		{
-			_sumWriter = writer;
-
-			Table = new DataTable();
-
-			Table.Columns.AddRange(new[] {
-				Tuple.Create(SORT, typeof(int)),
-				Tuple.Create(JOB, typeof(string)),
-				Tuple.Create(INPUTFILE, typeof(string)),
-				Tuple.Create(CYCLE, typeof(string)),
-				Tuple.Create(STATUS, typeof(string)),
-				Tuple.Create(VEHICLE_MANUFACTURER, typeof(string)),
-				Tuple.Create(VIN_NUMBER, typeof(string)),
-				Tuple.Create(VEHICLE_MODEL, typeof(string)),
-				Tuple.Create(HDV_CO2_VEHICLE_CLASS, typeof(string)),
-				Tuple.Create(CURB_MASS, typeof(SI)),
-				Tuple.Create(LOADING, typeof(SI)),
-				Tuple.Create(TOTAL_VEHICLE_MASS, typeof(SI)),
-				Tuple.Create(ENGINE_MANUFACTURER, typeof(string)),
-				Tuple.Create(ENGINE_MODEL, typeof(string)),
-				Tuple.Create(ENGINE_FUEL_TYPE, typeof(string)),
-				Tuple.Create(ENGINE_RATED_POWER, typeof(SI)),
-				Tuple.Create(ENGINE_IDLING_SPEED, typeof(SI)),
-				Tuple.Create(ENGINE_RATED_SPEED, typeof(SI)),
-				Tuple.Create(ENGINE_DISPLACEMENT, typeof(SI)),
-				Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)),
-				Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)),
-				Tuple.Create(ENGINE_WHTC_MOTORWAY, typeof(double)),
-				Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)),
-				Tuple.Create(ENGINE_CF_REG_PER, typeof(double)),
-				Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)),
-				Tuple.Create(CD_x_A, typeof(SI)),
-				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)),
-				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)),
-				Tuple.Create(R_DYN, typeof(SI)),
-				Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)),
-				Tuple.Create(GEARBOX_MODEL, typeof(string)),
-				Tuple.Create(GEARBOX_TYPE, typeof(string)),
-				Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(SI)),
-				Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(SI)),
-				Tuple.Create(TORQUECONVERTER_MANUFACTURER, typeof(string)),
-				Tuple.Create(TORQUECONVERTER_MODEL, typeof(string)),
-				Tuple.Create(RETARDER_MANUFACTURER, typeof(string)),
-				Tuple.Create(RETARDER_MODEL, typeof(string)),
-				Tuple.Create(RETARDER_TYPE, typeof(string)),
-				Tuple.Create(ANGLEDRIVE_MANUFACTURER, typeof(string)),
-				Tuple.Create(ANGLEDRIVE_MODEL, typeof(string)),
-				Tuple.Create(ANGLEDRIVE_RATIO, typeof(string)),
-				Tuple.Create(AXLE_MANUFACTURER, typeof(string)),
-				Tuple.Create(AXLE_MODEL, typeof(string)),
-				Tuple.Create(AXLE_RATIO, typeof(SI)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.SteeringPump), typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.Fan), typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition),
-					typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.PneumaticSystem), typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.ElectricSystem), typeof(string)),
-			}.Select(x => new DataColumn(x.Item1, x.Item2)).ToArray());
-
-			Table.Columns.AddRange(new[] {
-				CARGO_VOLUME,
-				TIME, DISTANCE,
-				SPEED, ALTITUDE_DELTA,
-				FCMAP_H, FCMAP_KM,
-				FCAUXC_H, FCAUXC_KM,
-				FCWHTCC_H, FCWHTCC_KM,
-				FCAAUX_H, FCAAUX_KM,
-				FCFINAL_H, FCFINAL_KM,
-				FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, FCFINAL_LiterPer100M3KM,
-				CO2_KM, CO2_TKM, CO2_M3KM,
-				P_WHEEL_POS, P_FCMAP_POS,
-				E_FCMAP_POS, E_FCMAP_NEG, E_POWERTRAIN_INERTIA,
-				E_AUX, E_CLUTCH_LOSS, E_TC_LOSS, E_SHIFT_LOSS, E_GBX_LOSS,
-				E_RET_LOSS, E_ANGLE_LOSS, E_AXL_LOSS, E_BRAKE, E_VEHICLE_INERTIA, E_AIR, E_ROLL, E_GRAD,
-				ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, STOP_TIMESHARE,
-				MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS,
-				ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE
-			}.Select(x => new DataColumn(x, typeof(SI))).ToArray());
-		}
-
-		/// <summary>
-		/// Finishes the summary data container (writes the data to the sumWriter).
-		/// </summary>
-		public virtual void Finish()
-		{
-			if (_sumWriter != null) {
-				var view = new DataView(Table, "", SORT, DataViewRowState.CurrentRows).ToTable();
-				var toRemove =
-					view.Columns.Cast<DataColumn>().Where(column => column.ColumnName.StartsWith(INTERNAL_PREFIX)).ToList();
-				foreach (var dataColumn in toRemove) {
-					view.Columns.Remove(dataColumn);
-				}
-				_sumWriter.WriteSumData(view);
-			}
-		}
-
-		/// <summary>
-		/// Writes the result of one run into the summary data container.
-		/// </summary>
-		[MethodImpl(MethodImplOptions.Synchronized)]
-		//public virtual void Write(IModalDataContainer modData, string jobFileName, string jobName, string cycleFileName,
-		//	Kilogram vehicleMass, Kilogram vehicleLoading, CubicMeter cargoVolume, uint gearCount)
-		public virtual void Write(IModalDataContainer modData, int jobNr, int runNr, VectoRunData runData)
-		{
-			var row = Table.NewRow();
-			Table.Rows.Add(row);
-
-			row[SORT] = jobNr * 1000 + runNr;
-			row[JOB] = string.Format("{0}-{1}", jobNr, runNr); //ReplaceNotAllowedCharacters(current);
-			row[INPUTFILE] = ReplaceNotAllowedCharacters(runData.JobName);
-			row[CYCLE] = ReplaceNotAllowedCharacters(runData.Cycle.Name + Constants.FileExtensions.CycleFile);
-
-			row[STATUS] = modData.RunStatus;
-
-			var vehicleLoading = 0.SI<Kilogram>();
-			var cargoVolume = 0.SI<CubicMeter>();
-			var gearCount = 0u;
-			if (runData.Cycle.CycleType != CycleType.EngineOnly) {
+using System;
+using System.Data;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+
+// ReSharper disable MemberCanBePrivate.Global  -- used by API!
+
+namespace TUGraz.VectoCore.OutputData
+{
+	public delegate void WriteSumData(IModalDataContainer data);
+
+	/// <summary>
+	/// Class for the sum file in vecto.
+	/// </summary>
+	public class SummaryDataContainer : LoggingObject, IDisposable
+	{
+		// ReSharper disable InconsistentNaming
+		public const string INTERNAL_PREFIX = "INTERNAL";
+		public const string SORT = INTERNAL_PREFIX + " Sorting";
+		public const string JOB = "Job [-]";
+		public const string INPUTFILE = "Input File [-]";
+		public const string CYCLE = "Cycle [-]";
+		public const string STATUS = "Status";
+		public const string CURB_MASS = "Chassis curb mass [kg]";
+		public const string LOADING = "Loading [kg]";
+
+		public const string VEHICLE_MANUFACTURER = "Vehicle manufacturer [-]";
+		public const string VIN_NUMBER = "VIN number";
+		public const string VEHICLE_MODEL = "Vehicle model [-]";
+
+		public const string ENGINE_MANUFACTURER = "Engine manufacturer [-]";
+		public const string ENGINE_MODEL = "Engine model [-]";
+		public const string ENGINE_FUEL_TYPE = "Engine fuel type [-]";
+		public const string ENGINE_WHTC_URBAN = "Engine WHTCUrban";
+		public const string ENGINE_WHTC_RURAL = "Engine WHTCRural";
+		public const string ENGINE_WHTC_MOTORWAY = "Engine WHTCMotorway";
+		public const string ENGINE_BF_COLD_HOT = "Engine BFColdHot";
+		public const string ENGINE_CF_REG_PER = "Engine CFRegPer";
+		public const string ENGINE_ACTUAL_CORRECTION_FACTOR = "Engine actual CF";
+		public const string ENGINE_RATED_POWER = "Engine rated power [kW]";
+		public const string ENGINE_IDLING_SPEED = "Engine idling speed [rpm]";
+		public const string ENGINE_RATED_SPEED = "Engine rated speed [rpm]";
+		public const string ENGINE_DISPLACEMENT = "Engine displacement [ccm]";
+
+		public const string ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER = "total RRC [-]";
+		public const string ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER = "weighted RRC w/o trailer [-]";
+
+		public const string GEARBOX_MANUFACTURER = "Gearbox manufacturer [-]";
+		public const string GEARBOX_MODEL = "Gearbox model [-]";
+		public const string GEARBOX_TYPE = "Gearbox type [-]";
+		public const string GEAR_RATIO_FIRST_GEAR = "Gear ratio first gear [-]";
+		public const string GEAR_RATIO_LAST_GEAR = "Gear ratio last gear [-]";
+
+		public const string TORQUECONVERTER_MANUFACTURER = "Torque converter manufacturer [-]";
+		public const string TORQUECONVERTER_MODEL = "Torque converter model [-]";
+
+		public const string RETARDER_MANUFACTURER = "Retarder manufacturer [-]";
+		public const string RETARDER_MODEL = "Retarder model [-]";
+		public const string RETARDER_TYPE = "Retarder type [-]";
+
+		public const string ANGLEDRIVE_MANUFACTURER = "Angledrive manufacturer [-]";
+		public const string ANGLEDRIVE_MODEL = "Angledrive model [-]";
+		public const string ANGLEDRIVE_RATIO = "Angledrive ratio [-]";
+
+		public const string AXLE_MANUFACTURER = "Axle manufacturer [-]";
+		public const string AXLE_MODEL = "Axle model [-]";
+		public const string AXLE_RATIO = "Axle gear ratio [-]";
+
+		public const string AUX_TECH_FORMAT = "Auxiliary technology {0} [-]";
+
+		public const string HDV_CO2_VEHICLE_CLASS = "HDV CO2 vehicle class [-]";
+		public const string TOTAL_VEHICLE_MASS = "Total vehicle mass [kg]";
+		public const string CD_x_A = "CdxA [m²]";
+		//public const string ROLLING_RESISTANCE_COEFFICIENT = "weighed RRC [-]";
+		public const string R_DYN = "r_dyn [m]";
+
+		public const string CARGO_VOLUME = "Cargo Volume [m³]";
+		public const string TIME = "time [s]";
+		public const string DISTANCE = "distance [km]";
+		public const string SPEED = "speed [km/h]";
+		public const string ALTITUDE_DELTA = "altitudeDelta [m]";
+
+		public const string FCMAP_H = "FC-Map [g/h]";
+		public const string FCMAP_KM = "FC-Map [g/km]";
+		public const string FCAUXC_H = "FC-AUXc [g/h]";
+		public const string FCAUXC_KM = "FC-AUXc [g/km]";
+		public const string FCWHTCC_H = "FC-WHTCc [g/h]";
+		public const string FCWHTCC_KM = "FC-WHTCc [g/km]";
+		public const string FCAAUX_H = "FC-AAUX [g/h]";
+		public const string FCAAUX_KM = "FC-AAUX [g/km]";
+
+		public const string FCFINAL_H = "FC-Final [g/h]";
+		public const string FCFINAL_KM = "FC-Final [g/km]";
+		public const string FCFINAL_LITERPER100KM = "FC-Final [l/100km]";
+		public const string FCFINAL_LITERPER100TKM = "FC-Final [l/100tkm]";
+		public const string FCFINAL_LiterPer100M3KM = "FC-Final [l/100m³km]";
+
+		public const string CO2_KM = "CO2 [g/km]";
+		public const string CO2_TKM = "CO2 [g/tkm]";
+		public const string CO2_M3KM = "CO2 [g/m³km]";
+
+		public const string P_WHEEL_POS = "P_wheel_in_pos [kW]";
+		public const string P_FCMAP_POS = "P_fcmap_pos [kW]";
+
+		public const string E_FORMAT = "E_{0} [kWh]";
+		public const string E_AUX_FORMAT = "E_aux_{0} [kWh]";
+		public const string E_AUX = "E_aux_sum [kWh]";
+
+		public const string E_AIR = "E_air [kWh]";
+		public const string E_ROLL = "E_roll [kWh]";
+		public const string E_GRAD = "E_grad [kWh]";
+		public const string E_VEHICLE_INERTIA = "E_vehi_inertia [kWh]";
+		public const string E_POWERTRAIN_INERTIA = "E_powertrain_inertia [kWh]";
+		public const string E_BRAKE = "E_brake [kWh]";
+		public const string E_GBX_LOSS = "E_gbx_loss [kWh]";
+		public const string E_SHIFT_LOSS = "E_shift_loss [kWh]";
+		public const string E_AXL_LOSS = "E_axl_loss [kWh]";
+		public const string E_RET_LOSS = "E_ret_loss [kWh]";
+		public const string E_TC_LOSS = "E_tc_loss [kWh]";
+		public const string E_ANGLE_LOSS = "E_angle_loss [kWh]";
+		public const string E_CLUTCH_LOSS = "E_clutch_loss [kWh]";
+		public const string E_FCMAP_POS = "E_fcmap_pos [kWh]";
+		public const string E_FCMAP_NEG = "E_fcmap_neg [kWh]";
+
+		public const string ACC = "a [m/s^2]";
+		public const string ACC_POS = "a_pos [m/s^2]";
+		public const string ACC_NEG = "a_neg [m/s^2]";
+
+		public const string ACC_TIMESHARE = "AccelerationTimeShare [%]";
+		public const string DEC_TIMESHARE = "DecelerationTimeShare [%]";
+		public const string CRUISE_TIMESHARE = "CruiseTimeShare [%]";
+		public const string STOP_TIMESHARE = "StopTimeShare [%]";
+
+		public const string MAX_SPEED = "max. speed [km/h";
+		public const string MAX_ACCELERATION = "max. acc [m/s²]";
+		public const string MAX_DECELERATION = "max. dec [m/s²]";
+		public const string AVG_ENGINE_SPEED = "n_eng_avg [rpm]";
+		public const string MAX_ENGINE_SPEED = "n_eng_max [rpm]";
+		public const string NUM_GEARSHIFTS = "gear shifts [-]";
+		public const string ENGINE_FULL_LOAD_TIME_SHARE = "Engine max. Load time share [%]";
+		public const string COASTING_TIME_SHARE = "CoastingTimeShare [%]";
+		public const string BRAKING_TIME_SHARE = "BrakingTImeShare [%]";
+
+		public const string TIME_SHARE_PER_GEAR_FORMAT = "Gear {0} TimeShare [%]";
+
+		// ReSharper restore InconsistentNaming
+
+		internal readonly DataTable Table;
+		private readonly ISummaryWriter _sumWriter;
+
+
+		protected SummaryDataContainer() {}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="SummaryDataContainer"/> class.
+		/// </summary>
+		/// <param name="writer"></param>
+		public SummaryDataContainer(ISummaryWriter writer)
+		{
+			_sumWriter = writer;
+
+			Table = new DataTable();
+
+			Table.Columns.AddRange(new[] {
+				Tuple.Create(SORT, typeof(int)),
+				Tuple.Create(JOB, typeof(string)),
+				Tuple.Create(INPUTFILE, typeof(string)),
+				Tuple.Create(CYCLE, typeof(string)),
+				Tuple.Create(STATUS, typeof(string)),
+				Tuple.Create(VEHICLE_MANUFACTURER, typeof(string)),
+				Tuple.Create(VIN_NUMBER, typeof(string)),
+				Tuple.Create(VEHICLE_MODEL, typeof(string)),
+				Tuple.Create(HDV_CO2_VEHICLE_CLASS, typeof(string)),
+				Tuple.Create(CURB_MASS, typeof(SI)),
+				Tuple.Create(LOADING, typeof(SI)),
+				Tuple.Create(TOTAL_VEHICLE_MASS, typeof(SI)),
+				Tuple.Create(ENGINE_MANUFACTURER, typeof(string)),
+				Tuple.Create(ENGINE_MODEL, typeof(string)),
+				Tuple.Create(ENGINE_FUEL_TYPE, typeof(string)),
+				Tuple.Create(ENGINE_RATED_POWER, typeof(SI)),
+				Tuple.Create(ENGINE_IDLING_SPEED, typeof(SI)),
+				Tuple.Create(ENGINE_RATED_SPEED, typeof(SI)),
+				Tuple.Create(ENGINE_DISPLACEMENT, typeof(SI)),
+				Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)),
+				Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)),
+				Tuple.Create(ENGINE_WHTC_MOTORWAY, typeof(double)),
+				Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)),
+				Tuple.Create(ENGINE_CF_REG_PER, typeof(double)),
+				Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)),
+				Tuple.Create(CD_x_A, typeof(SI)),
+				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)),
+				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)),
+				Tuple.Create(R_DYN, typeof(SI)),
+				Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)),
+				Tuple.Create(GEARBOX_MODEL, typeof(string)),
+				Tuple.Create(GEARBOX_TYPE, typeof(string)),
+				Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(SI)),
+				Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(SI)),
+				Tuple.Create(TORQUECONVERTER_MANUFACTURER, typeof(string)),
+				Tuple.Create(TORQUECONVERTER_MODEL, typeof(string)),
+				Tuple.Create(RETARDER_MANUFACTURER, typeof(string)),
+				Tuple.Create(RETARDER_MODEL, typeof(string)),
+				Tuple.Create(RETARDER_TYPE, typeof(string)),
+				Tuple.Create(ANGLEDRIVE_MANUFACTURER, typeof(string)),
+				Tuple.Create(ANGLEDRIVE_MODEL, typeof(string)),
+				Tuple.Create(ANGLEDRIVE_RATIO, typeof(string)),
+				Tuple.Create(AXLE_MANUFACTURER, typeof(string)),
+				Tuple.Create(AXLE_MODEL, typeof(string)),
+				Tuple.Create(AXLE_RATIO, typeof(SI)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.SteeringPump), typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.Fan), typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition),
+					typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.PneumaticSystem), typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.ElectricSystem), typeof(string)),
+			}.Select(x => new DataColumn(x.Item1, x.Item2)).ToArray());
+
+			Table.Columns.AddRange(new[] {
+				CARGO_VOLUME,
+				TIME, DISTANCE,
+				SPEED, ALTITUDE_DELTA,
+				FCMAP_H, FCMAP_KM,
+				FCAUXC_H, FCAUXC_KM,
+				FCWHTCC_H, FCWHTCC_KM,
+				FCAAUX_H, FCAAUX_KM,
+				FCFINAL_H, FCFINAL_KM,
+				FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, FCFINAL_LiterPer100M3KM,
+				CO2_KM, CO2_TKM, CO2_M3KM,
+				P_WHEEL_POS, P_FCMAP_POS,
+				E_FCMAP_POS, E_FCMAP_NEG, E_POWERTRAIN_INERTIA,
+				E_AUX, E_CLUTCH_LOSS, E_TC_LOSS, E_SHIFT_LOSS, E_GBX_LOSS,
+				E_RET_LOSS, E_ANGLE_LOSS, E_AXL_LOSS, E_BRAKE, E_VEHICLE_INERTIA, E_AIR, E_ROLL, E_GRAD,
+				ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, STOP_TIMESHARE,
+				MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS,
+				ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE
+			}.Select(x => new DataColumn(x, typeof(SI))).ToArray());
+		}
+
+		/// <summary>
+		/// Finishes the summary data container (writes the data to the sumWriter).
+		/// </summary>
+		public virtual void Finish()
+		{
+			if (_sumWriter != null) {
+				var view = new DataView(Table, "", SORT, DataViewRowState.CurrentRows).ToTable();
+				var toRemove =
+					view.Columns.Cast<DataColumn>().Where(column => column.ColumnName.StartsWith(INTERNAL_PREFIX)).ToList();
+				foreach (var dataColumn in toRemove) {
+					view.Columns.Remove(dataColumn);
+				}
+				_sumWriter.WriteSumData(view);
+			}
+		}
+
+		/// <summary>
+		/// Writes the result of one run into the summary data container.
+		/// </summary>
+		[MethodImpl(MethodImplOptions.Synchronized)]
+		//public virtual void Write(IModalDataContainer modData, string jobFileName, string jobName, string cycleFileName,
+		//	Kilogram vehicleMass, Kilogram vehicleLoading, CubicMeter cargoVolume, uint gearCount)
+		public virtual void Write(IModalDataContainer modData, int jobNr, int runNr, VectoRunData runData)
+		{
+			var row = Table.NewRow();
+			Table.Rows.Add(row);
+
+			row[SORT] = jobNr * 1000 + runNr;
+			row[JOB] = string.Format("{0}-{1}", jobNr, runNr); //ReplaceNotAllowedCharacters(current);
+			row[INPUTFILE] = ReplaceNotAllowedCharacters(runData.JobName);
+			row[CYCLE] = ReplaceNotAllowedCharacters(runData.Cycle.Name + Constants.FileExtensions.CycleFile);
+
+			row[STATUS] = modData.RunStatus;
+
+			var vehicleLoading = 0.SI<Kilogram>();
+			var cargoVolume = 0.SI<CubicMeter>();
+			var gearCount = 0u;
+			if (runData.Cycle.CycleType != CycleType.EngineOnly) {
 				WriteFullPowertrain(runData, row);
 
-				cargoVolume = runData.VehicleData.CargoVolume;
-				vehicleLoading = runData.VehicleData.Loading;
-				gearCount = (uint)runData.GearboxData.Gears.Count;
-			}
-
-
-			var totalTime = modData.Duration();
-			row[TIME] = totalTime;
-
-			var distance = modData.Distance();
-			if (distance != null) {
-				row[DISTANCE] = distance.ConvertTo().Kilo.Meter;
-			}
-
-			var speed = modData.Speed();
-			if (speed != null) {
-				row[SPEED] = speed.ConvertTo().Kilo.Meter.Per.Hour;
-			}
-
+				cargoVolume = runData.VehicleData.CargoVolume;
+				vehicleLoading = runData.VehicleData.Loading;
+				gearCount = (uint)runData.GearboxData.Gears.Count;
+			}
+
+
+			var totalTime = modData.Duration();
+			row[TIME] = totalTime;
+
+			var distance = modData.Distance();
+			if (distance != null) {
+				row[DISTANCE] = distance.ConvertTo().Kilo.Meter;
+			}
+
+			var speed = modData.Speed();
+			if (speed != null) {
+				row[SPEED] = speed.ConvertTo().Kilo.Meter.Per.Hour;
+			}
+
 			row[ALTITUDE_DELTA] = modData.AltitudeDelta();
 
 			WriteFuelconsumptionEntries(modData, row, vehicleLoading, cargoVolume);
 
-			var kilogramPerMeter = modData.CO2PerMeter();
-			if (kilogramPerMeter != null) {
-				row[CO2_KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter;
-				if (vehicleLoading != null && !vehicleLoading.IsEqual(0)) {
-					row[CO2_TKM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton;
-				}
-				if (cargoVolume > 0) {
-					row[CO2_M3KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / cargoVolume;
-				}
-			}
-
-			row[P_WHEEL_POS] = modData.PowerWheelPositive().ConvertTo().Kilo.Watt;
-
-			row[P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertTo().Kilo.Watt;
-
-			WriteAuxiliaries(modData, row);
-
+			var kilogramPerMeter = modData.CO2PerMeter();
+			if (kilogramPerMeter != null) {
+				row[CO2_KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter;
+				if (vehicleLoading != null && !vehicleLoading.IsEqual(0)) {
+					row[CO2_TKM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton;
+				}
+				if (cargoVolume > 0) {
+					row[CO2_M3KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / cargoVolume;
+				}
+			}
+
+			row[P_WHEEL_POS] = modData.PowerWheelPositive().ConvertTo().Kilo.Watt;
+
+			row[P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertTo().Kilo.Watt;
+
+			WriteAuxiliaries(modData, row);
+
 			WriteWorkEntries(modData, row);
 
-			//var acc = modData.AccelerationPer3Seconds();
-
-
 			WritePerformanceEntries(modData, row);
 
-			row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare();
-			row[COASTING_TIME_SHARE] = modData.CoastingTimeShare();
-			row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare();
-
-
-			if (gearCount <= 0) {
-				return;
-			}
-
+			row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare();
+			row[COASTING_TIME_SHARE] = modData.CoastingTimeShare();
+			row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare();
+
+			if (gearCount <= 0) {
+				return;
+			}
+
 			WriteGearshiftStats(modData, row, gearCount);
 		}
 
@@ -383,27 +379,19 @@ namespace TUGraz.VectoCore.OutputData
 
 			row[FCAUXC_H] = modData.FuelConsumptionAuxStartStopPerSecond().ConvertTo().Gramm.Per.Hour;
 			var fuelConsumptionAuxStartStopCorrected = modData.FuelConsumptionAuxStartStop();
-			if (fuelConsumptionAuxStartStopCorrected != null) {
-				row[FCAUXC_KM] = fuelConsumptionAuxStartStopCorrected.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
+			row[FCAUXC_KM] = FuelConsumptionAsGrammPerKiloMeter(fuelConsumptionAuxStartStopCorrected);
 
 			row[FCWHTCC_H] = modData.FuelConsumptionWHTCPerSecond().ConvertTo().Gramm.Per.Hour;
 			var fuelConsumptionWHTCCorrected = modData.FuelConsumptionWHTC();
-			if (fuelConsumptionWHTCCorrected != null) {
-				row[FCWHTCC_KM] = fuelConsumptionWHTCCorrected.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
+			row[FCWHTCC_KM] = FuelConsumptionAsGrammPerKiloMeter(fuelConsumptionWHTCCorrected);
 
 			row[FCAAUX_H] = modData.FuelConsumptionAAUXPerSecond().ConvertTo().Gramm.Per.Hour;
 			var fuelConsumptionAaux = modData.FuelConsumptionAAUX();
-			if (fuelConsumptionAaux != null) {
-				row[FCAAUX_KM] = fuelConsumptionAaux.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
+			row[FCAAUX_KM] = FuelConsumptionAsGrammPerKiloMeter(fuelConsumptionAaux);
 
 			row[FCFINAL_H] = modData.FuelConsumptionFinalPerSecond().ConvertTo().Gramm.Per.Hour;
 			var fcfinal = modData.FuelConsumptionFinal();
-			if (fcfinal != null) {
-				row[FCFINAL_KM] = fcfinal.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
+			row[FCFINAL_KM] = FuelConsumptionAsGrammPerKiloMeter(fcfinal);
 
 			var fcPer100lkm = modData.FuelConsumptionFinalLiterPer100Kilometer();
 			row[FCFINAL_LITERPER100KM] = fcPer100lkm;
@@ -416,6 +404,14 @@ namespace TUGraz.VectoCore.OutputData
 			}
 		}
 
+		private static SI FuelConsumptionAsGrammPerKiloMeter(SI fc)
+		{
+			if (fc == null) {
+				return null;
+			}
+			return fc.ConvertTo().Gramm.Per.Kilo.Meter;
+		}
+
 		private void WriteAuxiliaries(IModalDataContainer modData, DataRow row)
 		{
 			foreach (var aux in modData.Auxiliaries) {
@@ -545,6 +541,64 @@ namespace TUGraz.VectoCore.OutputData
 			row[GEARBOX_MANUFACTURER] = runData.GearboxData.Manufacturer;
 			row[GEARBOX_MODEL] = runData.GearboxData.ModelName;
 			row[GEARBOX_TYPE] = runData.GearboxData.Type;
+			WriteGearboxData(runData, row);
+
+			row[RETARDER_TYPE] = runData.Retarder.Type.GetLabel();
+			WriteRetarderData(runData, row);
+
+			WriteAngledriveData(runData, row);
+
+			row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer;
+			row[AXLE_MODEL] = runData.AxleGearData.ModelName;
+			row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>();
+
+			WriteAuxTechnologies(runData, row);
+		}
+
+		private void WriteAuxTechnologies(VectoRunData runData, DataRow row)
+		{
+			foreach (var aux in runData.Aux) {
+				if (aux.ID == Constants.Auxiliaries.IDs.PTOConsumer || aux.ID == Constants.Auxiliaries.IDs.PTOTransmission) {
+					continue;
+				}
+				var colName = string.Format(AUX_TECH_FORMAT, aux.ID);
+
+				if (!Table.Columns.Contains(colName)) {
+					var col = Table.Columns.Add(colName, typeof(string));
+					// move the new column to correct position
+					col.SetOrdinal(Table.Columns[CARGO_VOLUME].Ordinal);
+				}
+
+				row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology);
+			}
+		}
+
+		private static void WriteAngledriveData(VectoRunData runData, DataRow row)
+		{
+			if (runData.AngledriveData != null) {
+				row[ANGLEDRIVE_MANUFACTURER] = runData.AngledriveData.Manufacturer;
+				row[ANGLEDRIVE_MODEL] = runData.AngledriveData.ModelName;
+				row[ANGLEDRIVE_RATIO] = runData.AngledriveData.Angledrive.Ratio;
+			} else {
+				row[ANGLEDRIVE_MANUFACTURER] = "n.a.";
+				row[ANGLEDRIVE_MODEL] = "n.a.";
+				row[ANGLEDRIVE_RATIO] = "n.a.";
+			}
+		}
+
+		private static void WriteRetarderData(VectoRunData runData, DataRow row)
+		{
+			if (runData.Retarder.Type.IsDedicatedComponent()) {
+				row[RETARDER_MANUFACTURER] = runData.Retarder.Manufacturer;
+				row[RETARDER_MODEL] = runData.Retarder.ModelName;
+			} else {
+				row[RETARDER_MANUFACTURER] = "n.a.";
+				row[RETARDER_MODEL] = "n.a.";
+			}
+		}
+
+		private static void WriteGearboxData(VectoRunData runData, DataRow row)
+		{
 			if (runData.GearboxData.Type.AutomaticTransmission()) {
 				row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
 					? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio)
@@ -566,61 +620,24 @@ namespace TUGraz.VectoCore.OutputData
 				row[TORQUECONVERTER_MANUFACTURER] = "n.a.";
 				row[TORQUECONVERTER_MODEL] = "n.a.";
 			}
-			row[RETARDER_TYPE] = runData.Retarder.Type.GetLabel();
-			if (runData.Retarder.Type.IsDedicatedComponent()) {
-				row[RETARDER_MANUFACTURER] = runData.Retarder.Manufacturer;
-				row[RETARDER_MODEL] = runData.Retarder.ModelName;
-			} else {
-				row[RETARDER_MANUFACTURER] = "n.a.";
-				row[RETARDER_MODEL] = "n.a.";
-			}
-
-			if (runData.AngledriveData != null) {
-				row[ANGLEDRIVE_MANUFACTURER] = runData.AngledriveData.Manufacturer;
-				row[ANGLEDRIVE_MODEL] = runData.AngledriveData.ModelName;
-				row[ANGLEDRIVE_RATIO] = runData.AngledriveData.Angledrive.Ratio;
-			} else {
-				row[ANGLEDRIVE_MANUFACTURER] = "n.a.";
-				row[ANGLEDRIVE_MODEL] = "n.a.";
-				row[ANGLEDRIVE_RATIO] = "n.a.";
-			}
-
-			row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer;
-			row[AXLE_MODEL] = runData.AxleGearData.ModelName;
-			row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>();
+		}
 
-			foreach (var aux in runData.Aux) {
-				if (aux.ID == Constants.Auxiliaries.IDs.PTOConsumer || aux.ID == Constants.Auxiliaries.IDs.PTOTransmission) {
-					continue;
-				}
-				var colName = string.Format(AUX_TECH_FORMAT, aux.ID);
+		private static string ReplaceNotAllowedCharacters(string text)
+		{
+			return text.Replace('#', '_').Replace(',', '_').Replace('\n', '_').Replace('\r', '_');
+		}
 
-				if (!Table.Columns.Contains(colName)) {
-					var col = Table.Columns.Add(colName, typeof(string));
-					// move the new column to correct position
-					col.SetOrdinal(Table.Columns[CARGO_VOLUME].Ordinal);
-				}
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
 
-				row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology);
+		protected void Dispose(bool disposing)
+		{
+			if (disposing) {
+				Table.Dispose();
 			}
 		}
-
-		private static string ReplaceNotAllowedCharacters(string text)
-		{
-			return text.Replace('#', '_').Replace(',', '_').Replace('\n', '_').Replace('\r', '_');
-		}
-
-		public void Dispose()
-		{
-			Dispose(true);
-			GC.SuppressFinalize(this);
-		}
-
-		protected void Dispose(bool disposing)
-		{
-			if (disposing) {
-				Table.Dispose();
-			}
-		}
-	}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Utils/VectoCSVFile.cs b/VectoCore/VectoCore/Utils/VectoCSVFile.cs
index e904ab0adeb9f252dca49b16d2d47476c175298d..59a24a038afda03cb6240c3b8692e2a6d77d80c5 100644
--- a/VectoCore/VectoCore/Utils/VectoCSVFile.cs
+++ b/VectoCore/VectoCore/Utils/VectoCSVFile.cs
@@ -147,12 +147,8 @@ namespace TUGraz.VectoCore.Utils
 				table.Columns.Add(col);
 			}
 
-			if (p.EndOfData) {
-				return;
-			}
-
 			var lineNumber = 1;
-			do {
+			while (!p.EndOfData) {
 				string[] cells = { };
 				if (firstLineIsData) {
 					cells = colsWithoutComment;
@@ -179,7 +175,7 @@ namespace TUGraz.VectoCore.Utils
 						string.Format("Line {0}: The data format of a value is not correct. {1}", lineNumber, e.Message), e);
 				}
 				lineNumber++;
-			} while (!p.EndOfData);
+			}
 		}
 
 		/// <summary>