diff --git a/VectoCore/Models/SimulationComponent/IShiftStrategy.cs b/VectoCore/Models/SimulationComponent/IShiftStrategy.cs
index 62dc6c54193b56675810d5cf423efba2b4e1e74a..918a1f5a12e8c9d92ba0f915d33df0f83e66118d 100644
--- a/VectoCore/Models/SimulationComponent/IShiftStrategy.cs
+++ b/VectoCore/Models/SimulationComponent/IShiftStrategy.cs
@@ -11,6 +11,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 		/// <summary>
 		/// Checks if a shift operation is required.
 		/// </summary>
+		/// <param name="absTime">The abs time.</param>
+		/// <param name="dt">The dt.</param>
+		/// <param name="outTorque">The out torque.</param>
+		/// <param name="outAngularVelocity">The out angular velocity.</param>
+		/// <param name="inTorque">The in torque.</param>
+		/// <param name="inAngularVelocity">The in angular velocity.</param>
+		/// <param name="gear">The current gear.</param>
+		/// <param name="lastShiftTime">The last shift time.</param>
+		/// <returns><c>true</c> if a shift is required, <c>false</c> otherwise.</returns>
 		bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
 			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime);
 
@@ -20,9 +29,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 		/// <param name="absTime">The abs time.</param>
 		/// <param name="dt">The dt.</param>
 		/// <param name="torque">The torque.</param>
-		/// <param name="outEngineSpeed">The angular speed.</param>
-		/// <returns></returns>
-		uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outEngineSpeed);
+		/// <param name="outAngularVelocity">The angular speed.</param>
+		/// <returns>The initial gear.</returns>
+		uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity);
 
 		/// <summary>
 		/// Engages a gear.
@@ -31,7 +40,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 		/// <param name="dt">The dt.</param>
 		/// <param name="outTorque">The out torque.</param>
 		/// <param name="outEngineSpeed">The out engine speed.</param>
-		/// <returns></returns>
+		/// <returns>The gear to take.</returns>
 		uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
 
 		/// <summary>
diff --git a/VectoCore/Models/SimulationComponent/Impl/Driver.cs b/VectoCore/Models/SimulationComponent/Impl/Driver.cs
index 73c8e68a28b8ca0ba9ee7318b23e337477cd3e86..732d008c3f914825735b988c0c05b088fba2e9a4 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Driver.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Driver.cs
@@ -474,7 +474,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			debug.Add(new { brakingPower = 0.SI<Watt>(), searchInterval, delta = origDelta, operatingPoint });
 
-			var breakingPower = searchInterval * -origDelta.Sign();
+			var brakePower = searchInterval * -origDelta.Sign();
 
 			// double the searchInterval until a good interval was found
 			var intervalFactor = 1.0;
@@ -482,7 +482,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			//ResponseDryRun response;
 			do {
 				operatingPoint = ComputeTimeInterval(operatingPoint.Acceleration, ds);
-				DataBus.BreakPower = breakingPower;
+				DataBus.BreakPower = brakePower;
 				var response =
 					(ResponseDryRun)
 						NextComponent.Request(absTime, operatingPoint.SimulationInterval, operatingPoint.Acceleration, gradient, true);
@@ -494,7 +494,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					return operatingPoint;
 				}
 
-				debug.Add(new { breakingPower, searchInterval, delta, operatingPoint });
+				debug.Add(new { brakePower, searchInterval, delta, operatingPoint });
 
 				// check if a correct searchInterval was found (when the delta changed signs, we stepped through the 0-point)
 				// from then on the searchInterval can be bisected.
@@ -504,7 +504,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				}
 
 				searchInterval *= intervalFactor;
-				breakingPower += searchInterval * -delta.Sign();
+				brakePower += searchInterval * -delta.Sign();
 			} while (retryCount++ < Constants.SimulationSettings.DriverSearchLoopThreshold);
 
 			LogManager.EnableLogging();
diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 08897b6045d0a42835b7ef470a0fb8cada2ec31e..258cbb63c7057b0fbf57ab2d265a89e9cb3ba82b 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -1,5 +1,4 @@
 using System.Diagnostics;
-using System.Dynamic;
 using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.Exceptions;
 using TUGraz.VectoCore.Models.Connector.Ports;
@@ -249,10 +248,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				};
 			}
 
-			//if (DataBus.VehicleSpeed.IsEqual(0)) {
-			//	Gear = _strategy.Engage(torque, angularVelocity, Data.SkipGears);
-			//}
-
 			var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
 			response.GearboxPowerRequest = outTorque * outAngularVelocity;
 
@@ -268,27 +263,27 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// <item><term>else</term><description>Response from NextComponent.</description></item>
 		/// </list>
 		/// </returns>
-		private IResponse RequestGearEngaged(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed,
+		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 && !outEngineSpeed.IsEqual(0)) {
+			if (_disengaged && !outAngularVelocity.IsEqual(0)) {
 				_disengaged = false;
 				if (DataBus.VehicleStopped) {
-					Gear = _strategy.InitGear(absTime, dt, outTorque, outEngineSpeed);
+					Gear = _strategy.InitGear(absTime, dt, outTorque, outAngularVelocity);
 				} else {
-					Gear = _strategy.Engage(absTime, dt, outTorque, outEngineSpeed);
+					Gear = _strategy.Engage(absTime, dt, outTorque, outAngularVelocity);
 				}
 
 				Log.Debug("Gearbox engaged gear {0}", Gear);
 			}
 
-			var inEngineSpeed = outEngineSpeed * Data.Gears[Gear].Ratio;
-			var inTorque = (outEngineSpeed.IsEqual(0))
+			var inEngineSpeed = outAngularVelocity * Data.Gears[Gear].Ratio;
+			var inTorque = (outAngularVelocity.IsEqual(0))
 				? outTorque / Data.Gears[Gear].Ratio
 				: Data.Gears[Gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque);
 
-			_powerLoss = inTorque * inEngineSpeed - outTorque * outEngineSpeed;
+			_powerLoss = inTorque * inEngineSpeed - outTorque * outAngularVelocity;
 
 			if (!inEngineSpeed.IsEqual(0)) {
 				_powerLossInertia = Formulas.InertiaPower(inEngineSpeed, _previousInAngularSpeed, Data.Inertia, dt);
@@ -299,32 +294,36 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			if (dryRun) {
 				var dryRunResponse = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed, true);
-				dryRunResponse.GearboxPowerRequest = outTorque * outEngineSpeed;
+				dryRunResponse.GearboxPowerRequest = outTorque * outAngularVelocity;
 				return dryRunResponse;
 			}
 
-			if (!inEngineSpeed.IsEqual(0)) {
-				if (_strategy.ShiftRequired(absTime, dt, outTorque, outEngineSpeed, inTorque, inEngineSpeed, Gear,
-					_shiftTime + Data.TractionInterruption)) {
+			var shiftAllowed = !inEngineSpeed.IsEqual(0) && !DataBus.VehicleSpeed.IsEqual(0);
+
+			if (shiftAllowed) {
+				var shiftRequired = _strategy.ShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inEngineSpeed,
+					Gear, _shiftTime + Data.TractionInterruption);
+
+				if (shiftRequired) {
 					_shiftTime = absTime + Data.TractionInterruption;
 
 					Log.Debug("Gearbox is shifting. absTime: {0}, dt: {1}, shiftTime: {2}, out: ({3}, {4}), in: ({5}, {6})", absTime,
-						dt, _shiftTime, outTorque, outEngineSpeed, inTorque, inEngineSpeed);
+						dt, _shiftTime, outTorque, outAngularVelocity, inTorque, inEngineSpeed);
 
 					_disengaged = true;
-					_strategy.Disengage(absTime, dt, outTorque, outEngineSpeed);
+					_strategy.Disengage(absTime, dt, outTorque, outAngularVelocity);
 					Log.Info("Gearbox disengaged");
 
 					return new ResponseGearShift {
 						Source = this,
 						SimulationInterval = Data.TractionInterruption,
-						GearboxPowerRequest = outTorque * outEngineSpeed
+						GearboxPowerRequest = outTorque * outAngularVelocity
 					};
 				}
 			}
 
 			var response = NextComponent.Request(absTime, dt, inTorque, inEngineSpeed);
-			response.GearboxPowerRequest = outTorque * outEngineSpeed;
+			response.GearboxPowerRequest = outTorque * outAngularVelocity;
 
 			_previousInAngularSpeed = inEngineSpeed;
 			return response;
@@ -345,7 +344,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		protected override void DoWriteModalResults(IModalDataWriter writer)
 		{
-			writer[ModalResultField.Gear] = _disengaged ? 0 : Gear;
+			writer[ModalResultField.Gear] = _disengaged || DataBus.VehicleStopped ? 0 : Gear;
 			writer[ModalResultField.PlossGB] = _powerLoss;
 			writer[ModalResultField.PaGB] = _powerLossInertia;
 		}
diff --git a/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
index d70dd631ed839f93c6d7abce9ffa0653a64213f2..e206552002811b7c0e319804fa10e4ec2f40c2ed 100644
--- a/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
@@ -1,5 +1,4 @@
 using System;
-using TUGraz.VectoCore.Exceptions;
 using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
@@ -8,9 +7,13 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
+	/// <summary>
+	/// Class ShiftStrategy is a base class for shift strategies. Implements some helper methods for checking the shift curves.
+	/// </summary>
 	public abstract class ShiftStrategy : IShiftStrategy
 	{
 		protected IDataBus DataBus;
+
 		protected GearboxData Data;
 
 		protected ShiftStrategy(GearboxData data, IDataBus dataBus)
@@ -20,17 +23,23 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		public abstract uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
+
 		public abstract void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
 
 		public abstract bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
 			NewtonMeter inTorque, PerSecond inAngularSpeed, uint gear, Second lastShiftTime);
 
 		public abstract uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
+
 		public Gearbox Gearbox { get; set; }
 
 		/// <summary>
 		/// Tests if the operating point is below the down-shift curve (=outside of 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>
 		protected virtual bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
 		{
 			if (gear <= 1) {
@@ -38,12 +47,20 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			}
 
 			var downSection = Data.Gears[gear].ShiftPolygon.Downshift.GetSection(entry => entry.AngularSpeed < inEngineSpeed);
+			if (downSection.Item2.AngularSpeed < inEngineSpeed) {
+				return false;
+			}
+
 			return IsOnLeftSide(inEngineSpeed, inTorque, downSection.Item1, downSection.Item2);
 		}
 
 		/// <summary>
-		/// Tests if the gearbox is above the up-shift curve (=outside of shift curve).
+		/// Tests if the operating point is above the up-shift curve (=outside of 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 above the up-shift curve; otherwise, <c>false</c>.</returns>
 		protected virtual bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
 		{
 			if (gear >= Data.Gears.Count) {
@@ -51,16 +68,24 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			}
 
 			var upSection = Data.Gears[gear].ShiftPolygon.Upshift.GetSection(entry => entry.AngularSpeed < inEngineSpeed);
+
+			if (upSection.Item2.AngularSpeed < inEngineSpeed) {
+				return true;
+			}
+
 			return IsOnRightSide(inEngineSpeed, inTorque, upSection.Item1, upSection.Item2);
 		}
 
 		/// <summary>
-		/// Tests if current power request is left or right of the shiftpolygon segment
+		/// Tests if current power request is on the left side of the shiftpolygon segment
 		/// </summary>
-		/// <remarks>
-		/// Computes a simplified cross product for the vectors: from-->X, from-->to and checks 
-		/// if the z-component is positive (which means that X was on the right side of from-->to).
-		/// </remarks>
+		/// <param name="angularSpeed">The angular speed.</param>
+		/// <param name="torque">The torque.</param>
+		/// <param name="from">From.</param>
+		/// <param name="to">To.</param>
+		/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
+		/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
+		/// if the z-component is positive (which means that X was on the right side of from--to).</remarks>
 		private static bool IsOnLeftSide(PerSecond angularSpeed, NewtonMeter torque, ShiftPolygon.ShiftPolygonEntry from,
 			ShiftPolygon.ShiftPolygonEntry to)
 		{
@@ -71,12 +96,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		/// <summary>
-		/// Tests if current power request is left or right of the shiftpolygon segment
+		/// Tests if current power request is on the left side of the shiftpolygon segment
 		/// </summary>
-		/// <remarks>
-		/// Computes a simplified cross product for the vectors: from-->X, from-->to and checks 
-		/// if the z-component is negative (which means that X was on the left side of from-->to).
-		/// </remarks>
+		/// <param name="angularSpeed">The angular speed.</param>
+		/// <param name="torque">The torque.</param>
+		/// <param name="from">From.</param>
+		/// <param name="to">To.</param>
+		/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
+		/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
+		/// if the z-component is negative (which means that X was on the left side of from--to).</remarks>
 		private static bool IsOnRightSide(PerSecond angularSpeed, NewtonMeter torque, ShiftPolygon.ShiftPolygonEntry from,
 			ShiftPolygon.ShiftPolygonEntry to)
 		{
@@ -87,6 +115,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 	}
 
+	/// <summary>
+	/// AMTShiftStrategy implements the AMT Shifting Behaviour.
+	/// </summary>
 	public class AMTShiftStrategy : ShiftStrategy
 	{
 		/// <summary>
@@ -99,111 +130,37 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			PreviousGear = 1;
 		}
 
-		private uint GetGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularSpeed, bool skipGears,
-			double torqueReserve)
-		{
-			// maxGear ratio must not result in a angularSpeed below idle-speed
-			var maxGear = (uint)(skipGears ? Data.Gears.Count : Math.Min(PreviousGear + 1, Data.Gears.Count));
-			var minGear = skipGears ? 1 : Math.Max(PreviousGear - 1, 1);
-
-			while (outAngularSpeed * Data.Gears[maxGear].Ratio < DataBus.EngineIdleSpeed && maxGear > minGear) {
-				maxGear--;
-			}
-
-			// minGear ratio must not result in an angularSpeed above ratedspeed-range * 1.2
 
-			while ((outAngularSpeed * Data.Gears[minGear].Ratio - DataBus.EngineIdleSpeed) /
-					(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) >= 1.2 && minGear < maxGear) {
-				minGear++;
-			}
-
-			// loop only runs from maxGear to minGear+1 because minGear is returned afterwards anyway.
-			for (var gear = maxGear; gear > minGear; gear--) {
-				Gearbox.Gear = gear;
-				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularSpeed, true);
-				var currentPower = response.EnginePowerRequest;
-
-				var fullLoadPower = currentPower - response.DeltaFullLoad;
-				var reserve = 1 - (currentPower / fullLoadPower).Cast<Scalar>();
-
-				var inAngularSpeed = outAngularSpeed * Data.Gears[gear].Ratio;
-				var inTorque = response.ClutchPowerRequest / inAngularSpeed;
-
-				// if in shift curve and torque reserve is provided: return the current gear
-				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) &&
-					!IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
-					reserve >= torqueReserve) {
-					return gear;
-				}
-
-				// if over the up shift curve: return the previous gear (although it did not provide the required torque reserve)
-				if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && gear < maxGear) {
-					return gear + 1;
-				}
-			}
-			return minGear;
-		}
-
-		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		private bool SpeedTooLowForEngine(uint gear, PerSecond outAngularSpeed)
 		{
-			return GetGear(absTime, dt, outTorque, outEngineSpeed, Data.SkipGears, Data.TorqueReserve);
+			return (outAngularSpeed * Data.Gears[NextGear].Ratio).IsSmaller(DataBus.EngineIdleSpeed);
 		}
 
-		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		// original vecto2.2: (inAngularSpeed - IdleSpeed) / (RatedSpeed - IdleSpeed) >= 1.2
+		//                  =  inAngularSpeed - IdleSpeed >= 1.2*(RatedSpeed - IdleSpeed)
+		//                  =  inAngularSpeed >= 1.2*RatedSpeed - 0.2*IdleSpeed
+		private bool SpeedTooHighForEngine(uint gear, PerSecond outAngularSpeed)
 		{
-			PreviousGear = Gearbox.Gear;
+			return (outAngularSpeed * Data.Gears[NextGear].Ratio).IsGreaterOrEqual(1.2 * DataBus.EngineRatedSpeed -
+																					0.2 * DataBus.EngineIdleSpeed);
 		}
 
-		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
-		{
-			if (DataBus.VehicleStopped) {
-				return false;
-			}
-
-			var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmallerOrEqual(absTime);
-			if (!minimumShiftTimePassed) {
-				return false;
-			}
-
-			var speedTooLowForEngine = inAngularVelocity < DataBus.EngineIdleSpeed;
-			var speedToHighForEngine = (inAngularVelocity * Data.Gears[gear].Ratio - DataBus.EngineIdleSpeed) /
-										(DataBus.EngineRatedSpeed - DataBus.EngineIdleSpeed) >= 1.2;
-
-			// if angularSpeed is too high or too low to operate the engine, a shift is needed, regardless of shiftTime
-			if (gear > 1 && speedTooLowForEngine || gear < Data.Gears.Count && speedToHighForEngine) {
-				return true;
-			}
 
-			// todo: simulate traction interruption power request change after shift 
-			// and only shift if simulated power request still fullfills the shift conditions.
-
-			if (IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity) ||
-				IsAboveUpShiftCurve(gear, inTorque, inAngularVelocity)) {
-				return true;
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
+				NextGear--;
 			}
-
-			if (Data.EarlyShiftUp && gear < Data.Gears.Count) {
-				// try if next gear would provide enough torque reserve
-				var nextGear = gear + 1;
-
-				//todo: is initialize correct? shouldnt it be a dry run request? but gear has to be set in advance
-				var response = Gearbox.Initialize(nextGear, outTorque, outAngularVelocity);
-
-				var nextAngularVelocity = Data.Gears[nextGear].Ratio * outAngularVelocity;
-
-				if (!IsBelowDownShiftCurve(nextGear, response.ClutchPowerRequest / nextAngularVelocity, nextAngularVelocity)) {
-					var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
-					var reserve = 1 - (response.EnginePowerRequest / fullLoadPower).Cast<Scalar>();
-
-					if (reserve >= Data.TorqueReserve) {
-						return true;
-					}
-				}
+			while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
+				NextGear++;
 			}
 
+			return NextGear;
+		}
 
-			return false;
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		{
+			PreviousGear = Gearbox.Gear;
 		}
 
 		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
@@ -254,6 +211,98 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			// fallback: return first gear
 			return 1;
 		}
+
+		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+		{
+			// no shift when vehicle stands
+			if (DataBus.VehicleStopped) {
+				return false;
+			}
+
+			// emergency shift to not stall the engine ------------------------
+			NextGear = gear;
+			while (NextGear > 1 && SpeedTooLowForEngine(NextGear, outAngularVelocity)) {
+				NextGear--;
+			}
+			while (NextGear < Data.Gears.Count && SpeedTooHighForEngine(NextGear, outAngularVelocity)) {
+				NextGear++;
+			}
+			if (NextGear != gear) {
+				return true;
+			}
+
+
+			// normal shift when all requirements are fullfilled ------------------
+			var minimumShiftTimePassed = (lastShiftTime + Data.ShiftTime).IsSmaller(absTime);
+			if (!minimumShiftTimePassed) {
+				return false;
+			}
+
+			// down shift
+			while (IsBelowDownShiftCurve(NextGear, inTorque, inAngularVelocity)) {
+				NextGear--;
+				if (!Data.SkipGears) {
+					break;
+				}
+
+				var tmpGear = Gearbox.Gear;
+				Gearbox.Gear = NextGear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				Gearbox.Gear = tmpGear;
+
+				inAngularVelocity = Data.Gears[NextGear].Ratio * outAngularVelocity;
+				inTorque = response.ClutchPowerRequest / inAngularVelocity;
+			}
+
+			if (NextGear != gear) {
+				return true;
+			}
+
+			// upshift
+			while (IsAboveUpShiftCurve(NextGear, inTorque, inAngularVelocity)) {
+				NextGear++;
+				if (!Data.SkipGears) {
+					break;
+				}
+
+				var tmpGear = Gearbox.Gear;
+				Gearbox.Gear = NextGear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				Gearbox.Gear = tmpGear;
+
+				inAngularVelocity = Data.Gears[NextGear].Ratio * outAngularVelocity;
+				inTorque = response.ClutchPowerRequest / inAngularVelocity;
+			}
+
+			// early up shift to higher gear ---------------------------------------
+			if (Data.EarlyShiftUp && NextGear < Data.Gears.Count) {
+				// try if next gear would provide enough torque reserve
+				var tryNextGear = NextGear + 1;
+				var tmpGear = Gearbox.Gear;
+				Gearbox.Gear = tryNextGear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				Gearbox.Gear = tmpGear;
+
+				inAngularVelocity = Data.Gears[tryNextGear].Ratio * outAngularVelocity;
+				inTorque = response.ClutchPowerRequest / inAngularVelocity;
+
+				// if next gear supplied enough power reserve: take it
+				// otherwise take
+				if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
+					var fullLoadPower = response.EnginePowerRequest - response.DeltaFullLoad;
+					var reserve = 1 - (response.EnginePowerRequest / fullLoadPower).Cast<Scalar>();
+
+					if (reserve >= Data.TorqueReserve) {
+						NextGear = tryNextGear;
+					}
+				}
+			}
+
+			return (NextGear != gear);
+		}
+
+		public uint NextGear { get; set; }
 	}
 
 	//TODO Implement MTShiftStrategy
@@ -263,12 +312,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			throw new System.NotImplementedException();
+			throw new NotImplementedException();
 		}
 
 		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			throw new System.NotImplementedException();
+			throw new NotImplementedException();
 		}
 
 		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
@@ -278,10 +327,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			throw new NotImplementedException();
 		}
 
-
 		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			throw new System.NotImplementedException();
+			throw new NotImplementedException();
 		}
 	}
 
@@ -292,12 +340,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			throw new System.NotImplementedException();
+			throw new NotImplementedException();
 		}
 
 		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			throw new System.NotImplementedException();
+			throw new NotImplementedException();
 		}
 
 		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
@@ -307,10 +355,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			throw new NotImplementedException();
 		}
 
-
 		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			throw new System.NotImplementedException();
+			throw new NotImplementedException();
 		}
 	}
 
@@ -319,7 +366,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	{
 		public CustomShiftStrategy(GearboxData data, IDataBus dataBus) : base(data, dataBus) {}
 
-
 		public override bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
 			NewtonMeter inTorque,
 			PerSecond inAngularSpeed, uint gear, Second lastShiftTime)
diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs
index b5ef5de8534c7fe21adcac355413d5b6f1d4f608..bef29889a3e2b9bd180f3517704207afdf0096c3 100644
--- a/VectoCore/Utils/SI.cs
+++ b/VectoCore/Utils/SI.cs
@@ -925,6 +925,7 @@ namespace TUGraz.VectoCore.Utils
 		/// Returns the numerical sign of the SI.
 		/// </summary>
 		/// <returns>-1 if si &lt; 0. 0 if si==0, 1 if si &gt; 0.</returns>
+		[DebuggerHidden]
 		public int Sign()
 		{
 			return Math.Sign(Val);
diff --git a/VectoCoreTest/Integration/Truck40tPowerTrain.cs b/VectoCoreTest/Integration/Truck40tPowerTrain.cs
index c0e3963865f2570909e5aca689532b5055a77c87..576ea99097d79b48e0629963c2612d64269e825f 100644
--- a/VectoCoreTest/Integration/Truck40tPowerTrain.cs
+++ b/VectoCoreTest/Integration/Truck40tPowerTrain.cs
@@ -104,7 +104,7 @@ namespace TUGraz.VectoCore.Tests.Integration
 				TorqueReserve = 0.2,
 				StartTorqueReserve = 0.2,
 				SkipGears = true,
-				EarlyShiftUp = false,
+				EarlyShiftUp = true,
 			};
 		}
 
diff --git a/VectoCoreTest/Utils/GraphWriter.cs b/VectoCoreTest/Utils/GraphWriter.cs
index 8fc4f77561e280815330a67abfc17d22caf1c8bf..16200c31aaeaaa7872657cada645b30b2fbfa235 100644
--- a/VectoCoreTest/Utils/GraphWriter.cs
+++ b/VectoCoreTest/Utils/GraphWriter.cs
@@ -61,7 +61,7 @@ namespace TUGraz.VectoCore.Tests.Utils
 									.Select(v => v.Field<string>(ModalResultField.v_targ.GetName()))
 									.Select(v => string.IsNullOrWhiteSpace(v) ? "0" : v);
 
-							values += string.Format("|{0}|{1}", string.Join(",", x), string.Join(",", y3));
+							values += string.Format("|{0}|{1}|0|0", string.Join(",", x), string.Join(",", y3));
 						}
 
 						values = values.Replace("NaN", "0");