diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
index 5af38c58dcdf83cf3998edb8dc7c978e5a7f423b..ab488ae867df7ec8734cc941d4dfe200d29b01fa 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Clutch.cs
@@ -29,145 +29,152 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports;
-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 Clutch : StatefulProviderComponent<Clutch.ClutchState, ITnOutPort, ITnInPort, ITnOutPort>, IClutch,
-		ITnOutPort, ITnInPort
-	{
-		private readonly PerSecond _idleSpeed;
-		private readonly PerSecond _ratedSpeed;
-
-		public IIdleController IdleController {
-			get { return _idleController; }
-			set {
-				_idleController = value;
-				_idleController.RequestPort = NextComponent;
-			}
-		}
-
-		private readonly SI _clutchSpeedSlippingFactor;
-		private IIdleController _idleController;
-
-		public Clutch(IVehicleContainer container, CombustionEngineData engineData) : base(container)
-		{
-			_idleSpeed = engineData.IdleSpeed;
-			_ratedSpeed = engineData.FullLoadCurves[0].RatedSpeed;
-			_clutchSpeedSlippingFactor = Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed) /
-										(_idleSpeed + Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed));
-		}
-
-		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			NewtonMeter torqueIn;
-			PerSecond engineSpeedIn;
-			if (DataBus.DriverBehavior == DrivingBehavior.Halted /*DataBus.VehicleStopped*/) {
-				engineSpeedIn = _idleSpeed;
-				torqueIn = 0.SI<NewtonMeter>();
-			} else {
-				AddClutchLoss(outTorque, outAngularVelocity, true, out torqueIn, out engineSpeedIn);
-			}
-			PreviousState.SetState(torqueIn, outAngularVelocity, outTorque, outAngularVelocity);
-
-			var retVal = NextComponent.Initialize(torqueIn, engineSpeedIn);
-			retVal.ClutchPowerRequest = outTorque * outAngularVelocity;
-			return retVal;
-		}
-
-		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun = false)
-		{
-			var startClutch = DataBus.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0);
-			if (!DataBus.ClutchClosed(absTime) && !dryRun) {
-				Log.Debug("Invoking IdleController...");
-				var retval = IdleController.Request(absTime, dt, outTorque, null, dryRun);
-				retval.ClutchPowerRequest = 0.SI<Watt>();
-				CurrentState.SetState(0.SI<NewtonMeter>(), retval.EngineSpeed, outTorque, outAngularVelocity);
-				CurrentState.ClutchLoss = 0.SI<Watt>();
-				return retval;
-			}
-			if (IdleController != null) {
-				IdleController.Reset();
-			}
-
-			Log.Debug("from Wheels: torque: {0}, angularVelocity: {1}, power {2}", outTorque, outAngularVelocity,
-				Formulas.TorqueToPower(outTorque, outAngularVelocity));
-
-			NewtonMeter torqueIn;
-			PerSecond angularVelocityIn;
-			if (DataBus.DriverBehavior == DrivingBehavior.Halted /*DataBus.VehicleStopped*/) {
-				angularVelocityIn = _idleSpeed;
-				torqueIn = 0.SI<NewtonMeter>();
-			} else {
-				AddClutchLoss(outTorque, outAngularVelocity, (DataBus.Gear == 1 && outTorque > 0) ||startClutch || outAngularVelocity.IsEqual(0), out torqueIn, out angularVelocityIn);
-			}
-			Log.Debug("to Engine:   torque: {0}, angularVelocity: {1}, power {2}", torqueIn, angularVelocityIn,
-				Formulas.TorqueToPower(torqueIn, angularVelocityIn));
-
-			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			var avgInAngularVelocity = (PreviousState.InAngularVelocity + angularVelocityIn) / 2.0;
-			var clutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity;
-			if (!startClutch && !clutchLoss.IsEqual(0)) {
-				// we don't want to have negative clutch losses, so adapt input torque to match the average output power
-				torqueIn = outTorque * avgOutAngularVelocity / avgInAngularVelocity;
-			}
-
-			var retVal = NextComponent.Request(absTime, dt, torqueIn, angularVelocityIn, dryRun);
-			if (!dryRun) {
-				CurrentState.SetState(torqueIn, angularVelocityIn, outTorque, outAngularVelocity);
-				CurrentState.ClutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity;
-			}
-			retVal.ClutchPowerRequest = outTorque *
-										((PreviousState.OutAngularVelocity ?? 0.SI<PerSecond>()) + CurrentState.OutAngularVelocity) / 2.0;
-			return retVal;
-		}
-
-		private void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool startClutch, out NewtonMeter torqueIn, out PerSecond angularVelocityIn)
-		{
-			torqueIn = torque;
-			angularVelocityIn = angularVelocity;
-
-			var engineSpeedNorm = (angularVelocity - _idleSpeed) / (_ratedSpeed - _idleSpeed);
-			if (startClutch && engineSpeedNorm < Constants.SimulationSettings.ClutchClosingSpeedNorm) {
-				// MQ: 27.5.2016: when angularVelocity is 0 (at the end of the simulation interval) don't use the 
-				//     angularVelocity but average angular velocity
-				//     Reason: if angularVelocity = 0 also the power (torque * angularVelocity) is 0 and then
-				//             the torque demand for the engine is 0. no drag torque although vehicle has to decelerate
-				//             "the clutch" eats up the whole torque
-				var engineSpeed = VectoMath.Max(_idleSpeed, angularVelocity);
-
-				angularVelocityIn = _clutchSpeedSlippingFactor * engineSpeed + _idleSpeed;
-				
-			}
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			if (PreviousState.InAngularVelocity == null || CurrentState.InAngularVelocity == null) {
-				container[ModalResultField.P_clutch_out] = 0.SI<Watt>();
-				container[ModalResultField.P_clutch_loss] = 0.SI<Watt>();
-			} else {
-				var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
-				var avgInAngularVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
-				container[ModalResultField.P_clutch_out] = CurrentState.OutTorque * avgOutAngularVelocity;
-				container[ModalResultField.P_clutch_loss] = CurrentState.InTorque * avgInAngularVelocity -
-															CurrentState.OutTorque * avgOutAngularVelocity;
-			}
-		}
-
-		public class ClutchState : SimpleComponentState
-		{
-			public Watt ClutchLoss = 0.SI<Watt>();
-		}
-	}
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
+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 Clutch : StatefulProviderComponent<Clutch.ClutchState, ITnOutPort, ITnInPort, ITnOutPort>, IClutch,
+		ITnOutPort, ITnInPort
+	{
+		private readonly PerSecond _idleSpeed;
+		private readonly PerSecond _ratedSpeed;
+
+		public IIdleController IdleController
+		{
+			get { return _idleController; }
+			set
+			{
+				_idleController = value;
+				_idleController.RequestPort = NextComponent;
+			}
+		}
+
+		private readonly SI _clutchSpeedSlippingFactor;
+		private IIdleController _idleController;
+
+		public Clutch(IVehicleContainer container, CombustionEngineData engineData) : base(container)
+		{
+			_idleSpeed = engineData.IdleSpeed;
+			_ratedSpeed = engineData.FullLoadCurves[0].RatedSpeed;
+			_clutchSpeedSlippingFactor = Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed) /
+										(_idleSpeed + Constants.SimulationSettings.ClutchClosingSpeedNorm * (_ratedSpeed - _idleSpeed));
+		}
+
+		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			NewtonMeter torqueIn;
+			PerSecond engineSpeedIn;
+			if (DataBus.DriverBehavior == DrivingBehavior.Halted /*DataBus.VehicleStopped*/) {
+				engineSpeedIn = _idleSpeed;
+				torqueIn = 0.SI<NewtonMeter>();
+			} else {
+				AddClutchLoss(outTorque, outAngularVelocity, true, out torqueIn, out engineSpeedIn);
+			}
+			PreviousState.SetState(torqueIn, outAngularVelocity, outTorque, outAngularVelocity);
+
+			var retVal = NextComponent.Initialize(torqueIn, engineSpeedIn);
+			retVal.ClutchPowerRequest = outTorque * outAngularVelocity;
+			return retVal;
+		}
+
+		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun = false)
+		{
+			var startClutch = DataBus.VehicleStopped || !PreviousState.ClutchLoss.IsEqual(0);
+			if (!DataBus.ClutchClosed(absTime) && !dryRun) {
+				Log.Debug("Invoking IdleController...");
+				var retval = IdleController.Request(absTime, dt, outTorque, null, dryRun);
+				retval.ClutchPowerRequest = 0.SI<Watt>();
+				CurrentState.SetState(0.SI<NewtonMeter>(), retval.EngineSpeed, outTorque, outAngularVelocity);
+				CurrentState.ClutchLoss = 0.SI<Watt>();
+				return retval;
+			}
+			if (IdleController != null) {
+				IdleController.Reset();
+			}
+
+			Log.Debug("from Wheels: torque: {0}, angularVelocity: {1}, power {2}", outTorque, outAngularVelocity,
+				Formulas.TorqueToPower(outTorque, outAngularVelocity));
+
+			NewtonMeter torqueIn;
+			PerSecond angularVelocityIn;
+
+			AddClutchLoss(outTorque, outAngularVelocity,
+				(DataBus.Gear == 1 && outTorque > 0) || startClutch || outAngularVelocity.IsEqual(0), out torqueIn,
+				out angularVelocityIn);
+
+			Log.Debug("to Engine:   torque: {0}, angularVelocity: {1}, power {2}", torqueIn, angularVelocityIn,
+				Formulas.TorqueToPower(torqueIn, angularVelocityIn));
+
+			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			var avgInAngularVelocity = (PreviousState.InAngularVelocity + angularVelocityIn) / 2.0;
+			var clutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity;
+			if (!startClutch && !clutchLoss.IsEqual(0)) {
+				// we don't want to have negative clutch losses, so adapt input torque to match the average output power
+				torqueIn = outTorque * avgOutAngularVelocity / avgInAngularVelocity;
+			}
+
+			var retVal = NextComponent.Request(absTime, dt, torqueIn, angularVelocityIn, dryRun);
+			if (!dryRun) {
+				CurrentState.SetState(torqueIn, angularVelocityIn, outTorque, outAngularVelocity);
+				CurrentState.ClutchLoss = torqueIn * avgInAngularVelocity - outTorque * avgOutAngularVelocity;
+			}
+			retVal.ClutchPowerRequest = outTorque *
+										((PreviousState.OutAngularVelocity ?? 0.SI<PerSecond>()) + CurrentState.OutAngularVelocity) / 2.0;
+			return retVal;
+		}
+
+		private void AddClutchLoss(NewtonMeter torque, PerSecond angularVelocity, bool startClutch, out NewtonMeter torqueIn,
+			out PerSecond angularVelocityIn)
+		{
+			if (DataBus.DriverBehavior == DrivingBehavior.Halted) {
+				angularVelocityIn = _idleSpeed;
+				torqueIn = 0.SI<NewtonMeter>();
+				return;
+			}
+
+			torqueIn = torque;
+			angularVelocityIn = angularVelocity;
+
+			var engineSpeedNorm = (angularVelocity - _idleSpeed) / (_ratedSpeed - _idleSpeed);
+			if (startClutch && engineSpeedNorm < Constants.SimulationSettings.ClutchClosingSpeedNorm) {
+				// MQ: 27.5.2016: when angularVelocity is 0 (at the end of the simulation interval) don't use the 
+				//     angularVelocity but average angular velocity
+				//     Reason: if angularVelocity = 0 also the power (torque * angularVelocity) is 0 and then
+				//             the torque demand for the engine is 0. no drag torque although vehicle has to decelerate
+				//             "the clutch" eats up the whole torque
+				var engineSpeed = VectoMath.Max(_idleSpeed, angularVelocity);
+
+				angularVelocityIn = _clutchSpeedSlippingFactor * engineSpeed + _idleSpeed;
+			}
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			if (PreviousState.InAngularVelocity == null || CurrentState.InAngularVelocity == null) {
+				container[ModalResultField.P_clutch_out] = 0.SI<Watt>();
+				container[ModalResultField.P_clutch_loss] = 0.SI<Watt>();
+			} else {
+				var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
+				var avgInAngularVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
+				container[ModalResultField.P_clutch_out] = CurrentState.OutTorque * avgOutAngularVelocity;
+				container[ModalResultField.P_clutch_loss] = CurrentState.InTorque * avgInAngularVelocity -
+															CurrentState.OutTorque * avgOutAngularVelocity;
+			}
+		}
+
+		public class ClutchState : SimpleComponentState
+		{
+			public Watt ClutchLoss = 0.SI<Watt>();
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
index 4321fb273c867e832cbabb552e6afae6bf8311d9..1267b16fe0557d1db55ee07a9d7bd6f841bd12c3 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
@@ -175,9 +175,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				// if the clutch disengages the idle controller should take over!
 				throw new VectoSimulationException("angular velocity is null! Clutch open without IdleController?");
 			}
-			if (angularVelocity < ModelData.IdleSpeed.Value() - EngineIdleSpeedStopThreshold) {
-				CurrentState.OperationMode = EngineOperationMode.Stopped;
-			}
+			//if (angularVelocity < ModelData.IdleSpeed.Value() - EngineIdleSpeedStopThreshold) {
+			//	CurrentState.OperationMode = EngineOperationMode.Stopped;
+			//}
 
 			var avgEngineSpeed = (PreviousState.EngineSpeed + angularVelocity) / 2.0;
 
@@ -192,9 +192,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			var fullDragTorque = ModelData.FullLoadCurves[DataBus.Gear].DragLoadStationaryTorque(avgEngineSpeed);
 			var dynamicFullLoadPower = ComputeFullLoadPower(avgEngineSpeed, dt, dryRun);
-			if (dynamicFullLoadPower < 0) {
-				dynamicFullLoadPower = 0.SI<Watt>();
-			}
+
 			var dynamicFullLoadTorque = dynamicFullLoadPower / avgEngineSpeed;
 			var inertiaTorqueLoss =
 				Formulas.InertiaPower(angularVelocity, PreviousState.EngineSpeed, ModelData.Inertia, dt) /
@@ -460,6 +458,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				dynFullPowerCalculated = stationaryFullLoadPower;
 			}
 
+			if (dynFullPowerCalculated < 0) {
+				return 0.SI<Watt>();
+			}
 			return dynFullPowerCalculated;
 		}
 
@@ -590,7 +591,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 						angularSpeed = angularSpeed.LimitTo(_engine.ModelData.IdleSpeed, _engine.EngineRatedSpeed);
 						retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed);
 					}).
-					Default(r => { throw new UnexpectedResponseException("searching Idling point", r); });
+					Default(r => {
+						throw new UnexpectedResponseException("searching Idling point", r);
+					});
 
 				return retVal;
 			}
@@ -647,7 +650,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 							0.SI<NewtonMeter>(), angularSpeed);
 						retVal = RequestPort.Request(absTime, dt, 0.SI<NewtonMeter>(), angularSpeed);
 					}).
-					Default(r => { throw new UnexpectedResponseException("searching Idling point", r); });
+					Default(r => {
+						throw new UnexpectedResponseException("searching Idling point", r);
+					});
 
 				return retVal;
 			}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 8ea0d270916aada48966c3ae5065d1389cab16e3..6682c9725aa171e603600d371a8581beb71bbca1 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -29,401 +29,406 @@
 *   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.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class Gearbox : AbstractGearbox<GearboxState>
-	{
-		/// <summary>
-		/// The shift strategy.
-		/// </summary>
-		private readonly IShiftStrategy _strategy;
-
-		/// <summary>
-		/// Time when a gearbox shift engages a new gear (shift is finished). Is set when shifting is needed.
-		/// </summary>
-		private Second _engageTime = 0.SI<Second>();
-
-		/// <summary>
-		/// True if gearbox is disengaged (no gear is set).
-		/// </summary>
-		protected internal bool Disengaged = true;
-
-		public Second LastUpshift { get; protected internal set; }
-
-		public Second LastDownshift { get; protected internal set; }
-
-		public override GearInfo NextGear
-		{
-			get { return _strategy.NextGear; }
-		}
-
-		public override bool ClutchClosed(Second absTime)
-		{
-			return _engageTime.IsSmallerOrEqual(absTime);
-		}
-
-		public Gearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) : base(container, runData)
-		{
-			_strategy = strategy;
-			_strategy.Gearbox = this;
-
-			LastDownshift = -double.MaxValue.SI<Second>();
-			LastUpshift = -double.MaxValue.SI<Second>();
-		}
-
-		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			var absTime = 0.SI<Second>();
-			var dt = Constants.SimulationSettings.TargetTimeInterval;
-
-			_engageTime = -double.MaxValue.SI<Second>();
-
-			if (Disengaged) {
-				Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
-			}
-
-			var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
-			var gearboxTorqueLoss = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
-			CurrentState.TorqueLossResult = gearboxTorqueLoss;
-
-			var inTorque = outTorque / ModelData.Gears[Gear].Ratio
-							+ gearboxTorqueLoss.Value;
-
-			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-			PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>();
-			PreviousState.Gear = Gear;
-			Disengaged = false;
-
-			var response = NextComponent.Initialize(inTorque, inAngularVelocity);
-
-			return response;
-		}
-
-		internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			var oldGear = Gear;
-			Gear = gear;
-			var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio;
-			var torqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
-			CurrentState.TorqueLossResult = torqueLossResult;
-			var inTorque = outTorque / ModelData.Gears[gear].Ratio + torqueLossResult.Value;
-
-			if (!inAngularVelocity.IsEqual(0)) {
-				var alpha = ModelData.Inertia.IsEqual(0)
-					? 0.SI<PerSquareSecond>()
-					: outTorque / ModelData.Inertia;
-
-				var inertiaPowerLoss = Formulas.InertiaPower(inAngularVelocity, alpha, ModelData.Inertia,
-					Constants.SimulationSettings.TargetTimeInterval);
-				inTorque += inertiaPowerLoss / inAngularVelocity;
-			}
-
-			var response =
-				(ResponseDryRun)
-					NextComponent.Request(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, inTorque,
-						inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity);
-			//response.Switch().
-			//	Case<ResponseSuccess>().
-			//	Case<ResponseOverload>().
-			//	Case<ResponseUnderload>().
-			//	Default(r => { throw new UnexpectedResponseException("Gearbox.Initialize", r); });
-
-			var fullLoad = DataBus.EngineStationaryFullPower(inAngularVelocity);
-
-			Gear = oldGear;
-			return new ResponseDryRun {
-				Source = this,
-				EnginePowerRequest = response.EnginePowerRequest,
-				EngineSpeed = response.EngineSpeed,
-				DynamicFullLoadPower = response.DynamicFullLoadPower,
-				ClutchPowerRequest = response.ClutchPowerRequest,
-				GearboxPowerRequest = outTorque * outAngularVelocity,
-				DeltaFullLoad = response.EnginePowerRequest - fullLoad
-			};
-		}
-
-		/// <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)
-		{
-			IterationStatistics.Increment(this, "Requests");
-
-			Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
-			if (DataBus.VehicleStopped) {
-				_engageTime = absTime;
-				LastDownshift = -double.MaxValue.SI<Second>();
-				LastUpshift = -double.MaxValue.SI<Second>();
-			}
-			if (DataBus.DriverBehavior == DrivingBehavior.Halted) {
-				_engageTime = absTime + dt;
-			}
-
-			if (DataBus.DriverBehavior == DrivingBehavior.Braking && (DataBus.BrakePower.IsGreater(0) || outTorque < 0) &&
-				DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed)) {
-				_engageTime = VectoMath.Max(_engageTime, absTime + dt);
-
-				return RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-			}
-
-			return ClutchClosed(absTime)
-				? RequestGearEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun)
-				: RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
-		}
-
-		/// <summary>
-		/// Requests the Gearbox in Disengaged mode
-		/// </summary>
-		/// <returns>
-		/// <list type="bullet">
-		/// <item><term>ResponseDryRun</term><description>if dryRun, immediate return!</description></item>
-		/// <item><term>ResponseFailTimeInterval</term><description>if shiftTime would be exceeded by current step</description></item>
-		/// <item><term>ResponseOverload</term><description>if torque &gt; 0</description></item>
-		/// <item><term>ResponseUnderload</term><description>if torque &lt; 0</description></item>
-		/// <item><term>else</term><description>Response from NextComponent</description></item>
-		/// </list>
-		/// </returns>
-		private IResponse RequestGearDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun)
-		{
-			Disengaged = true;
-			Log.Debug("Current Gear: Neutral");
-
-			var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-
-			var gear = NextGear.Gear;
-
-			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			var inTorqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
-			var inTorque = outTorque / ModelData.Gears[gear].Ratio + inTorqueLossResult.Value;
-
-			var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio;
-			var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
-				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
-				avgOutAngularVelocity
-				: 0.SI<NewtonMeter>();
-			inTorque += inertiaTorqueLossOut / ModelData.Gears[gear].Ratio;
-			var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0;
-
-			if (dryRun) {
-				// if gearbox is disengaged the 0[W]-line is the limit for drag and full load.
-				var delta = inTorque * avgInAngularVelocity;
-				return new ResponseDryRun {
-					Source = this,
-					GearboxPowerRequest = delta,
-					DeltaDragLoad = delta,
-					DeltaFullLoad = delta,
-				};
-			}
-
-			var shiftTimeExceeded = absTime.IsSmaller(_engageTime) &&
-									_engageTime.IsSmaller(absTime + dt, Constants.SimulationSettings.LowerBoundTimeInterval);
-			// allow 5% tolerance of shift time
-			if (shiftTimeExceeded && _engageTime - absTime > Constants.SimulationSettings.LowerBoundTimeInterval / 2) {
-				return new ResponseFailTimeInterval {
-					Source = this,
-					DeltaT = _engageTime - absTime,
-					GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0
-				};
-			}
-
-			if ((inTorque * avgInAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
-				return new ResponseOverload {
-					Source = this,
-					Delta = inTorque * avgInAngularVelocity,
-					GearboxPowerRequest = inTorque * avgInAngularVelocity
-				};
-			}
-
-			if ((inTorque * avgInAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
-				return new ResponseUnderload {
-					Source = this,
-					Delta = inTorque * avgInAngularVelocity,
-					GearboxPowerRequest = inTorque * avgInAngularVelocity
-				};
-			}
-
-			//var inTorque = 0.SI<NewtonMeter>();
-			if (avgInAngularVelocity.Equals(0.SI<PerSecond>())) {
-				inTorque = 0.SI<NewtonMeter>();
-			}
-
-			CurrentState.SetState(inTorque, inAngularVelocity, outTorque,
-				outAngularVelocity);
-			CurrentState.Gear = gear;
-			CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[gear].Ratio - outTorque;
-
-			var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), inAngularVelocity);
-
-			//CurrentState.InAngularVelocity = response.EngineSpeed;
-
-			response.GearboxPowerRequest = outTorque * avgAngularVelocity;
-
-			return response;
-		}
-
-		/// <summary>
-		/// Requests the gearbox in engaged mode. Sets the gear if no gear was set previously.
-		/// </summary>
-		/// <returns>
-		/// <list type="bullet">
-		/// <item><term>ResponseGearShift</term><description>if a shift is needed.</description></item>
-		/// <item><term>else</term><description>Response from NextComponent.</description></item>
-		/// </list>
-		/// </returns>
-		private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun)
-		{
-			// Set a Gear if no gear was set and engineSpeed is not zero
-			//if (!Disengaged && DataBus.VehicleStopped && !outAngularVelocity.IsEqual(0))
-			//{
-			//	Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
-			//}
-			if (Disengaged && !outAngularVelocity.IsEqual(0)) {
-				Disengaged = false;
-				var lastGear = Gear;
-				Gear = DataBus.VehicleStopped
-					? _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity)
-					: _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
-				if (!DataBus.VehicleStopped) {
-					if (Gear > lastGear) {
-						LastUpshift = absTime;
-					}
-					if (Gear < lastGear) {
-						LastDownshift = absTime;
-					}
-				}
-				Log.Debug("Gearbox engaged gear {0}", Gear);
-			}
-
-			var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
-			var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0;
-			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-			var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
-			var inTorque = !avgInAngularVelocity.IsEqual(0)
-				? outTorque * (avgOutAngularVelocity / avgInAngularVelocity)
-				: outTorque / ModelData.Gears[Gear].Ratio;
-			inTorque += inTorqueLossResult.Value;
-
-			var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
-				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
-				avgOutAngularVelocity
-				: 0.SI<NewtonMeter>();
-			inTorque += inertiaTorqueLossOut / ModelData.Gears[Gear].Ratio;
-
-			if (dryRun) {
-				var inertiaTorqueLossIn = avgOutAngularVelocity.IsEqual(0, 1e-9)
-					? 0.SI<NewtonMeter>()
-					: Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
-					avgOutAngularVelocity / ModelData.Gears[Gear].Ratio;
-				var dryRunResponse = NextComponent.Request(absTime, dt, inTorque + inertiaTorqueLossIn, inAngularVelocity, true);
-				dryRunResponse.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
-				return dryRunResponse;
-			}
-
-			var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity);
-			var shiftAllowed = !inAngularVelocity.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0);
-
-			if (response is ResponseSuccess && shiftAllowed) {
-				var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque,
-					response.EngineSpeed, Gear, _engageTime);
-
-				if (shiftRequired) {
-					_engageTime = absTime + ModelData.TractionInterruption;
-
-					Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, interuptionTime: {2}, out: ({3}, {4}), in: ({5}, {6})",
-						absTime,
-						dt, _engageTime, outTorque, outAngularVelocity, inTorque, inAngularVelocity);
-
-					Disengaged = true;
-					_strategy.Disengage(absTime, dt, outTorque, outAngularVelocity);
-					Log.Info("Gearbox disengaged");
-
-					return new ResponseGearShift {
-						Source = this,
-						SimulationInterval = ModelData.TractionInterruption,
-						GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0
-					};
-				}
-			}
-
-			// this code has to be _after_ the check for a potential gear-shift!
-			// (the above block issues dry-run requests and thus may update the CurrentState!)
-			// begin critical section
-			CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[Gear].Ratio - outTorque;
-			// MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side
-			CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut;
-
-
-			CurrentState.TorqueLossResult = inTorqueLossResult;
-			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-			CurrentState.Gear = Gear;
-			// end critical section
-
-
-			response.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
-
-			return response;
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
-			var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
-			// (PreviousState.OutAngularVelocity +
-			//CurrentState.OutAngularVelocity) / 2.0 * ModelData.Gears[Gear].Ratio;
-			var inPower = CurrentState.InTorque * avgInAngularSpeed;
-			var outPower = CurrentState.OutTorque * avgOutAngularSpeed;
-			container[ModalResultField.Gear] = Disengaged || DataBus.VehicleStopped ? 0 : Gear;
-			container[ModalResultField.P_gbx_loss] = inPower - outPower;
-			//CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed;
-			container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed;
-			container[ModalResultField.P_gbx_in] = inPower;
-			container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity +
-														CurrentState.OutAngularVelocity) / 2.0;
-			container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			if (!Disengaged) {
-				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}, 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);
-					}
-				}
-			}
-			if (DataBus.VehicleStopped) {
-				Disengaged = true;
-				_engageTime = -double.MaxValue.SI<Second>();
-			}
-			base.DoCommitSimulationStep();
-		}
-	}
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+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.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class Gearbox : AbstractGearbox<GearboxState>
+	{
+		/// <summary>
+		/// The shift strategy.
+		/// </summary>
+		private readonly IShiftStrategy _strategy;
+
+		/// <summary>
+		/// Time when a gearbox shift engages a new gear (shift is finished). Is set when shifting is needed.
+		/// </summary>
+		private Second _engageTime = 0.SI<Second>();
+
+		/// <summary>
+		/// True if gearbox is disengaged (no gear is set).
+		/// </summary>
+		protected internal bool Disengaged = true;
+
+		public Second LastUpshift { get; protected internal set; }
+
+		public Second LastDownshift { get; protected internal set; }
+
+		public override GearInfo NextGear
+		{
+			get { return _strategy.NextGear; }
+		}
+
+		public override bool ClutchClosed(Second absTime)
+		{
+			return _engageTime.IsSmallerOrEqual(absTime);
+		}
+
+		public Gearbox(IVehicleContainer container, IShiftStrategy strategy, VectoRunData runData) : base(container, runData)
+		{
+			_strategy = strategy;
+			_strategy.Gearbox = this;
+
+			LastDownshift = -double.MaxValue.SI<Second>();
+			LastUpshift = -double.MaxValue.SI<Second>();
+		}
+
+		public override IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			var absTime = 0.SI<Second>();
+			var dt = Constants.SimulationSettings.TargetTimeInterval;
+
+			_engageTime = -double.MaxValue.SI<Second>();
+
+			if (Disengaged) {
+				Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
+			}
+
+			var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
+			var gearboxTorqueLoss = ModelData.Gears[Gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
+			CurrentState.TorqueLossResult = gearboxTorqueLoss;
+
+			var inTorque = outTorque / ModelData.Gears[Gear].Ratio
+							+ gearboxTorqueLoss.Value;
+
+			PreviousState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+			PreviousState.InertiaTorqueLossOut = 0.SI<NewtonMeter>();
+			PreviousState.Gear = Gear;
+			Disengaged = false;
+
+			var response = NextComponent.Initialize(inTorque, inAngularVelocity);
+
+			return response;
+		}
+
+		internal ResponseDryRun Initialize(uint gear, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			var oldGear = Gear;
+			Gear = gear;
+			var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio;
+			var torqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(outAngularVelocity, outTorque);
+			CurrentState.TorqueLossResult = torqueLossResult;
+			var inTorque = outTorque / ModelData.Gears[gear].Ratio + torqueLossResult.Value;
+
+			if (!inAngularVelocity.IsEqual(0)) {
+				var alpha = ModelData.Inertia.IsEqual(0)
+					? 0.SI<PerSquareSecond>()
+					: outTorque / ModelData.Inertia;
+
+				var inertiaPowerLoss = Formulas.InertiaPower(inAngularVelocity, alpha, ModelData.Inertia,
+					Constants.SimulationSettings.TargetTimeInterval);
+				inTorque += inertiaPowerLoss / inAngularVelocity;
+			}
+
+			var response =
+				(ResponseDryRun)
+					NextComponent.Request(0.SI<Second>(), Constants.SimulationSettings.TargetTimeInterval, inTorque,
+						inAngularVelocity, true); //NextComponent.Initialize(inTorque, inAngularVelocity);
+			//response.Switch().
+			//	Case<ResponseSuccess>().
+			//	Case<ResponseOverload>().
+			//	Case<ResponseUnderload>().
+			//	Default(r => { throw new UnexpectedResponseException("Gearbox.Initialize", r); });
+
+			var fullLoad = DataBus.EngineStationaryFullPower(inAngularVelocity);
+
+			Gear = oldGear;
+			return new ResponseDryRun {
+				Source = this,
+				EnginePowerRequest = response.EnginePowerRequest,
+				EngineSpeed = response.EngineSpeed,
+				DynamicFullLoadPower = response.DynamicFullLoadPower,
+				ClutchPowerRequest = response.ClutchPowerRequest,
+				GearboxPowerRequest = outTorque * outAngularVelocity,
+				DeltaFullLoad = response.EnginePowerRequest - fullLoad
+			};
+		}
+
+		/// <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)
+		{
+			IterationStatistics.Increment(this, "Requests");
+
+			Log.Debug("Gearbox Power Request: torque: {0}, angularVelocity: {1}", outTorque, outAngularVelocity);
+			if (DataBus.VehicleStopped) {
+				_engageTime = absTime;
+				LastDownshift = -double.MaxValue.SI<Second>();
+				LastUpshift = -double.MaxValue.SI<Second>();
+			}
+			if (DataBus.DriverBehavior == DrivingBehavior.Halted) {
+				_engageTime = absTime + dt;
+			}
+
+			if (DataBus.DriverBehavior == DrivingBehavior.Braking && (DataBus.BrakePower.IsGreater(0) || outTorque < 0) &&
+				DataBus.VehicleSpeed.IsSmaller(Constants.SimulationSettings.ClutchDisengageWhenHaltingSpeed)) {
+				_engageTime = VectoMath.Max(_engageTime, absTime + dt);
+
+				return RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+			}
+
+			return ClutchClosed(absTime)
+				? RequestGearEngaged(absTime, dt, outTorque, outAngularVelocity, dryRun)
+				: RequestGearDisengaged(absTime, dt, outTorque, outAngularVelocity, dryRun);
+		}
+
+		/// <summary>
+		/// Requests the Gearbox in Disengaged mode
+		/// </summary>
+		/// <returns>
+		/// <list type="bullet">
+		/// <item><term>ResponseDryRun</term><description>if dryRun, immediate return!</description></item>
+		/// <item><term>ResponseFailTimeInterval</term><description>if shiftTime would be exceeded by current step</description></item>
+		/// <item><term>ResponseOverload</term><description>if torque &gt; 0</description></item>
+		/// <item><term>ResponseUnderload</term><description>if torque &lt; 0</description></item>
+		/// <item><term>else</term><description>Response from NextComponent</description></item>
+		/// </list>
+		/// </returns>
+		private IResponse RequestGearDisengaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun)
+		{
+			Disengaged = true;
+			Log.Debug("Current Gear: Neutral");
+
+			var avgAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+
+			var gear = NextGear.Gear;
+
+			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			var inTorqueLossResult = ModelData.Gears[gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
+			var inTorque = outTorque / ModelData.Gears[gear].Ratio + inTorqueLossResult.Value;
+
+			var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio;
+			var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
+				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
+				avgOutAngularVelocity
+				: 0.SI<NewtonMeter>();
+			inTorque += inertiaTorqueLossOut / ModelData.Gears[gear].Ratio;
+			var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0;
+
+			if (dryRun) {
+				// if gearbox is disengaged the 0[W]-line is the limit for drag and full load.
+				var delta = inTorque * avgInAngularVelocity;
+				return new ResponseDryRun {
+					Source = this,
+					GearboxPowerRequest = delta,
+					DeltaDragLoad = delta,
+					DeltaFullLoad = delta,
+				};
+			}
+
+			var shiftTimeExceeded = absTime.IsSmaller(_engageTime) &&
+									_engageTime.IsSmaller(absTime + dt, Constants.SimulationSettings.LowerBoundTimeInterval);
+			// allow 5% tolerance of shift time
+			if (shiftTimeExceeded && _engageTime - absTime > Constants.SimulationSettings.LowerBoundTimeInterval / 2) {
+				return new ResponseFailTimeInterval {
+					Source = this,
+					DeltaT = _engageTime - absTime,
+					GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0
+				};
+			}
+
+			if ((inTorque * avgInAngularVelocity).IsGreater(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
+				return new ResponseOverload {
+					Source = this,
+					Delta = inTorque * avgInAngularVelocity,
+					GearboxPowerRequest = inTorque * avgInAngularVelocity
+				};
+			}
+
+			if ((inTorque * avgInAngularVelocity).IsSmaller(0.SI<Watt>(), Constants.SimulationSettings.LineSearchTolerance)) {
+				return new ResponseUnderload {
+					Source = this,
+					Delta = inTorque * avgInAngularVelocity,
+					GearboxPowerRequest = inTorque * avgInAngularVelocity
+				};
+			}
+
+			//var inTorque = 0.SI<NewtonMeter>();
+			if (avgInAngularVelocity.Equals(0.SI<PerSecond>())) {
+				inTorque = 0.SI<NewtonMeter>();
+			}
+
+			CurrentState.SetState(inTorque, inAngularVelocity, outTorque,
+				outAngularVelocity);
+			CurrentState.Gear = gear;
+			CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[gear].Ratio - outTorque;
+
+			var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), inAngularVelocity);
+
+			//CurrentState.InAngularVelocity = response.EngineSpeed;
+
+			response.GearboxPowerRequest = outTorque * avgAngularVelocity;
+
+			return response;
+		}
+
+		/// <summary>
+		/// Requests the gearbox in engaged mode. Sets the gear if no gear was set previously.
+		/// </summary>
+		/// <returns>
+		/// <list type="bullet">
+		/// <item><term>ResponseGearShift</term><description>if a shift is needed.</description></item>
+		/// <item><term>else</term><description>Response from NextComponent.</description></item>
+		/// </list>
+		/// </returns>
+		private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun)
+		{
+			// Set a Gear if no gear was set and engineSpeed is not zero
+			//if (!Disengaged && DataBus.VehicleStopped && !outAngularVelocity.IsEqual(0))
+			//{
+			//	Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
+			//}
+			if (Disengaged && !outAngularVelocity.IsEqual(0)) {
+				ReEngageGear(absTime, dt, outTorque, outAngularVelocity);
+				Log.Debug("Gearbox engaged gear {0}", Gear);
+			}
+
+			var inAngularVelocity = outAngularVelocity * ModelData.Gears[Gear].Ratio;
+			var avgInAngularVelocity = (PreviousState.InAngularVelocity + inAngularVelocity) / 2.0;
+			var avgOutAngularVelocity = (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+			var inTorqueLossResult = ModelData.Gears[Gear].LossMap.GetTorqueLoss(avgOutAngularVelocity, outTorque);
+			var inTorque = !avgInAngularVelocity.IsEqual(0)
+				? outTorque * (avgOutAngularVelocity / avgInAngularVelocity)
+				: outTorque / ModelData.Gears[Gear].Ratio;
+			inTorque += inTorqueLossResult.Value;
+
+			var inertiaTorqueLossOut = !inAngularVelocity.IsEqual(0)
+				? Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
+				avgOutAngularVelocity
+				: 0.SI<NewtonMeter>();
+			inTorque += inertiaTorqueLossOut / ModelData.Gears[Gear].Ratio;
+
+			if (dryRun) {
+				var inertiaTorqueLossIn = avgOutAngularVelocity.IsEqual(0, 1e-9)
+					? 0.SI<NewtonMeter>()
+					: Formulas.InertiaPower(outAngularVelocity, PreviousState.OutAngularVelocity, ModelData.Inertia, dt) /
+					avgOutAngularVelocity / ModelData.Gears[Gear].Ratio;
+				var dryRunResponse = NextComponent.Request(absTime, dt, inTorque + inertiaTorqueLossIn, inAngularVelocity, true);
+				dryRunResponse.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0;
+				return dryRunResponse;
+			}
+
+			var response = NextComponent.Request(absTime, dt, inTorque, inAngularVelocity);
+			var shiftAllowed = !inAngularVelocity.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0);
+
+			if (response is ResponseSuccess && shiftAllowed) {
+				var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque,
+					response.EngineSpeed, Gear, _engageTime);
+
+				if (shiftRequired) {
+					_engageTime = absTime + ModelData.TractionInterruption;
+
+					Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, interuptionTime: {2}, out: ({3}, {4}), in: ({5}, {6})",
+						absTime,
+						dt, _engageTime, outTorque, outAngularVelocity, inTorque, inAngularVelocity);
+
+					Disengaged = true;
+					_strategy.Disengage(absTime, dt, outTorque, outAngularVelocity);
+					Log.Info("Gearbox disengaged");
+
+					return new ResponseGearShift {
+						Source = this,
+						SimulationInterval = ModelData.TractionInterruption,
+						GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + outAngularVelocity) / 2.0
+					};
+				}
+			}
+
+			// this code has to be _after_ the check for a potential gear-shift!
+			// (the above block issues dry-run requests and thus may update the CurrentState!)
+			// begin critical section
+			CurrentState.TransmissionTorqueLoss = inTorque * ModelData.Gears[Gear].Ratio - outTorque;
+			// MQ 19.2.2016: check! inertia is related to output side, torque loss accounts to input side
+			CurrentState.InertiaTorqueLossOut = inertiaTorqueLossOut;
+
+
+			CurrentState.TorqueLossResult = inTorqueLossResult;
+			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+			CurrentState.Gear = Gear;
+			// end critical section
+
+
+			response.GearboxPowerRequest = outTorque * (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
+
+			return response;
+		}
+
+		private void ReEngageGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			Disengaged = false;
+			var lastGear = Gear;
+			Gear = DataBus.VehicleStopped
+				? _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity)
+				: _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
+			if (!DataBus.VehicleStopped) {
+				if (Gear > lastGear) {
+					LastUpshift = absTime;
+				}
+				if (Gear < lastGear) {
+					LastDownshift = absTime;
+				}
+			}
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			var avgInAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
+			var avgOutAngularSpeed = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
+			// (PreviousState.OutAngularVelocity +
+			//CurrentState.OutAngularVelocity) / 2.0 * ModelData.Gears[Gear].Ratio;
+			var inPower = CurrentState.InTorque * avgInAngularSpeed;
+			var outPower = CurrentState.OutTorque * avgOutAngularSpeed;
+			container[ModalResultField.Gear] = Disengaged || DataBus.VehicleStopped ? 0 : Gear;
+			container[ModalResultField.P_gbx_loss] = inPower - outPower;
+			//CurrentState.TransmissionTorqueLoss * avgOutAngularSpeed;
+			container[ModalResultField.P_gbx_inertia] = CurrentState.InertiaTorqueLossOut * avgOutAngularSpeed;
+			container[ModalResultField.P_gbx_in] = inPower;
+			container[ModalResultField.n_gbx_out_avg] = (PreviousState.OutAngularVelocity +
+														CurrentState.OutAngularVelocity) / 2.0;
+			container[ModalResultField.T_gbx_out] = CurrentState.OutTorque;
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			if (!Disengaged) {
+				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}, 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);
+					}
+				}
+			}
+			if (DataBus.VehicleStopped) {
+				Disengaged = true;
+				_engageTime = -double.MaxValue.SI<Second>();
+			}
+			base.DoCommitSimulationStep();
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
index 8a5db4a93a9e679c06d9acde320d7c7e6c109328..0e5eb487fad515148cd93b1824c8e383d72179ac 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/TorqueConverter.cs
@@ -29,265 +29,270 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System.Collections.Generic;
-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;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>,
-		ITnInPort, ITnOutPort
-	{
-		protected readonly IGearboxInfo Gearbox;
-		protected readonly IShiftStrategy ShiftStrategy;
-		protected readonly TorqueConverterData ModelData;
-		private readonly KilogramSquareMeter _engineInertia;
-
-		public ITnOutPort NextComponent { protected internal get; set; }
-
-		public TorqueConverter(IGearboxInfo gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container,
-			TorqueConverterData tcData, VectoRunData runData) : base(container)
-		{
-			Gearbox = gearbox;
-			ShiftStrategy = shiftStrategy;
-			ModelData = tcData;
-			_engineInertia = runData != null && runData.EngineData != null
-				? runData.EngineData.Inertia
-				: 0.SI<KilogramSquareMeter>();
-		}
-
-		public void Connect(ITnOutPort other)
-		{
-			NextComponent = other;
-		}
-
-		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed);
-			TorqueConverterOperatingPoint operatingPoint;
-			if (operatingPointList.Count > 0) {
-				operatingPoint = SelectOperatingPoint(operatingPointList);
-			} else {
-				Log.Warn(
-					"TorqueConverter Initialize: No operating point found. Using output as input values as fallback for initialize.");
-				var inAngularVelocity = outAngularVelocity.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineN95hSpeed);
-				operatingPoint = new TorqueConverterOperatingPoint {
-					OutAngularVelocity = outAngularVelocity,
-					OutTorque = outTorque,
-					InAngularVelocity = inAngularVelocity,
-					InTorque = outTorque * (outAngularVelocity / inAngularVelocity)
-				};
-			}
-			var retVal = NextComponent.Initialize(operatingPoint.InTorque, operatingPoint.InAngularVelocity);
-			PreviousState.SetState(operatingPoint.InTorque, operatingPoint.InAngularVelocity, operatingPoint.OutTorque,
-				operatingPoint.OutAngularVelocity);
-			return retVal;
-		}
-
-		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			bool dryRun = false)
-		{
-			var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
-			var avgEngineSpeed = (PreviousState.InAngularVelocity + operatingPoint.InAngularVelocity) / 2;
-			var avgPower = (PreviousState.InAngularVelocity * PreviousState.InTorque +
-							operatingPoint.InAngularVelocity * operatingPoint.InTorque) / 2;
-			var inTorque = avgPower / avgEngineSpeed;
-
-			if (dryRun) {
-				// dry run request
-				var engineResponse = (ResponseDryRun)
-					NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity, true);
-
-				var engineOK = engineResponse.DeltaDragLoad.IsGreaterOrEqual(0) && engineResponse.DeltaFullLoad.IsSmallerOrEqual(0);
-				if (DataBus.DriverBehavior != DrivingBehavior.Braking && engineOK && operatingPoint.Creeping) {
-					var delta = (outTorque - operatingPoint.OutTorque) *
-								(PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0;
-					return new ResponseDryRun() {
-						Source = this,
-						DeltaFullLoad = delta,
-						DeltaDragLoad = delta,
-						TorqueConverterOperatingPoint = operatingPoint
-					};
-				}
-
-				var dryOperatingPointMax = GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse,
-					PreviousState.InTorque * PreviousState.InAngularVelocity);
-				var avgOutSpeedMax = (PreviousState.OutAngularVelocity + dryOperatingPointMax.OutAngularVelocity) / 2.0;
-				var deltaMax = (outTorque - dryOperatingPointMax.OutTorque) * avgOutSpeedMax;
-
-				var dryOperatingPointMin = GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse,
-					PreviousState.InTorque * PreviousState.InAngularVelocity);
-				var avgOutSpeedMin = (PreviousState.OutAngularVelocity + dryOperatingPointMin.OutAngularVelocity) / 2.0;
-				var deltaMin = (outTorque - dryOperatingPointMin.OutTorque) * avgOutSpeedMin;
-
-				return new ResponseDryRun {
-					Source = this,
-					DeltaFullLoad = 2 * deltaMax,
-					DeltaDragLoad = 2 * deltaMin,
-					TorqueConverterOperatingPoint = dryOperatingPointMax
-				};
-			}
-
-			// normal request
-
-			// check if out-side of the operating point is equal to requested values
-			if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) {
-				var delta = (outTorque - operatingPoint.OutTorque) *
-							(PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0;
-				if (!delta.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) {
-					if (delta > 0) {
-						return new ResponseOverload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
-					} else {
-						return new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
-					}
-				}
-			}
-
-			CurrentState.SetState(inTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity);
-			CurrentState.OperatingPoint = operatingPoint;
-
-			var retVal = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity);
-
-			// check if shift is required
-			var ratio = Gearbox.GetGearData(Gearbox.Gear).TorqueConverterRatio;
-			if (retVal is ResponseSuccess &&
-				ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, inTorque,
-					operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) {
-				return new ResponseGearShift { Source = this };
-			}
-			return retVal;
-		}
-
-		private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
-			ResponseDryRun engineResponse, Watt previousPower)
-		{
-			try {
-				var operatingPoint = ModelData.FindOperatingPointForPowerDemand(
-					engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand,
-					DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower);
-				var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed);
-				if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) {
-					operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity);
-				}
-				if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
-					operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
-				}
-				return operatingPoint;
-			} catch (VectoException ve) {
-				Log.Error(ve, "TorqueConverter: Failed to find operating point for DragPower {0}", engineResponse.DragPower);
-				var retVal = ModelData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity);
-				retVal.Creeping = true;
-				return retVal;
-			}
-		}
-
-		private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
-			ResponseDryRun engineResponse, Watt previousPower)
-		{
-			try {
-				var operatingPoint = ModelData.FindOperatingPointForPowerDemand(
-					engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
-					DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower);
-				var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed);
-				if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) {
-					operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity);
-				}
-				return operatingPoint;
-			} catch (VectoException ve) {
-				Log.Error(ve, "TorqueConverter: Failed to find operating point for MaxPower {0}",
-					engineResponse.DynamicFullLoadPower);
-				var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
-				tqOperatingPoint.Creeping = true;
-				return tqOperatingPoint;
-			}
-		}
-
-		protected internal TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
-			PerSecond outAngularVelocity)
-		{
-			var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed);
-			if (operatingPointList.Count == 0) {
-				Log.Debug("TorqueConverter: Failed to find torque converter operating point, fallback: creeping");
-				var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
-				tqOperatingPoint.Creeping = true;
-				return tqOperatingPoint;
-			}
-
-			var operatingPoint = SelectOperatingPoint(operatingPointList);
-			if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
-				throw new VectoException(
-					"TorqueConverter: Invalid operating point, inAngularVelocity would be below engine's idle speed: {0}",
-					operatingPoint.InAngularVelocity);
-			}
-			var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed);
-			if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) {
-				operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity);
-			}
-			return operatingPoint;
-		}
-
-		private TorqueConverterOperatingPoint SelectOperatingPoint(IList<TorqueConverterOperatingPoint> operatingPointList)
-		{
-			if (operatingPointList.Count == 1) {
-				return operatingPointList[0];
-			}
-
-			foreach (var x in operatingPointList) {
-				if ((x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity),
-					Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) &&
-					(x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity),
-						Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())) {
-					return x;
-				}
-			}
-
-			return operatingPointList[0];
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			if (CurrentState.OperatingPoint == null) {
-				container[ModalResultField.TorqueConverterTorqueRatio] = 1.0;
-				container[ModalResultField.TorqueConverterSpeedRatio] = 1.0;
-			} else {
-				container[ModalResultField.TorqueConverterTorqueRatio] = CurrentState.OperatingPoint.TorqueRatio;
-				container[ModalResultField.TorqueConverterSpeedRatio] = CurrentState.OperatingPoint.SpeedRatio;
-			}
-			container[ModalResultField.TC_TorqueIn] = CurrentState.InTorque;
-			container[ModalResultField.TC_TorqueOut] = CurrentState.OutTorque;
-			container[ModalResultField.TC_angularSpeedIn] = CurrentState.InAngularVelocity;
-			container[ModalResultField.TC_angularSpeedOut] = CurrentState.OutAngularVelocity;
-
-			var avgOutVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
-			var avgInVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
-			container[ModalResultField.P_TC_out] = CurrentState.OutTorque * avgOutVelocity;
-			container[ModalResultField.P_TC_loss] = CurrentState.InTorque * avgInVelocity -
-													CurrentState.OutTorque * avgOutVelocity;
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			AdvanceState();
-		}
-
-		public void Locked(NewtonMeter inTorque, PerSecond inAngularVelocity, NewtonMeter outTorque,
-			PerSecond outAngularVelocity)
-		{
-			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
-		}
-
-		public class TorqueConverterComponentState : SimpleComponentState
-		{
-			public TorqueConverterOperatingPoint OperatingPoint;
-		}
-	}
+using System.Collections.Generic;
+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;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class TorqueConverter : StatefulVectoSimulationComponent<TorqueConverter.TorqueConverterComponentState>,
+		ITnInPort, ITnOutPort
+	{
+		protected readonly IGearboxInfo Gearbox;
+		protected readonly IShiftStrategy ShiftStrategy;
+		protected readonly TorqueConverterData ModelData;
+		private readonly KilogramSquareMeter _engineInertia;
+
+		public ITnOutPort NextComponent { protected internal get; set; }
+
+		public TorqueConverter(IGearboxInfo gearbox, IShiftStrategy shiftStrategy, IVehicleContainer container,
+			TorqueConverterData tcData, VectoRunData runData) : base(container)
+		{
+			Gearbox = gearbox;
+			ShiftStrategy = shiftStrategy;
+			ModelData = tcData;
+			_engineInertia = runData != null && runData.EngineData != null
+				? runData.EngineData.Inertia
+				: 0.SI<KilogramSquareMeter>();
+		}
+
+		public void Connect(ITnOutPort other)
+		{
+			NextComponent = other;
+		}
+
+		public IResponse Initialize(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed);
+			TorqueConverterOperatingPoint operatingPoint;
+			if (operatingPointList.Count > 0) {
+				operatingPoint = SelectOperatingPoint(operatingPointList);
+			} else {
+				Log.Warn(
+					"TorqueConverter Initialize: No operating point found. Using output as input values as fallback for initialize.");
+				var inAngularVelocity = outAngularVelocity.LimitTo(DataBus.EngineIdleSpeed, DataBus.EngineN95hSpeed);
+				operatingPoint = new TorqueConverterOperatingPoint {
+					OutAngularVelocity = outAngularVelocity,
+					OutTorque = outTorque,
+					InAngularVelocity = inAngularVelocity,
+					InTorque = outTorque * (outAngularVelocity / inAngularVelocity)
+				};
+			}
+			var retVal = NextComponent.Initialize(operatingPoint.InTorque, operatingPoint.InAngularVelocity);
+			PreviousState.SetState(operatingPoint.InTorque, operatingPoint.InAngularVelocity, operatingPoint.OutTorque,
+				operatingPoint.OutAngularVelocity);
+			return retVal;
+		}
+
+		public IResponse Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			bool dryRun = false)
+		{
+			var operatingPoint = FindOperatingPoint(outTorque, outAngularVelocity);
+			var avgEngineSpeed = (PreviousState.InAngularVelocity + operatingPoint.InAngularVelocity) / 2;
+			var avgPower = (PreviousState.InAngularVelocity * PreviousState.InTorque +
+							operatingPoint.InAngularVelocity * operatingPoint.InTorque) / 2;
+			var inTorque = avgPower / avgEngineSpeed;
+
+			if (dryRun) {
+				return HandleDryRun(absTime, dt, outTorque, outAngularVelocity, inTorque, operatingPoint);
+			}
+
+			// normal request
+
+			// check if out-side of the operating point is equal to requested values
+			if (!outAngularVelocity.IsEqual(operatingPoint.OutAngularVelocity) || !outTorque.IsEqual(operatingPoint.OutTorque)) {
+				var delta = (outTorque - operatingPoint.OutTorque) *
+							(PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0;
+				if (!delta.IsEqual(0, Constants.SimulationSettings.LineSearchTolerance)) {
+					return delta > 0
+						? new ResponseOverload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint }
+						: (IResponse)
+							new ResponseUnderload { Source = this, Delta = delta, TorqueConverterOperatingPoint = operatingPoint };
+				}
+			}
+
+			CurrentState.SetState(inTorque, operatingPoint.InAngularVelocity, outTorque, outAngularVelocity);
+			CurrentState.OperatingPoint = operatingPoint;
+
+			var retVal = NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity);
+
+			// check if shift is required
+			var ratio = Gearbox.GetGearData(Gearbox.Gear).TorqueConverterRatio;
+			if (retVal is ResponseSuccess &&
+				ShiftStrategy.ShiftRequired(absTime, dt, outTorque * ratio, outAngularVelocity / ratio, inTorque,
+					operatingPoint.InAngularVelocity, Gearbox.Gear, Gearbox.LastShift)) {
+				return new ResponseGearShift { Source = this };
+			}
+			return retVal;
+		}
+
+		private IResponse HandleDryRun(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, TorqueConverterOperatingPoint operatingPoint)
+		{
+// dry run request
+			var engineResponse = (ResponseDryRun)
+				NextComponent.Request(absTime, dt, inTorque, operatingPoint.InAngularVelocity, true);
+
+			var engineOK = engineResponse.DeltaDragLoad.IsGreaterOrEqual(0) && engineResponse.DeltaFullLoad.IsSmallerOrEqual(0);
+			if (DataBus.DriverBehavior != DrivingBehavior.Braking && engineOK && operatingPoint.Creeping) {
+				var delta = (outTorque - operatingPoint.OutTorque) *
+							(PreviousState.OutAngularVelocity + operatingPoint.OutAngularVelocity) / 2.0;
+				return new ResponseDryRun() {
+					Source = this,
+					DeltaFullLoad = delta,
+					DeltaDragLoad = delta,
+					TorqueConverterOperatingPoint = operatingPoint
+				};
+			}
+
+			var dryOperatingPointMax = GetMaxPowerOperatingPoint(dt, outAngularVelocity, engineResponse,
+				PreviousState.InTorque * PreviousState.InAngularVelocity);
+			var avgOutSpeedMax = (PreviousState.OutAngularVelocity + dryOperatingPointMax.OutAngularVelocity) / 2.0;
+			var deltaMax = (outTorque - dryOperatingPointMax.OutTorque) * avgOutSpeedMax;
+
+			var dryOperatingPointMin = GetDragPowerOperatingPoint(dt, outAngularVelocity, engineResponse,
+				PreviousState.InTorque * PreviousState.InAngularVelocity);
+			var avgOutSpeedMin = (PreviousState.OutAngularVelocity + dryOperatingPointMin.OutAngularVelocity) / 2.0;
+			var deltaMin = (outTorque - dryOperatingPointMin.OutTorque) * avgOutSpeedMin;
+
+			return new ResponseDryRun {
+				Source = this,
+				DeltaFullLoad = 2 * deltaMax,
+				DeltaDragLoad = 2 * deltaMin,
+				TorqueConverterOperatingPoint = dryOperatingPointMax
+			};
+		}
+
+		private TorqueConverterOperatingPoint GetDragPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
+			ResponseDryRun engineResponse, Watt previousPower)
+		{
+			try {
+				var operatingPoint = ModelData.FindOperatingPointForPowerDemand(
+					engineResponse.DragPower - engineResponse.AuxiliariesPowerDemand,
+					DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower);
+				var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed);
+				if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) {
+					operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity);
+				}
+				if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+					operatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
+				}
+				return operatingPoint;
+			} catch (VectoException ve) {
+				Log.Error(ve, "TorqueConverter: Failed to find operating point for DragPower {0}", engineResponse.DragPower);
+				var retVal = ModelData.FindOperatingPoint(engineResponse.EngineSpeed, outAngularVelocity);
+				retVal.Creeping = true;
+				return retVal;
+			}
+		}
+
+		private TorqueConverterOperatingPoint GetMaxPowerOperatingPoint(Second dt, PerSecond outAngularVelocity,
+			ResponseDryRun engineResponse, Watt previousPower)
+		{
+			try {
+				var operatingPoint = ModelData.FindOperatingPointForPowerDemand(
+					engineResponse.DynamicFullLoadPower - engineResponse.AuxiliariesPowerDemand,
+					DataBus.EngineSpeed, outAngularVelocity, _engineInertia, dt, previousPower);
+				var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed);
+				if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) {
+					operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity);
+				}
+				return operatingPoint;
+			} catch (VectoException ve) {
+				Log.Error(ve, "TorqueConverter: Failed to find operating point for MaxPower {0}",
+					engineResponse.DynamicFullLoadPower);
+				var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
+				tqOperatingPoint.Creeping = true;
+				return tqOperatingPoint;
+			}
+		}
+
+		protected internal TorqueConverterOperatingPoint FindOperatingPoint(NewtonMeter outTorque,
+			PerSecond outAngularVelocity)
+		{
+			var operatingPointList = ModelData.FindOperatingPoint(outTorque, outAngularVelocity, DataBus.EngineIdleSpeed);
+			if (operatingPointList.Count == 0) {
+				Log.Debug("TorqueConverter: Failed to find torque converter operating point, fallback: creeping");
+				var tqOperatingPoint = ModelData.FindOperatingPoint(DataBus.EngineIdleSpeed, outAngularVelocity);
+				tqOperatingPoint.Creeping = true;
+				return tqOperatingPoint;
+			}
+
+			var operatingPoint = SelectOperatingPoint(operatingPointList);
+			if (operatingPoint.InAngularVelocity.IsSmaller(DataBus.EngineIdleSpeed)) {
+				throw new VectoException(
+					"TorqueConverter: Invalid operating point, inAngularVelocity would be below engine's idle speed: {0}",
+					operatingPoint.InAngularVelocity);
+			}
+			var maxInputSpeed = VectoMath.Min(ModelData.TorqueConverterSpeedLimit, DataBus.EngineRatedSpeed);
+			if (operatingPoint.InAngularVelocity.IsGreater(maxInputSpeed)) {
+				operatingPoint = ModelData.FindOperatingPoint(maxInputSpeed, outAngularVelocity);
+			}
+			return operatingPoint;
+		}
+
+		private TorqueConverterOperatingPoint SelectOperatingPoint(IList<TorqueConverterOperatingPoint> operatingPointList)
+		{
+			if (operatingPointList.Count == 1) {
+				return operatingPointList[0];
+			}
+
+			foreach (var x in operatingPointList) {
+				if ((x.InTorque * x.InAngularVelocity).IsSmallerOrEqual(DataBus.EngineStationaryFullPower(x.InAngularVelocity),
+					Constants.SimulationSettings.LineSearchTolerance.SI<Watt>()) &&
+					(x.InTorque * x.InAngularVelocity).IsGreaterOrEqual(DataBus.EngineDragPower(x.InAngularVelocity),
+						Constants.SimulationSettings.LineSearchTolerance.SI<Watt>())) {
+					return x;
+				}
+			}
+
+			return operatingPointList[0];
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			if (CurrentState.OperatingPoint == null) {
+				container[ModalResultField.TorqueConverterTorqueRatio] = 1.0;
+				container[ModalResultField.TorqueConverterSpeedRatio] = 1.0;
+			} else {
+				container[ModalResultField.TorqueConverterTorqueRatio] = CurrentState.OperatingPoint.TorqueRatio;
+				container[ModalResultField.TorqueConverterSpeedRatio] = CurrentState.OperatingPoint.SpeedRatio;
+			}
+			container[ModalResultField.TC_TorqueIn] = CurrentState.InTorque;
+			container[ModalResultField.TC_TorqueOut] = CurrentState.OutTorque;
+			container[ModalResultField.TC_angularSpeedIn] = CurrentState.InAngularVelocity;
+			container[ModalResultField.TC_angularSpeedOut] = CurrentState.OutAngularVelocity;
+
+			var avgOutVelocity = (PreviousState.OutAngularVelocity + CurrentState.OutAngularVelocity) / 2.0;
+			var avgInVelocity = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
+			container[ModalResultField.P_TC_out] = CurrentState.OutTorque * avgOutVelocity;
+			container[ModalResultField.P_TC_loss] = CurrentState.InTorque * avgInVelocity -
+													CurrentState.OutTorque * avgOutVelocity;
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			AdvanceState();
+		}
+
+		public void Locked(NewtonMeter inTorque, PerSecond inAngularVelocity, NewtonMeter outTorque,
+			PerSecond outAngularVelocity)
+		{
+			CurrentState.SetState(inTorque, inAngularVelocity, outTorque, outAngularVelocity);
+		}
+
+		public class TorqueConverterComponentState : SimpleComponentState
+		{
+			public TorqueConverterOperatingPoint OperatingPoint;
+		}
+	}
 }
\ No newline at end of file