diff --git a/VectoCore/Models/SimulationComponent/IShiftStrategy.cs b/VectoCore/Models/SimulationComponent/IShiftStrategy.cs
index 55b5ee590408d50d84be52e7d66170494f1393c7..6b1c6f8e05606830e0d775f1594ce3d3e2516b9a 100644
--- a/VectoCore/Models/SimulationComponent/IShiftStrategy.cs
+++ b/VectoCore/Models/SimulationComponent/IShiftStrategy.cs
@@ -5,10 +5,50 @@ namespace TUGraz.VectoCore.Models.SimulationComponent
 {
 	public interface IShiftStrategy
 	{
+		/// <summary>
+		/// Checks if a shift operation is required.
+		/// </summary>
+		/// <param name="gear">The current gear.</param>
+		/// <param name="torque">The torque.</param>
+		/// <param name="angularSpeed">The angular speed.</param>
+		/// <returns></returns>
 		bool ShiftRequired(uint gear, NewtonMeter torque, PerSecond angularSpeed);
-		uint InitGear(NewtonMeter torque, PerSecond angularSpeed);
-		uint Engage(NewtonMeter outTorque, PerSecond outEngineSpeed, bool skipGears);
-		void Disengage(NewtonMeter outTorque, PerSecond outEngineSpeed);
+
+		/// <summary>
+		/// Returns an appropriate starting gear.
+		/// </summary>
+		/// <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);
+
+		/// <summary>
+		/// Engages a gear
+		/// </summary>
+		/// <param name="absTime">The abs time.</param>
+		/// <param name="dt">The dt.</param>
+		/// <param name="outTorque">The out torque.</param>
+		/// <param name="outEngineSpeed">The out engine speed.</param>
+		/// <returns></returns>
+		uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
+
+		/// <summary>
+		/// Disengages a gear.
+		/// </summary>
+		/// <param name="absTime">The abs time.</param>
+		/// <param name="dt">The dt.</param>
+		/// <param name="outTorque">The out torque.</param>
+		/// <param name="outEngineSpeed">The out engine speed.</param>
+		void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
+
+		/// <summary>
+		/// Gets or sets the gearbox.
+		/// </summary>
+		/// <value>
+		/// The gearbox.
+		/// </value>
 		Gearbox Gearbox { get; set; }
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 0ea75d234846339afefb1dce314eed708076c759..b9edeed54d218e6f02ad55f87fa66d7ccb990092 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -8,10 +8,6 @@ using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Utils;
 
-// TODO:
-// * EarlyUpshift (shift before outside of up-shift curve if outTorque reserve for the next higher gear is fullfilled)
-// * SkipGears (when already shifting to next gear, check if outTorque reserve is fullfilled for the overnext gear and eventually shift to it)
-
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
 	public class Gearbox : VectoSimulationComponent, IGearbox, ITnOutPort, ITnInPort, IClutchInfo
@@ -36,7 +32,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// </summary>
 		private Second _shiftTime = double.NegativeInfinity.SI<Second>();
 
-
 		/// <summary>
 		/// True if gearbox is disengaged (no gear is set).
 		/// </summary>
@@ -57,7 +52,6 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// </summary>
 		private PerSecond _previousInEnginespeed = 0.SI<PerSecond>();
 
-
 		public bool ClutchClosed(Second absTime)
 		{
 			return _shiftTime.IsSmaller(absTime);
@@ -106,10 +100,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		public IResponse Initialize(NewtonMeter torque, PerSecond engineSpeed)
 		{
+			var response = NextComponent.Initialize(torque, engineSpeed);
+
 			_shiftTime = double.NegativeInfinity.SI<Second>();
-			Gear = _strategy.InitGear(torque, engineSpeed);
-			_disengaged = false;
-			return NextComponent.Initialize(torque, engineSpeed);
+			Gear = 0; //_strategy.InitGear(torque, engineSpeed);
+			_disengaged = true;
+
+			return response;
 		}
 
 		/// <summary>
@@ -180,9 +177,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				};
 			}
 
-			if (DataBus.VehicleSpeed.IsEqual(0)) {
-				Gear = _strategy.Engage(outTorque, outEngineSpeed, Data.SkipGears);
-			}
+			//if (DataBus.VehicleSpeed.IsEqual(0)) {
+			//	Gear = _strategy.Engage(outTorque, outEngineSpeed, Data.SkipGears);
+			//}
 
 			var response = NextComponent.Request(absTime, dt, 0.SI<NewtonMeter>(), null);
 			response.GearboxPowerRequest = outTorque * outEngineSpeed;
@@ -204,8 +201,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		{
 			// Set a Gear if no gear was set
 			if (_disengaged) {
-				Gear = _strategy.Engage(outTorque, outEngineSpeed, Data.SkipGears);
 				_disengaged = false;
+				Gear = DataBus.VehicleSpeed.IsEqual(0)
+					? _strategy.InitGear(absTime, dt, outTorque, outEngineSpeed) // initGear if speed was 0
+					: _strategy.Engage(absTime, dt, outTorque, outEngineSpeed);
+
 				Log.Debug("Gearbox engaged gear {0}", Gear);
 			}
 
@@ -233,13 +233,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			if (isShiftAllowed && _strategy.ShiftRequired(Gear, inTorque, inEngineSpeed)) {
 				_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);
+
 				_disengaged = true;
-				_strategy.Disengage(outTorque, outEngineSpeed);
+				_strategy.Disengage(absTime, dt, outTorque, outEngineSpeed);
 				Log.Info("Gearbox disengaged");
-
-				Log.Debug("Gearbox is shifting. absTime: {0}, shiftTime: {1}, outTorque:{2}, outEngineSpeed: {3}",
-					absTime, _shiftTime, outTorque, outEngineSpeed);
-
+				
 				return new ResponseGearShift {
 					Source = this,
 					SimulationInterval = Data.TractionInterruption,
diff --git a/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
index dce629977e008c394530627105b7e4df699d21ad..7239eb8c0850b2beab29ec40d6e665f409e5a198 100644
--- a/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
@@ -1,16 +1,20 @@
-using TUGraz.VectoCore.Exceptions;
+using System;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
+	// TODO:
+	// * EarlyUpshift (shift before outside of up-shift curve if outTorque reserve for the next higher gear is fullfilled)
+
 	public abstract class ShiftStrategy : IShiftStrategy
 	{
-		public abstract uint Engage(NewtonMeter torque, PerSecond angularSpeed, bool skipGears);
-		public abstract void Disengage(NewtonMeter outTorque, PerSecond outEngineSpeed);
+		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(uint gear, NewtonMeter torque, PerSecond angularSpeed);
-		public abstract uint InitGear(NewtonMeter torque, PerSecond angularSpeed);
+		public abstract uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed);
 
 		protected GearboxData Data;
 		public Gearbox Gearbox { get; set; }
@@ -24,7 +28,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// <summary>
 		/// Tests if the gearbox should shift down.
 		/// </summary>
-		protected bool ShouldShiftDown(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		protected virtual bool IsBelowDownShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
 		{
 			if (gear <= 1) {
 				return false;
@@ -37,7 +41,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		/// <summary>
 		/// Tests if the gearbox should shift up.
 		/// </summary>
-		protected bool ShouldShiftUp(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		protected virtual bool IsAboveUpShiftCurve(uint gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
 		{
 			if (gear >= Data.Gears.Count) {
 				return false;
@@ -72,56 +76,55 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 	public class AMTShiftStrategy : ShiftStrategy
 	{
-		protected uint LastGear;
+		protected uint PreviousGear;
 
 		public AMTShiftStrategy(GearboxData data) : base(data)
 		{
-			LastGear = 1;
+			PreviousGear = 1;
 		}
 
-		public uint GetGear(uint gear, NewtonMeter outTorque, PerSecond outEngineSpeed, bool skipGears)
+		private uint GetGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed, bool skipGears,
+			double torqueReserve)
 		{
-			var loopCount = Data.Gears.Count; // protection against infinite loops
-			do {
-				var inEngineSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
-				var inTorque = Data.Gears[gear].LossMap.GearboxInTorque(inEngineSpeed, outTorque);
-				if (ShouldShiftUp(gear, inTorque, inEngineSpeed)) {
-					gear++;
-					continue;
-				}
+			var maxGear = (uint)(skipGears ? Data.Gears.Count : Math.Min(PreviousGear + 1, Data.Gears.Count));
+			var minGear = skipGears ? 1 : Math.Max(PreviousGear - 1, 1);
 
-				if (ShouldShiftDown(gear, inTorque, inEngineSpeed)) {
-					gear--;
-					continue;
-				}
-				break;
-			} while (skipGears && loopCount-- > 0);
+			for (var gear = maxGear; gear > minGear; gear--) {
+				Gearbox.Gear = gear;
+				var response = (ResponseDryRun)Gearbox.Request(absTime, dt, outTorque, outEngineSpeed, true);
+				var currentPower = response.EnginePowerRequest;
 
-			if (gear == 0) {
-				throw new VectoSimulationException("Could not find gear! outTorque: {0}, outEngineSpeed: {1}, skipGears: {2}",
-					outTorque, outEngineSpeed, skipGears);
+				var fullLoadPower = currentPower - response.DeltaFullLoad;
+				var reserve = 1 - (currentPower / fullLoadPower).Cast<Scalar>();
+
+				var inAngularSpeed = outEngineSpeed * Data.Gears[gear].Ratio;
+				var inTorque = currentPower / inAngularSpeed;
+				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && reserve >= torqueReserve) {
+					return gear;
+				}
 			}
-			return gear;
+			return minGear;
 		}
 
-		public override uint Engage(NewtonMeter outTorque, PerSecond outEngineSpeed, bool skipGears)
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			return GetGear(LastGear, outTorque, outEngineSpeed, skipGears);
+			return GetGear(absTime, dt, outTorque, outEngineSpeed, Data.SkipGears, Data.TorqueReserve);
 		}
 
-		public override void Disengage(NewtonMeter outTorque, PerSecond outEngineSpeed)
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			LastGear = GetGear(Gearbox.Gear, outTorque, outEngineSpeed, Data.SkipGears);
+			PreviousGear = GetGear(absTime, dt, outTorque, outEngineSpeed, Data.SkipGears, Data.TorqueReserve);
 		}
 
 		public override bool ShiftRequired(uint gear, NewtonMeter torque, PerSecond angularSpeed)
 		{
-			return ShouldShiftDown(gear, torque, angularSpeed) || ShouldShiftUp(gear, torque, angularSpeed);
+			return IsBelowDownShiftCurve(gear, torque, angularSpeed) || IsAboveUpShiftCurve(gear, torque, angularSpeed);
 		}
 
-		public override uint InitGear(NewtonMeter torque, PerSecond angularSpeed)
+
+		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
-			return Engage(torque, angularSpeed, true);
+			return GetGear(absTime, dt, outTorque, outEngineSpeed, true, Data.StartTorqueReserve);
 		}
 	}
 
@@ -130,12 +133,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	{
 		public MTShiftStrategy(GearboxData data) : base(data) {}
 
-		public override uint Engage(NewtonMeter torque, PerSecond angularSpeed, bool skipGears)
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
 			throw new System.NotImplementedException();
 		}
 
-		public override void Disengage(NewtonMeter outTorque, PerSecond outEngineSpeed)
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
 			throw new System.NotImplementedException();
 		}
@@ -145,7 +148,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			throw new System.NotImplementedException();
 		}
 
-		public override uint InitGear(NewtonMeter torque, PerSecond angularSpeed)
+		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
 			throw new System.NotImplementedException();
 		}
@@ -156,12 +159,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	{
 		public ATShiftStrategy(GearboxData data) : base(data) {}
 
-		public override uint Engage(NewtonMeter torque, PerSecond angularSpeed, bool skipGears)
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
 			throw new System.NotImplementedException();
 		}
 
-		public override void Disengage(NewtonMeter outTorque, PerSecond outEngineSpeed)
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
 			throw new System.NotImplementedException();
 		}
@@ -171,7 +174,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			throw new System.NotImplementedException();
 		}
 
-		public override uint InitGear(NewtonMeter torque, PerSecond angularSpeed)
+		public override uint InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
 		{
 			throw new System.NotImplementedException();
 		}