diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
index 7c95e3401ef4cce19cecc8d394d0d9aa65f44566..1aea6ae89b904b782bc16a84b2c322d466d89a3d 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PowertrainBuilder.cs
@@ -49,6 +49,7 @@ using TUGraz.VectoCore.Models.SimulationComponent;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
 using TUGraz.VectoCore.Models.SimulationComponent.Impl;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
 using TUGraz.VectoCore.Models.SimulationComponent.Strategies;
 using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
@@ -1577,13 +1578,92 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			}
 		}
 
+		public static string GetShiftStrategyName(GearboxType gearboxType, VectoSimulationJobType jobType,
+			bool isTestPowerTrain = false)
+		{
+			switch (gearboxType) {
+				case GearboxType.AMT:
+					switch (jobType) {
+						case VectoSimulationJobType.ConventionalVehicle:
+						case VectoSimulationJobType.ParallelHybridVehicle:
+
+							return AMTShiftStrategyOptimized.Name;
+						//return new AMTShiftStrategyOptimized(container);
+						case VectoSimulationJobType.BatteryElectricVehicle:
+						case VectoSimulationJobType.SerialHybridVehicle:
+							return PEVAMTShiftStrategy.Name;
+						//return new PEVAMTShiftStrategy(container);
+						default:
+							throw new VectoException(
+								"no default gearshift strategy available for gearbox type {0} and job type {1}",
+								gearboxType, jobType);
+					}
+				case GearboxType.MT:
+					return MTShiftStrategy.Name;
+				//return new MTShiftStrategy(container);
+
+				case GearboxType.ATPowerSplit:
+				case GearboxType.ATSerial:
+					switch (jobType) {
+						case VectoSimulationJobType.ParallelHybridVehicle:
+						case VectoSimulationJobType.ConventionalVehicle:
+							return ATShiftStrategyOptimized.Name;
+						//return new ATShiftStrategyOptimized(container);
+						case VectoSimulationJobType.SerialHybridVehicle:
+						case VectoSimulationJobType.BatteryElectricVehicle:
+							return APTNShiftStrategy.Name;
+						//return new APTNShiftStrategy(container);
+						default:
+							throw new VectoException(
+								"no default gearshift strategy available for gearbox type {0} and job type {1}",
+								gearboxType, jobType);
+					}
+				case GearboxType.APTN:
+					switch (jobType) {
+						case VectoSimulationJobType.ParallelHybridVehicle:
+						case VectoSimulationJobType.SerialHybridVehicle:
+						case VectoSimulationJobType.BatteryElectricVehicle:
+						case VectoSimulationJobType.IEPC_E:
+						case VectoSimulationJobType.IEPC_S:
+							return APTNShiftStrategy.Name;
+						//return new APTNShiftStrategy(container);
+						case VectoSimulationJobType.ConventionalVehicle when isTestPowerTrain:
+							return null;
+						default:
+							throw new ArgumentException(
+								"APT-N Gearbox is only applicable on hybrids and battery electric vehicles.");
+					}
+				case GearboxType.IHPC:
+					switch (jobType) {
+						case VectoSimulationJobType.IHPC:
+							return AMTShiftStrategyOptimized.Name;
+						//return new AMTShiftStrategyOptimized(container);
+						default:
+							throw new ArgumentException(
+								"IHPC Gearbox is only applicable on hybrid vehicle of type IHPC.");
+					}
+				default:
+					throw new ArgumentOutOfRangeException("GearboxType", gearboxType,
+						"VECTO can not automatically derive shift strategy for GearboxType.");
+			}
+		}
+
+
 		public static IShiftStrategy GetShiftStrategy(IVehicleContainer container)
 		{
 			var runData = container.RunData;
 
-			switch (runData.GearboxData.Type) {
+			var gearboxType = runData.GearboxData.Type;
+			var jobType = runData.JobType;
+			var isTestPowerTrain = container.IsTestPowertrain;
+
+			var shiftStrategyName = GetShiftStrategyName(gearboxType, jobType, isTestPowerTrain);
+			runData.ShiftStrategy = shiftStrategyName;
+			return ShiftStrategy.Create(container, runData.ShiftStrategy);
+
+			switch (gearboxType) {
 				case GearboxType.AMT:
-					switch (runData.JobType) {
+					switch (jobType) {
 						case VectoSimulationJobType.ConventionalVehicle:
 						case VectoSimulationJobType.ParallelHybridVehicle:
 							runData.ShiftStrategy = AMTShiftStrategyOptimized.Name;
@@ -1595,7 +1675,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 						default:
 							throw new VectoException(
 								"no default gearshift strategy available for gearbox type {0} and job type {1}",
-								runData.GearboxData.Type, runData.JobType);
+								gearboxType, jobType);
 					}
 				case GearboxType.MT:
 					runData.ShiftStrategy = MTShiftStrategy.Name;
@@ -1603,7 +1683,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 				case GearboxType.ATPowerSplit:
 				case GearboxType.ATSerial:
-					switch (runData.JobType) {
+					switch (jobType) {
 						case VectoSimulationJobType.ParallelHybridVehicle:
 						case VectoSimulationJobType.ConventionalVehicle:
 							runData.ShiftStrategy = ATShiftStrategyOptimized.Name;
@@ -1615,10 +1695,10 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 						default:
 							throw new VectoException(
 								"no default gearshift strategy available for gearbox type {0} and job type {1}",
-								runData.GearboxData.Type, runData.JobType);
+								gearboxType, jobType);
 					}
 				case GearboxType.APTN:
-					switch (runData.JobType) {
+					switch (jobType) {
 						case VectoSimulationJobType.ParallelHybridVehicle:
 						case VectoSimulationJobType.SerialHybridVehicle:
 						case VectoSimulationJobType.BatteryElectricVehicle:
@@ -1632,7 +1712,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 							throw new ArgumentException("APT-N Gearbox is only applicable on hybrids and battery electric vehicles.");
 					}
 				case GearboxType.IHPC:
-					switch (runData.JobType) {
+					switch (jobType) {
 						case VectoSimulationJobType.IHPC:
 							runData.ShiftStrategy = AMTShiftStrategyOptimized.Name;
 							return new AMTShiftStrategyOptimized(container);
@@ -1640,10 +1720,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 							throw new ArgumentException("IHPC Gearbox is only applicable on hybrid vehicle of type IHPC.");
 					}
 				default:
-					throw new ArgumentOutOfRangeException("GearboxType", runData.GearboxData.Type, "VECTO can not automatically derive shift strategy for GearboxType.");
+					throw new ArgumentOutOfRangeException("GearboxType", gearboxType, "VECTO can not automatically derive shift strategy for GearboxType.");
 			}
 		}
 
+		
+
 		private static IGearbox GetSimpleGearbox(IVehicleContainer container, VectoRunData runData)
 		{
 			if (runData.GearboxData.Type.AutomaticTransmission() && runData.GearboxData.Type != GearboxType.APTN && runData.GearboxData.Type != GearboxType.IHPC) {
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
index 0e2910e5e1eaf4937ee0ef2367616ae02e11c3a2..167bf5bf84821987d1e493cda36051d68ba85c36 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/HybridController.cs
@@ -14,6 +14,7 @@ using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
 using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs
similarity index 95%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs
index 827ff73e1e6fec1fdb6259385a770dce3743d104..59e58915f7c74bfc84941f8107dc9bb4767114b8 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategy.cs
@@ -1,394 +1,409 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2019 European Union
-*
-* Developed by Graz University of Technology,
-*              Institute of Internal Combustion Engines and Thermodynamics,
-*              Institute of Technical Informatics
-*
-* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
-* by the European Commission - subsequent versions of the EUPL (the "Licence");
-* You may not use VECTO except in compliance with the Licence.
-* You may obtain a copy of the Licence at:
-*
-* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
-*
-* Unless required by applicable law or agreed to in writing, VECTO
-* distributed under the Licence is distributed on an "AS IS" basis,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Licence for the specific language governing permissions and
-* limitations under the Licence.
-*
-* Authors:
-*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
-*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
-*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
-*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
-*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
-*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
-*/
-
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	/// <summary>
-	/// AMTShiftStrategy implements the AMT Shifting Behaviour.
-	/// </summary>
-	public class AMTShiftStrategy : ShiftStrategy
-	{
-		//protected readonly GearshiftPosition MaxStartGear;
-		protected GearshiftPosition _nextGear;
-		private GearshiftPosition DesiredGearRoadsweeping;
-
-		public AMTShiftStrategy(IVehicleContainer dataBus) : base(dataBus)
-		{
-			var runData = dataBus.RunData;
-			EarlyShiftUp = true;
-			SkipGears = true;
-			if (runData.EngineData == null) {
-				return;
-			}
-			var transmissionRatio = runData.AxleGearData.AxleGear.Ratio *
-									(runData.AngledriveData?.Angledrive.Ratio ?? 1.0) /
-									runData.VehicleData.DynamicTyreRadius;
-			var minEngineSpeed = (runData.EngineData.FullLoadCurves[0].RatedSpeed - runData.EngineData.IdleSpeed) *
-								Constants.SimulationSettings.ClutchClosingSpeedNorm + runData.EngineData.IdleSpeed;
-
-			DesiredGearRoadsweeping = runData.DriverData?.PTODriveRoadsweepingGear;
-
-			MaxStartGear = GearboxModelData.GearList.First();
-			foreach (var gear in GearboxModelData.GearList.Reverse()) {
-				var gearData = GearboxModelData.Gears[gear.Gear];
-				if (GearshiftParams.StartSpeed * transmissionRatio * gearData.Ratio > minEngineSpeed) {
-					MaxStartGear = gear;
-					break;
-				}
-			}
-		}
-
-		private bool SpeedTooLowForEngine(GearshiftPosition gear, PerSecond outAngularSpeed)
-		{
-			return (outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsSmaller(DataBus.EngineInfo.EngineIdleSpeed);
-		}
-
-		private bool SpeedTooHighForEngine(GearshiftPosition gear, PerSecond outAngularSpeed)
-		{
-			return
-				(outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed,
-																				DataBus.EngineInfo.EngineN95hSpeed - 1.RPMtoRad()));
-		}
-
-		public override GearshiftPosition NextGear => _nextGear;
-
-		public override ShiftPolygon ComputeDeclarationShiftPolygon(
-			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears,
-			CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
-		{
-			return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon(
-				i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius);
-		}
-
-		public static string Name => "AMT - Classic";
-
-		public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear, outAngularVelocity)) {
-				_nextGear = Gears.Predecessor(_nextGear);
-			}
-			while (Gears.HasSuccessor(_nextGear) && SpeedTooHighForEngine(_nextGear, outAngularVelocity)) {
-				_nextGear = Gears.Successor(_nextGear);
-			}
-
-			return _nextGear;
-		}
-
-		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) {}
-
-		public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) {
-				return InitStartGear(absTime, outTorque, outAngularVelocity);
-			}
-
-			foreach (var gear in Gears.Reverse()) {
-				var selected = gear;
-				var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity);
-
-				var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
-				var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad;
-				var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
-				var inTorque = response.Clutch.PowerRequest / inAngularSpeed;
-
-				// if in shift curve and torque reserve is provided: return the current gear
-				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
-					reserve >= GearshiftParams.StartTorqueReserve) {
-					if ((inAngularSpeed - DataBus.EngineInfo.EngineIdleSpeed) / (DataBus.EngineInfo.EngineRatedSpeed - DataBus.EngineInfo.EngineIdleSpeed) <
-						Constants.SimulationSettings.ClutchClosingSpeedNorm && Gears.HasPredecessor(gear)) {
-						selected = Gears.Predecessor(gear);
-					}
-					_nextGear = selected;
-					return selected;
-				}
-
-				// if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve)
-				if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && Gears.HasSuccessor(gear)) {
-					selected = Gears.Successor(gear);
-					_nextGear = selected;
-					return selected;
-				}
-			}
-
-			// fallback: return first gear
-			_nextGear = Gears.First();
-			return _nextGear;
-		}
-
-		private GearshiftPosition InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			foreach (var gear in Gears.IterateGears(MaxStartGear, Gears.First())) {
-				var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
-
-				var ratedSpeed = DataBus.EngineInfo.EngineRatedSpeed;
-				if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) {
-					continue;
-				}
-
-				var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity);
-
-				var fullLoadPower = response.Engine.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad;
-				var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
-
-				if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineIdleSpeed && reserve >= GearshiftParams.StartTorqueReserve) {
-					_nextGear = gear;
-					return gear;
-				}
-			}
-			_nextGear = Gears.First();
-			return _nextGear;
-		}
-
-		protected override bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque,
-			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear,
-			Second lastShiftTime, IResponse response)
-		{
-			// no shift when vehicle stands
-			if (DataBus.VehicleInfo.VehicleStopped) {
-				return false;
-			}
-
-			// emergency shift to not stall the engine ------------------------
-			if (Gears.First().Equals(gear) &&
-				SpeedTooLowForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) {
-				return true;
-			}
-
-			_nextGear = gear;
-			while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear,
-				inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) {
-				_nextGear = Gears.Predecessor(_nextGear);
-			}
-
-			while (Gears.HasSuccessor(_nextGear) &&
-					SpeedTooHighForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) {
-				_nextGear = Gears.Successor(_nextGear);
-			}
-
-			if (!_nextGear.Equals(gear)) {
-				return true;
-			}
-
-			// PTO Active while drive (roadsweeping) shift rules
-			if (DataBus.DrivingCycleInfo.CycleData.LeftSample.PTOActive == PTOActivity.PTOActivityRoadSweeping) {
-				if (gear.Equals(DesiredGearRoadsweeping)) {
-					return false;
-				}
-
-				if (gear > DesiredGearRoadsweeping) {
-					if (IsAboveDownShiftCurve(DesiredGearRoadsweeping, inTorque, inAngularVelocity)) {
-						_nextGear = DesiredGearRoadsweeping;
-						return true;
-					}
-				}
-
-				if (gear < DesiredGearRoadsweeping) {
-					if (!SpeedTooHighForEngine(
-						DesiredGearRoadsweeping, inAngularVelocity / GearboxModelData.Gears[DesiredGearRoadsweeping.Gear].Ratio)) {
-						_nextGear = DesiredGearRoadsweeping;
-						return true;
-					}
-				}
-			}
-
-			// normal shift when all requirements are fullfilled ------------------
-			var minimumShiftTimePassed =
-				(lastShiftTime + GearshiftParams.TimeBetweenGearshifts).IsSmallerOrEqual(absTime);
-			if (!minimumShiftTimePassed) {
-				return false;
-			}
-
-			_nextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
-				response);
-			if (!_nextGear.Equals(gear)) {
-				return true;
-			}
-
-			_nextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
-				response);
-
-			return !_nextGear.Equals(gear);
-		}
-
-		protected virtual GearshiftPosition CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response)
-		{
-			// if the driver's intention is _not_ to accelerate or drive along then don't upshift
-			if (DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Driving) {
-				return currentGear;
-			}
-			if ((absTime - _gearbox.LastDownshift).IsSmaller(GearshiftParams.UpshiftAfterDownshiftDelay)) {
-				return currentGear;
-			}
-			var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response);
-			if (nextGear.Equals(currentGear)) {
-				return nextGear;
-			}
-
-			// estimate acceleration for selected gear
-			if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(GearshiftParams.UpshiftMinAcceleration)) {
-				// if less than 0.1 for next gear, don't shift
-				if (nextGear.Gear - currentGear.Gear == 1) {
-					return currentGear;
-				}
-				// if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift!
-				if (nextGear.Gear > currentGear.Gear &&
-					EstimateAccelerationForGear(Gears.Successor(currentGear), outAngularVelocity)
-						.IsSmaller(GearshiftParams.UpshiftMinAcceleration)) {
-					return currentGear;
-				}
-				nextGear = Gears.Successor(currentGear);
-			}
-
-			return nextGear;
-		}
-
-		protected virtual GearshiftPosition CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response)
-		{
-			if ((absTime - _gearbox.LastUpshift).IsSmaller(GearshiftParams.DownshiftAfterUpshiftDelay)) {
-				return currentGear;
-			}
-			return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response);
-		}
-
-		protected virtual GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
-		{
-			// upshift
-			if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				currentGear = Gears.Successor(currentGear);
-
-				while (SkipGears && Gears.HasSuccessor(currentGear)) {
-					currentGear = Gears.Successor(currentGear);
-					var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear);
-
-					inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity;
-					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
-
-					var maxTorque = VectoMath.Min(
-						response.Engine.DynamicFullLoadPower /
-						((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2),
-						currentGear.Equals(Gears.First())
-							? double.MaxValue.SI<NewtonMeter>()
-							: GearboxModelData.Gears[currentGear.Gear].ShiftPolygon
-								.InterpolateDownshift(response.Engine.EngineSpeed));
-					var reserve = 1 - inTorque.Value() / maxTorque.Value();
-
-					if (reserve >= 0 /*ModelData.TorqueReserve */ && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-						continue;
-					}
-
-					currentGear = Gears.Predecessor(currentGear);
-					break;
-				}
-			}
-
-			// early up shift to higher gear ---------------------------------------
-			if (EarlyShiftUp && Gears.HasSuccessor(currentGear)) {
-				currentGear = CheckEarlyUpshift(absTime, dt, outTorque, outAngularVelocity, currentGear, response1);
-			}
-			return currentGear;
-		}
-
-		protected virtual GearshiftPosition CheckEarlyUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition currentGear, IResponse response1)
-		{
-			// try if next gear would provide enough torque reserve
-			var tryNextGear = Gears.Successor(currentGear);
-			var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear);
-
-			var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
-			var inTorque = response.Clutch.PowerRequest / inAngularVelocity;
-
-			// if next gear supplied enough power reserve: take it
-			// otherwise take
-			if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
-				var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad;
-				var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
-
-				if (reserve >= GearshiftParams.TorqueReserve) {
-					currentGear = tryNextGear;
-				}
-			}
-			return currentGear;
-		}
-
-		
-		protected virtual GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response)
-		{
-			// down shift
-			if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				currentGear = Gears.Predecessor(currentGear);
-				//while (SkipGears && currentGear > 1) {
-				//	currentGear--;
-				//	var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear);
-
-				//	inAngularVelocity = ModelData.Gears[currentGear].Ratio * outAngularVelocity;
-				//	inTorque = response.ClutchPowerRequest / inAngularVelocity;
-				//	var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2),
-				//		currentGear > 1
-				//			? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed)
-				//			: double.MaxValue.SI<NewtonMeter>());
-				//	var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value();
-				//	if (reserve >= ModelData.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				//		continue;
-				//	}
-				//	currentGear++;
-				//	break;
-				//}
-			}
-			return currentGear;
-		}
-
-		protected virtual ResponseDryRun RequestDryRunWithGear(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition tryNextGear)
-		{
-			var tmpGear = Gearbox.Gear;
-			_gearbox.Gear = tryNextGear;
-			var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-			_gearbox.Gear = tmpGear;
-			return response;
-		}
-	}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2019 European Union
+*
+* Developed by Graz University of Technology,
+*              Institute of Internal Combustion Engines and Thermodynamics,
+*              Institute of Technical Informatics
+*
+* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
+* by the European Commission - subsequent versions of the EUPL (the "Licence");
+* You may not use VECTO except in compliance with the Licence.
+* You may obtain a copy of the Licence at:
+*
+* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
+*
+* Unless required by applicable law or agreed to in writing, VECTO
+* distributed under the Licence is distributed on an "AS IS" basis,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the Licence for the specific language governing permissions and
+* limitations under the Licence.
+*
+* Authors:
+*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
+*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
+*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
+*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
+*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
+*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
+*/
+
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class AMTShiftStrategyPolygonCalculator : IShiftPolygonCalculator
+	{
+		public ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears,
+			CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		{
+			return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon(
+				i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius);
+		}
+	}
+
+	/// <summary>
+	/// AMTShiftStrategy implements the AMT Shifting Behaviour.
+	/// </summary>
+	public class AMTShiftStrategy : ShiftStrategy
+	{
+		//protected readonly GearshiftPosition MaxStartGear;
+		protected GearshiftPosition _nextGear;
+		private GearshiftPosition DesiredGearRoadsweeping;
+		private readonly IShiftPolygonCalculator _shiftPolygonCalculator;
+
+		public AMTShiftStrategy(IVehicleContainer dataBus) : base(dataBus)
+		{
+			var runData = dataBus.RunData;
+			EarlyShiftUp = true;
+			SkipGears = true;
+			if (runData.EngineData == null) {
+				return;
+			}
+
+			_shiftPolygonCalculator = ShiftPolygonCalculator.Create(Name, null);
+			var transmissionRatio = runData.AxleGearData.AxleGear.Ratio *
+									(runData.AngledriveData?.Angledrive.Ratio ?? 1.0) /
+									runData.VehicleData.DynamicTyreRadius;
+			var minEngineSpeed = (runData.EngineData.FullLoadCurves[0].RatedSpeed - runData.EngineData.IdleSpeed) *
+								Constants.SimulationSettings.ClutchClosingSpeedNorm + runData.EngineData.IdleSpeed;
+
+			DesiredGearRoadsweeping = runData.DriverData?.PTODriveRoadsweepingGear;
+
+			MaxStartGear = GearboxModelData.GearList.First();
+			foreach (var gear in GearboxModelData.GearList.Reverse()) {
+				var gearData = GearboxModelData.Gears[gear.Gear];
+				if (GearshiftParams.StartSpeed * transmissionRatio * gearData.Ratio > minEngineSpeed) {
+					MaxStartGear = gear;
+					break;
+				}
+			}
+		}
+
+		private bool SpeedTooLowForEngine(GearshiftPosition gear, PerSecond outAngularSpeed)
+		{
+			return (outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsSmaller(DataBus.EngineInfo.EngineIdleSpeed);
+		}
+
+		private bool SpeedTooHighForEngine(GearshiftPosition gear, PerSecond outAngularSpeed)
+		{
+			return
+				(outAngularSpeed * GearboxModelData.Gears[gear.Gear].Ratio).IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed,
+																				DataBus.EngineInfo.EngineN95hSpeed - 1.RPMtoRad()));
+		}
+
+		public override GearshiftPosition NextGear => _nextGear;
+
+		public override ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears,
+			CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		{
+			return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType,
+				i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius, electricMotorData);
+		}
+
+		public static string Name => "AMT - Classic";
+
+		public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear, outAngularVelocity)) {
+				_nextGear = Gears.Predecessor(_nextGear);
+			}
+			while (Gears.HasSuccessor(_nextGear) && SpeedTooHighForEngine(_nextGear, outAngularVelocity)) {
+				_nextGear = Gears.Successor(_nextGear);
+			}
+
+			return _nextGear;
+		}
+
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity) {}
+
+		public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) {
+				return InitStartGear(absTime, outTorque, outAngularVelocity);
+			}
+
+			foreach (var gear in Gears.Reverse()) {
+				var selected = gear;
+				var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity);
+
+				var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
+				var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad;
+				var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
+				var inTorque = response.Clutch.PowerRequest / inAngularSpeed;
+
+				// if in shift curve and torque reserve is provided: return the current gear
+				if (!IsBelowDownShiftCurve(gear, inTorque, inAngularSpeed) && !IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) &&
+					reserve >= GearshiftParams.StartTorqueReserve) {
+					if ((inAngularSpeed - DataBus.EngineInfo.EngineIdleSpeed) / (DataBus.EngineInfo.EngineRatedSpeed - DataBus.EngineInfo.EngineIdleSpeed) <
+						Constants.SimulationSettings.ClutchClosingSpeedNorm && Gears.HasPredecessor(gear)) {
+						selected = Gears.Predecessor(gear);
+					}
+					_nextGear = selected;
+					return selected;
+				}
+
+				// if over the up shift curve: return the previous gear (even thou it did not provide the required torque reserve)
+				if (IsAboveUpShiftCurve(gear, inTorque, inAngularSpeed) && Gears.HasSuccessor(gear)) {
+					selected = Gears.Successor(gear);
+					_nextGear = selected;
+					return selected;
+				}
+			}
+
+			// fallback: return first gear
+			_nextGear = Gears.First();
+			return _nextGear;
+		}
+
+		private GearshiftPosition InitStartGear(Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			foreach (var gear in Gears.IterateGears(MaxStartGear, Gears.First())) {
+				var inAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
+
+				var ratedSpeed = DataBus.EngineInfo.EngineRatedSpeed;
+				if (inAngularSpeed > ratedSpeed || inAngularSpeed.IsEqual(0)) {
+					continue;
+				}
+
+				var response = _gearbox.Initialize(absTime, gear, outTorque, outAngularVelocity);
+
+				var fullLoadPower = response.Engine.DynamicFullLoadPower; //EnginePowerRequest - response.DeltaFullLoad;
+				var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
+
+				if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineIdleSpeed && reserve >= GearshiftParams.StartTorqueReserve) {
+					_nextGear = gear;
+					return gear;
+				}
+			}
+			_nextGear = Gears.First();
+			return _nextGear;
+		}
+
+		protected override bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque,
+			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear,
+			Second lastShiftTime, IResponse response)
+		{
+			// no shift when vehicle stands
+			if (DataBus.VehicleInfo.VehicleStopped) {
+				return false;
+			}
+
+			// emergency shift to not stall the engine ------------------------
+			if (Gears.First().Equals(gear) &&
+				SpeedTooLowForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) {
+				return true;
+			}
+
+			_nextGear = gear;
+			while (Gears.HasPredecessor(_nextGear) && SpeedTooLowForEngine(_nextGear,
+				inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) {
+				_nextGear = Gears.Predecessor(_nextGear);
+			}
+
+			while (Gears.HasSuccessor(_nextGear) &&
+					SpeedTooHighForEngine(_nextGear, inAngularVelocity / GearboxModelData.Gears[gear.Gear].Ratio)) {
+				_nextGear = Gears.Successor(_nextGear);
+			}
+
+			if (!_nextGear.Equals(gear)) {
+				return true;
+			}
+
+			// PTO Active while drive (roadsweeping) shift rules
+			if (DataBus.DrivingCycleInfo.CycleData.LeftSample.PTOActive == PTOActivity.PTOActivityRoadSweeping) {
+				if (gear.Equals(DesiredGearRoadsweeping)) {
+					return false;
+				}
+
+				if (gear > DesiredGearRoadsweeping) {
+					if (IsAboveDownShiftCurve(DesiredGearRoadsweeping, inTorque, inAngularVelocity)) {
+						_nextGear = DesiredGearRoadsweeping;
+						return true;
+					}
+				}
+
+				if (gear < DesiredGearRoadsweeping) {
+					if (!SpeedTooHighForEngine(
+						DesiredGearRoadsweeping, inAngularVelocity / GearboxModelData.Gears[DesiredGearRoadsweeping.Gear].Ratio)) {
+						_nextGear = DesiredGearRoadsweeping;
+						return true;
+					}
+				}
+			}
+
+			// normal shift when all requirements are fullfilled ------------------
+			var minimumShiftTimePassed =
+				(lastShiftTime + GearshiftParams.TimeBetweenGearshifts).IsSmallerOrEqual(absTime);
+			if (!minimumShiftTimePassed) {
+				return false;
+			}
+
+			_nextGear = CheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
+				response);
+			if (!_nextGear.Equals(gear)) {
+				return true;
+			}
+
+			_nextGear = CheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
+				response);
+
+			return !_nextGear.Equals(gear);
+		}
+
+		protected virtual GearshiftPosition CheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response)
+		{
+			// if the driver's intention is _not_ to accelerate or drive along then don't upshift
+			if (DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Accelerating && DataBus.DriverInfo.DriverBehavior != DrivingBehavior.Driving) {
+				return currentGear;
+			}
+			if ((absTime - _gearbox.LastDownshift).IsSmaller(GearshiftParams.UpshiftAfterDownshiftDelay)) {
+				return currentGear;
+			}
+			var nextGear = DoCheckUpshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response);
+			if (nextGear.Equals(currentGear)) {
+				return nextGear;
+			}
+
+			// estimate acceleration for selected gear
+			if (EstimateAccelerationForGear(nextGear, outAngularVelocity).IsSmaller(GearshiftParams.UpshiftMinAcceleration)) {
+				// if less than 0.1 for next gear, don't shift
+				if (nextGear.Gear - currentGear.Gear == 1) {
+					return currentGear;
+				}
+				// if a gear is skipped but acceleration is less than 0.1, try for next gear. if acceleration is still below 0.1 don't shift!
+				if (nextGear.Gear > currentGear.Gear &&
+					EstimateAccelerationForGear(Gears.Successor(currentGear), outAngularVelocity)
+						.IsSmaller(GearshiftParams.UpshiftMinAcceleration)) {
+					return currentGear;
+				}
+				nextGear = Gears.Successor(currentGear);
+			}
+
+			return nextGear;
+		}
+
+		protected virtual GearshiftPosition CheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response)
+		{
+			if ((absTime - _gearbox.LastUpshift).IsSmaller(GearshiftParams.DownshiftAfterUpshiftDelay)) {
+				return currentGear;
+			}
+			return DoCheckDownshift(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, currentGear, response);
+		}
+
+		protected virtual GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
+		{
+			// upshift
+			if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				currentGear = Gears.Successor(currentGear);
+
+				while (SkipGears && Gears.HasSuccessor(currentGear)) {
+					currentGear = Gears.Successor(currentGear);
+					var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear);
+
+					inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity;
+					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
+
+					var maxTorque = VectoMath.Min(
+						response.Engine.DynamicFullLoadPower /
+						((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2),
+						currentGear.Equals(Gears.First())
+							? double.MaxValue.SI<NewtonMeter>()
+							: GearboxModelData.Gears[currentGear.Gear].ShiftPolygon
+								.InterpolateDownshift(response.Engine.EngineSpeed));
+					var reserve = 1 - inTorque.Value() / maxTorque.Value();
+
+					if (reserve >= 0 /*ModelData.TorqueReserve */ && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+						continue;
+					}
+
+					currentGear = Gears.Predecessor(currentGear);
+					break;
+				}
+			}
+
+			// early up shift to higher gear ---------------------------------------
+			if (EarlyShiftUp && Gears.HasSuccessor(currentGear)) {
+				currentGear = CheckEarlyUpshift(absTime, dt, outTorque, outAngularVelocity, currentGear, response1);
+			}
+			return currentGear;
+		}
+
+		protected virtual GearshiftPosition CheckEarlyUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition currentGear, IResponse response1)
+		{
+			// try if next gear would provide enough torque reserve
+			var tryNextGear = Gears.Successor(currentGear);
+			var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear);
+
+			var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
+			var inTorque = response.Clutch.PowerRequest / inAngularVelocity;
+
+			// if next gear supplied enough power reserve: take it
+			// otherwise take
+			if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
+				var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad;
+				var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
+
+				if (reserve >= GearshiftParams.TorqueReserve) {
+					currentGear = tryNextGear;
+				}
+			}
+			return currentGear;
+		}
+
+		
+		protected virtual GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response)
+		{
+			// down shift
+			if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				currentGear = Gears.Predecessor(currentGear);
+				//while (SkipGears && currentGear > 1) {
+				//	currentGear--;
+				//	var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, currentGear);
+
+				//	inAngularVelocity = ModelData.Gears[currentGear].Ratio * outAngularVelocity;
+				//	inTorque = response.ClutchPowerRequest / inAngularVelocity;
+				//	var maxTorque = VectoMath.Min(response.DynamicFullLoadPower / ((DataBus.EngineSpeed + response.EngineSpeed) / 2),
+				//		currentGear > 1
+				//			? ModelData.Gears[currentGear].ShiftPolygon.InterpolateDownshift(response.EngineSpeed)
+				//			: double.MaxValue.SI<NewtonMeter>());
+				//	var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value();
+				//	if (reserve >= ModelData.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				//		continue;
+				//	}
+				//	currentGear++;
+				//	break;
+				//}
+			}
+			return currentGear;
+		}
+
+		protected virtual ResponseDryRun RequestDryRunWithGear(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, GearshiftPosition tryNextGear)
+		{
+			var tmpGear = Gearbox.Gear;
+			_gearbox.Gear = tryNextGear;
+			var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+			_gearbox.Gear = tmpGear;
+			return response;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs
similarity index 86%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs
index d63082eec148f69c0e9137a1cbfc32ed6a05a388..dc0ccc21193d1a3741de367230b19c1578d8d4fd 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyOptimized.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/AMTShiftStrategyOptimized.cs
@@ -13,15 +13,28 @@ using TUGraz.VectoCore.Models.Simulation.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies;
 using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 {
+	public class AMTShiftStrategyOptimizedPolygonCalculator : IShiftPolygonCalculator
+	{
+		public ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears,
+			CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		{
+			return DeclarationData.Gearbox.ComputeManualTransmissionShiftPolygon(
+				i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius);
+		}
+	}
 	public class AMTShiftStrategyOptimized : AMTShiftStrategy
 	{
+		
+
 		private List<CombustionEngineFuelData> fcMap;
 		private Dictionary<uint, EngineFullLoadCurve> fld;
-		private ShiftStrategyParameters shiftStrategyParameters;
+		private ShiftStrategyParameters _shiftStrategyParameters;
 		private SimplePowertrainContainer TestContainer;
 		private Gearbox TestContainerGbx;
 
@@ -29,9 +42,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		//private AccelerationCurveData accCurve;
 
 		private Kilogram vehicleMass;
-		
+		private readonly IShiftPolygonCalculator _shiftPolygonCalculator;
 
-		
 
 		public AMTShiftStrategyOptimized(IVehicleContainer dataBus) : base(dataBus)
 		{
@@ -42,18 +54,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			fcMap = runData.EngineData.Fuels;
 			fld = runData.EngineData.FullLoadCurves;
-			shiftStrategyParameters = runData.GearshiftParameters;
+			_shiftStrategyParameters = runData.GearshiftParameters;
+			_shiftPolygonCalculator = ShiftPolygonCalculator.Create(Name, _shiftStrategyParameters);
 			//accCurve = runData.DriverData.AccelerationCurve;
 			vehicleMass = runData.VehicleData.TotalVehicleMass;
-			if (shiftStrategyParameters == null) {
+			if (_shiftStrategyParameters == null) {
 				throw new VectoException("Parameters for shift strategy missing!");
 			}
 
 			SetupVelocityDropPreprocessor(dataBus);
 
-			if (shiftStrategyParameters.AllowedGearRangeFC > 2 || shiftStrategyParameters.AllowedGearRangeFC < 1) {
+			if (_shiftStrategyParameters.AllowedGearRangeFC > 2 || _shiftStrategyParameters.AllowedGearRangeFC < 1) {
 				Log.Warn("Gear-range for FC-based gearshift must be either 1 or 2!");
-				shiftStrategyParameters.AllowedGearRangeFC = shiftStrategyParameters.AllowedGearRangeFC.LimitTo(1, 2);
+				_shiftStrategyParameters.AllowedGearRangeFC = _shiftStrategyParameters.AllowedGearRangeFC.LimitTo(1, 2);
 			}
 		}
 
@@ -101,17 +114,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			}
 
 			var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift;
-			var vehicleSpeedPostShift = DataBus.VehicleInfo.VehicleSpeed - vDrop * shiftStrategyParameters.VelocityDropFactor;
+			var vehicleSpeedPostShift = DataBus.VehicleInfo.VehicleSpeed - vDrop * _shiftStrategyParameters.VelocityDropFactor;
 
 			var totalTransmissionRatio = DataBus.EngineInfo.EngineSpeed / DataBus.VehicleInfo.VehicleSpeed;
 
 			//for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) {
 			foreach (var tryNextGear in Gears.IterateGears(Gears.Successor(currentGear),
-				Gears.Successor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) {
+				Gears.Successor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) {
 				//var tryNextGear = (uint)(currentGear.Gear + i);
 
 				if (tryNextGear == null ||
-					!(GearboxModelData.Gears[tryNextGear.Gear].Ratio < shiftStrategyParameters.RatioEarlyUpshiftFC)) {
+					!(GearboxModelData.Gears[tryNextGear.Gear].Ratio < _shiftStrategyParameters.RatioEarlyUpshiftFC)) {
 					continue;
 				}
 
@@ -132,7 +145,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 				var estimatedEngineSpeed = vehicleSpeedPostShift * (totalTransmissionRatio /
 						GearboxModelData.Gears[currentGear.Gear].Ratio * GearboxModelData.Gears[tryNextGear.Gear].Ratio);
-				if (estimatedEngineSpeed.IsSmaller(shiftStrategyParameters.MinEngineSpeedPostUpshift)) {
+				if (estimatedEngineSpeed.IsSmaller(_shiftStrategyParameters.MinEngineSpeedPostUpshift)) {
 					continue;
 				}
 
@@ -153,7 +166,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					var accelerationFactor = outAngularVelocity * GearboxModelData.Gears[currentGear.Gear].Ratio < fld[0].NTq98hSpeed
 						? 1.0
 						: VectoMath.Interpolate(
-							fld[0].NTq98hSpeed, fld[0].NP98hSpeed, 1.0, shiftStrategyParameters.AccelerationFactor,
+							fld[0].NTq98hSpeed, fld[0].NP98hSpeed, 1.0, _shiftStrategyParameters.AccelerationFactor,
 							outAngularVelocity * GearboxModelData.Gears[currentGear.Gear].Ratio);
 					if (accelerationFactor.IsEqual(1, 1e-9)) {
 						continue;
@@ -188,7 +201,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				var fcNext = GetFCRating(response.Engine.EngineSpeed, tqNext);
 				
 				if (reserve < GearshiftParams.TorqueReserve ||
-					!fcNext.IsSmaller(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear) || !fcNext.IsSmaller(minFc)) {
+					!fcNext.IsSmaller(fcCurrent * _shiftStrategyParameters.RatingFactorCurrentGear) || !fcNext.IsSmaller(minFc)) {
 					continue;
 				}
 
@@ -253,10 +266,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			//for (var i = 1; i <= shiftStrategyParameters.AllowedGearRangeFC; i++) {
 			foreach (var tryNextGear in Gears.IterateGears(Gears.Predecessor(currentGear),
-				Gears.Predecessor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) {
+				Gears.Predecessor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) {
 				//var tryNextGear = (uint)(currentGear.Gear - i);
 
-				if (tryNextGear == null || !(GearboxModelData.Gears[tryNextGear.Gear].Ratio <= shiftStrategyParameters.RatioEarlyDownshiftFC)) {
+				if (tryNextGear == null || !(GearboxModelData.Gears[tryNextGear.Gear].Ratio <= _shiftStrategyParameters.RatioEarlyDownshiftFC)) {
 					continue;
 				}
 
@@ -283,7 +296,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 						fld[tryNextGear.Gear].DragLoadStationaryTorque(response.Engine.EngineSpeed),
 						fld[tryNextGear.Gear].FullLoadStationaryTorque(response.Engine.EngineSpeed)));
 
-				if (!fcNext.IsSmaller(fcCurrent * shiftStrategyParameters.RatingFactorCurrentGear) ||
+				if (!fcNext.IsSmaller(fcCurrent * _shiftStrategyParameters.RatingFactorCurrentGear) ||
 					!fcNext.IsSmaller(minFc)) {
 					continue;
 				}
@@ -338,8 +351,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio,
 			Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
 		{
-			return DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon(
-				i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius);
+			return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType, i, engineDataFullLoadCurve,
+				gearboxGears,
+				engineData, axlegearRatio, dynamicTyreRadius, electricMotorData);
 		}
 
 		#endregion
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/APTNShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/APTNShiftStrategy.cs
similarity index 96%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/APTNShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/APTNShiftStrategy.cs
index ed2c50526f16e5319ecf01a5efbd3bcc161196fe..b449fe794b3f01f412412075a59b100c0f66bc64 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/APTNShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/APTNShiftStrategy.cs
@@ -2,7 +2,7 @@
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Models.Simulation;
 
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 {
 	public class APTNShiftStrategy : PEVAMTShiftStrategy
 	{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategy.cs
similarity index 96%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategy.cs
index d1af4f8622f3d4e9e00518318b62880475a2627f..b69ee812549a5e691783d451ddc4d3dac81b8929 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategy.cs
@@ -1,549 +1,562 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2019 European Union
-*
-* Developed by Graz University of Technology,
-*              Institute of Internal Combustion Engines and Thermodynamics,
-*              Institute of Technical Informatics
-*
-* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
-* by the European Commission - subsequent versions of the EUPL (the "Licence");
-* You may not use VECTO except in compliance with the Licence.
-* You may obtain a copy of the Licence at:
-*
-* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
-*
-* Unless required by applicable law or agreed to in writing, VECTO
-* distributed under the Licence is distributed on an "AS IS" basis,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Licence for the specific language governing permissions and
-* limitations under the Licence.
-*
-* Authors:
-*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
-*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
-*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
-*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
-*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
-*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
-*/
-
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class ATShiftStrategy : BaseShiftStrategy
-	{
-		protected ATGearbox _gearbox;
-		protected readonly NextGearState _nextGear = new NextGearState();
-		private KilogramSquareMeter EngineInertia;
-
-		public override IGearbox Gearbox
-		{
-			get => _gearbox;
-			set {
-				_gearbox = value as ATGearbox;
-				if (_gearbox == null) {
-					throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType());
-				}
-			}
-		}
-
-		public override GearshiftPosition NextGear => _nextGear.Gear;
-
-		public override ShiftPolygon ComputeDeclarationShiftPolygon(
-			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
-			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio,
-			Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
-		{
-			return DeclarationData.TorqueConverter.ComputeShiftPolygon(
-				engineDataFullLoadCurve, i == 0, i >= gearboxGears.Count - 1);
-		}
-
-		public static string Name => "AT - Classic";
-
-		public ATShiftStrategy(IVehicleContainer dataBus) : base(dataBus)
-		{
-			EngineInertia = dataBus.RunData.EngineData?.Inertia ?? 0.SI<KilogramSquareMeter>();
-
-			if (Gears.Any(x => !x.TorqueConverterLocked.HasValue)) {
-				throw new VectoException("Gear list must have TC info for all gears! {0}", Gears.Join());
-			}
-
-			MaxStartGear = Gears.Any() ? Gears.First() : new GearshiftPosition(0);
-		}
-
-		public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
-		{
-			if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) {
-				// AT always starts in first gear and TC active!
-				_gearbox.Disengaged = true;
-				return Gears.First();
-			}
-
-			foreach (var gear in Gears.Reverse()) {
-				var response = _gearbox.Initialize(gear, torque, outAngularVelocity);
-
-				if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineRatedSpeed || response.Engine.EngineSpeed < DataBus.EngineInfo.EngineIdleSpeed) {
-					continue;
-				}
-
-				if (!IsBelowDownShiftCurve(gear, response.Engine.PowerRequest / response.Engine.EngineSpeed, response.Engine.EngineSpeed)) {
-					_gearbox.Disengaged = false;
-					return gear;
-				}
-			}
-
-			// fallback: start with first gear;
-			_gearbox.Disengaged = false;
-			return Gears.First();
-		}
-
-		public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) {
-				//_gearbox.Gear = _nextGear.Gear;
-				_gearbox.Disengaged = _nextGear.Disengaged;
-				_nextGear.AbsTime = null;
-				return _nextGear.Gear;
-			}
-
-			_nextGear.AbsTime = null;
-			return _gearbox.Gear;
-		}
-
-		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{
-			throw new System.NotImplementedException("AT Shift Strategy does not support disengaging.");
-		}
-
-		protected override bool DoCheckShiftRequired(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
-		{
-			// ENGAGE ---------------------------------------------------------
-			// 0 -> 1C: drive off after disengaged - engage first gear
-			if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) {
-				Log.Debug("shift required: drive off after vehicle stopped");
-				_nextGear.SetState(absTime, disengaged: false, gear: Gears.First());
-				return true;
-			}
-
-			// DISENGAGE ------------------------------------------------------
-			// 1) _ -> 0: disengage before halting
-			var braking = DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking;
-			var torqueNegative = outTorque.IsSmaller(0);
-			var slowerThanDisengageSpeed =
-				DataBus.VehicleInfo.VehicleSpeed.IsSmaller(GearboxModelData.DisengageWhenHaltingSpeed);
-			var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed;
-
-			// 2) L -> 0: disengage if inAngularVelocity == 0
-			var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>());
-
-			// 3) 1C -> 0: disengange when negative T_out and positive T_in
-			var gear1C = Gears.First().Equals(gear);
-			var disengageTOutNegativeAndTInPositive = DataBus.DriverInfo.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) &&
-													inTorque.IsGreater(0);
-
-			var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C &&
-												inAngularVelocity.IsSmallerOrEqual(DataBus.EngineInfo.EngineIdleSpeed);
-
-			if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero ||
-				disengageTOutNegativeAndTInPositive) {
-				_nextGear.SetState(absTime, disengaged: true, gear: Gears.First());
-				return true;
-			}
-
-			// EMERGENCY SHIFTS ---------------------------------------
-			if (CheckEmergencyShift(absTime, outTorque, outAngularVelocity, inAngularVelocity, gear)) {
-				return true;
-			}
-
-			// UPSHIFT --------------------------------------------------------
-			if (CheckUpshift(
-				absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
-				lastShiftTime, response)) {
-				return true;
-			}
-
-			// DOWNSHIFT ------------------------------------------------------
-			if (CheckDownshift(
-				absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
-				lastShiftTime, response)) {
-				return true;
-			}
-
-			return false;
-		}
-
-		protected virtual bool CheckEmergencyShift(
-			Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, PerSecond inAngularVelocity, GearshiftPosition gear)
-		{
-			// Emergency Downshift: if lower than engine idle speed
-			if (inAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed) && Gears.HasPredecessor(gear)) {
-				Log.Debug("engine speed would fall below idle speed - shift down");
-				Downshift(absTime, gear);
-				return true;
-			}
-
-			// Emergency Upshift: if higher than engine rated speed
-			if (inAngularVelocity.IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed, DataBus.EngineInfo.EngineN95hSpeed))) {
-				// check if upshift is possible
-				if (!Gears.HasSuccessor(gear)) {
-					return false;
-				}
-
-				PerSecond nextInAngularSpeed;
-				NewtonMeter nextInTorque;
-				if (GearboxModelData.Gears[gear.Gear].HasLockedGear) {
-					nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
-					nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear].Ratio;
-				} else {
-					nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear + 1].Ratio;
-					nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear + 1].Ratio;
-				}
-
-				var nextGear = Gears.Successor(gear);
-				var acc = EstimateAccelerationForGear(nextGear, outAngularVelocity);
-				if ((acc > 0 || _gearbox.TCLocked) && !IsBelowDownShiftCurve(nextGear, nextInTorque, nextInAngularSpeed)) {
-					Log.Debug("engine speed would be above max speed / rated speed - shift up");
-					Upshift(absTime, gear);
-					return true;
-				}
-			}
-
-			return false;
-		}
-
-		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
-		protected virtual bool CheckUpshift(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
-		{
-			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts);
-			if (!shiftTimeReached) {
-				return false;
-			}
-
-			var currentGear = GearboxModelData.Gears[gear.Gear];
-
-			if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) {
-				var result = CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear);
-				if (result.HasValue) {
-					return result.Value;
-				}
-			}
-
-			// UPSHIFT - Special rule for 1C -> 2C
-			var nextGear = Gears.Successor(gear);
-			if (!gear.TorqueConverterLocked.Value && nextGear != null && !nextGear.TorqueConverterLocked.Value && outAngularVelocity.IsGreater(0)) {
-				var result = CheckUpshiftTcTc(
-					absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, currentGear, response);
-				if (result.HasValue) {
-					return result.Value;
-				}
-			}
-
-			if (Gears.HasSuccessor(gear)) {
-				var earlyUpshift = CheckEarlyUpshift(
-					absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response);
-				if (earlyUpshift.HasValue) {
-					return earlyUpshift.Value;
-				}
-			}
-
-			return false;
-		}
-
-		protected virtual bool? CheckEarlyUpshift(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
-		{
-			return null;
-		}
-
-		protected virtual bool? CheckUpshiftTcTc(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear, GearData currentGear, IResponse response)
-		{
-			// C -> C+1
-			var nextGearPos = Gears.Successor(gear); // GearboxModelData.Gears[gear + 1];
-			var nextGear = GearboxModelData.Gears[nextGearPos.Gear];
-			var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio;
-			var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineInfo.EngineN80hSpeed - 150.RPMtoRad()));
-
-			var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio;
-			var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio;
-			var shiftLosses = _gearbox.ComputeShiftLosses(outTorque, outAngularVelocity, nextGearPos) /
-							GearboxModelData.PowershiftShiftTime / nextGearboxInSpeed;
-			nextGearboxInTorque += shiftLosses;
-			var tcOperatingPoint =
-				_gearbox.TorqueConverter.FindOperatingPoint(absTime, dt, nextGearboxInTorque, nextGearboxInSpeed);
-
-			var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed);
-			var avgSpeed = (DataBus.EngineInfo.EngineSpeed + tcOperatingPoint.InAngularVelocity) / 2;
-			var engineMaxTorque = DataBus.EngineInfo.EngineStationaryFullPower(avgSpeed) / avgSpeed;
-			var engineInertiaTorque = Formulas.InertiaPower(
-										DataBus.EngineInfo.EngineSpeed, tcOperatingPoint.InAngularVelocity, _gearbox.EngineInertia, dt) / avgSpeed;
-			var engineTorqueBelowMax =
-				tcOperatingPoint.InTorque.IsSmallerOrEqual(engineMaxTorque - engineInertiaTorque);
-
-			var reachableAcceleration =
-				EstimateAcceleration(
-					outAngularVelocity, outTorque, inAngularVelocity, inTorque, gear.Gear, response); // EstimateAccelerationForGear(gear + 1, outAngularVelocity);
-			var minAcceleration = VectoMath.Min(
-				GearboxModelData.TorqueConverterData.CCUpshiftMinAcceleration,
-				DataBus.DriverInfo.DriverAcceleration);
-			var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
-
-			if (engineSpeedOverMin && engineTorqueBelowMax && minAccelerationReachable) {
-				Upshift(absTime, gear);
-				return true;
-			}
-
-			return null;
-		}
-
-		protected virtual bool? CheckUpshiftToLocked(
-			Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear)
-		{
-			// UPSHIFT - General Rule
-			// L -> L+1 
-			// C -> L
-			var nextGear = Gears.Successor(gear); // _gearbox.TorqueConverterLocked ? gear + 1 : gear;
-			if (nextGear == null || !GearboxModelData.Gears.ContainsKey(nextGear.Gear)) {
-				return false;
-			}
-
-			var nextEngineSpeed = outAngularVelocity * GearboxModelData.Gears[nextGear.Gear].Ratio;
-			if (nextEngineSpeed.IsEqual(0)) {
-				return false;
-			}
-
-			var currentEnginePower = inTorque * inAngularVelocity;
-			var nextEngineTorque = currentEnginePower / nextEngineSpeed;
-			var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked);
-
-			var minAccelerationReachable = true;
-			if (DataBus.DriverInfo.DriverAcceleration.IsSmaller(0)) {
-				return null;
-			}
-			if (!DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) {
-				var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity);
-				var minAcceleration = _gearbox.TorqueConverterLocked
-					? GearshiftParams.UpshiftMinAcceleration
-					: GearboxModelData.TorqueConverterData.CLUpshiftMinAcceleration;
-				minAcceleration = VectoMath.Min(
-					minAcceleration, VectoMath.Max(0.SI<MeterPerSquareSecond>(), DataBus.DriverInfo.DriverAcceleration));
-				minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
-			}
-
-			if (isAboveUpShift && minAccelerationReachable) {
-				Upshift(absTime, gear);
-				return true;
-			}
-
-			return null;
-		}
-
-		/// <summary>
-		/// Tests if the operating point is above (right of) the up-shift curve.
-		/// </summary>
-		/// <param name="gear">The gear.</param>
-		/// <param name="inTorque">The in torque.</param>
-		/// <param name="inEngineSpeed">The in engine speed.</param>
-		/// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param>
-		/// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns>
-		protected virtual bool IsAboveUpShiftCurve(
-			GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed,
-			bool torqueConverterLocked)
-		{
-			var shiftPolygon = torqueConverterLocked
-				? GearboxModelData.Gears[gear.Gear].ShiftPolygon
-				: GearboxModelData.Gears[gear.Gear].TorqueConverterShiftPolygon;
-
-			return Gears.HasSuccessor(gear) && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
-		}
-
-		protected virtual void Upshift(Second absTime, GearshiftPosition gear)
-		{
-			if (!Gears.HasSuccessor(gear)) {
-				throw new VectoSimulationException(
-					"ShiftStrategy wanted to shift up but no higher gear available.");
-			}
-
-			_nextGear.SetState(absTime, false, Gears.Successor(gear));
-
-		}
-
-		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
-		protected virtual bool CheckDownshift(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
-		{
-			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts);
-
-			if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) {
-				Downshift(absTime, gear);
-				return true;
-			}
-
-			if (shiftTimeReached && DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate) {
-				if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() &&
-					DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) {
-					var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-					if (_gearbox.Gear > Gears.First()) {
-						// clone current state of _nextgear, set gearbox state to lower gear, issue request, restore old gearbox state
-						var tmp = _nextGear.Clone();
-						var gbxState = new NextGearState(absTime, _gearbox);
-						tmp.Gear = Gears.Predecessor(_gearbox.Gear);
-						SetGear(tmp);
-						var tmpResponseDs = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-						SetGear(gbxState);
-						// done
-						if (tmpResponseDs.DeltaFullLoad - Formulas.InertiaPower(
-								tmpResponseDs.Engine.EngineSpeed, DataBus.EngineInfo.EngineSpeed, EngineInertia, dt) < tmpResponseCurr.DeltaFullLoad) {
-							Downshift(absTime, gear);
-							return true;
-						}
-					}
-				}
-			}
-
-			if (shiftTimeReached && gear > Gears.First()) {
-				var earlyDownshift = CheckEarlyDownshift(
-					absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response);
-				if (earlyDownshift.HasValue) {
-					return earlyDownshift.Value;
-				}
-			}
-
-			return false;
-		}
-
-		protected virtual bool? CheckEarlyDownshift(
-			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
-			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
-		{
-			return null;
-		}
-
-		protected virtual void SetGear(NextGearState gbxState)
-		{
-			_gearbox.Gear = gbxState.Gear;
-			//_gearbox.TorqueConverterLocked = gbxState.TorqueConverterLocked;
-			_gearbox.Disengaged = gbxState.Disengaged;
-		}
-
-		/// <summary>
-		/// Tests if the operating point is below (left of) the down-shift curve.
-		/// </summary>
-		/// <param name="gear">The gear.</param>
-		/// <param name="inTorque">The in torque.</param>
-		/// <param name="inEngineSpeed">The in engine speed.</param>
-		/// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns>
-		protected virtual bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
-		{
-			return !Gears.First().Equals(gear) && GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed);
-		}
-
-		protected virtual void Downshift(Second absTime, GearshiftPosition gear)
-		{
-			if (!Gears.HasPredecessor(gear)) {
-				throw new VectoSimulationException(
-					"ShiftStrategy wanted to shift down but no lower gear available.");
-			}
-			_nextGear.SetState(absTime, false, Gears.Predecessor(gear));
-		}
-
-		protected MeterPerSquareSecond EstimateAcceleration(
-			PerSecond gbxOutSpeed, NewtonMeter gbxOutTorque, PerSecond tcInSpeed, NewtonMeter tcInTorque, uint currentGear, IResponse response)
-		{
-			var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed;
-			var avgSlope =
-			((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude -
-			DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>();
-
-			var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed;
-			var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
-
-			var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
-			var axleLoss = DataBus.AxlegearInfo.AxlegearLoss();
-
-			var tcLossesCurrentGear = tcInSpeed * tcInTorque - gbxOutSpeed * gbxOutTorque;
-
-			var nextTcOutSpeed = gbxOutSpeed * GearboxModelData.Gears[currentGear + 1].TorqueConverterRatio;
-			
-			var tcNext = GearboxModelData.TorqueConverterData.LookupOperatingPointOut(
-				nextTcOutSpeed, response.Engine.EngineSpeed, response.Engine.TorqueOutDemand);
-			var tcLossesNextGear = tcNext.InAngularVelocity * tcNext.InTorque - tcNext.OutAngularVelocity * tcNext.OutTorque;
-			var deltaTcLosses = tcLossesNextGear - tcLossesCurrentGear;
-
-			var accelerationPower = gbxOutSpeed * gbxOutTorque - deltaTcLosses - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss;
-
-			var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels);
-
-			return acceleration.Cast<MeterPerSquareSecond>();
-		}
-
-		protected class NextGearState
-		{
-			public Second AbsTime { get; internal set; }
-			public bool Disengaged { get; private set; }
-			public GearshiftPosition Gear { get; internal set; }
-
-			public NextGearState()
-			{
-				Gear = new GearshiftPosition(0);
-			}
-
-			private NextGearState(NextGearState nextGearState)
-			{
-				AbsTime = nextGearState.AbsTime;
-				Disengaged = nextGearState.Disengaged;
-				Gear = nextGearState.Gear;
-			}
-
-			public NextGearState(Second absTime, ATGearbox gearbox)
-			{
-				SetState(absTime, gearbox);
-			}
-
-			public void SetState(Second absTime, bool disengaged, GearshiftPosition gear)
-			{
-				AbsTime = absTime;
-				Disengaged = disengaged;
-				Gear = gear;
-			}
-			
-			public void SetState(Second absTime, ATGearbox gearbox)
-			{
-				AbsTime = absTime;
-				Disengaged = gearbox.Disengaged;
-				Gear = gearbox.Gear;
-			}
-
-			public NextGearState Clone()
-			{
-				return new NextGearState(this);
-			}
-		}
-	}
-}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2019 European Union
+*
+* Developed by Graz University of Technology,
+*              Institute of Internal Combustion Engines and Thermodynamics,
+*              Institute of Technical Informatics
+*
+* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
+* by the European Commission - subsequent versions of the EUPL (the "Licence");
+* You may not use VECTO except in compliance with the Licence.
+* You may obtain a copy of the Licence at:
+*
+* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
+*
+* Unless required by applicable law or agreed to in writing, VECTO
+* distributed under the Licence is distributed on an "AS IS" basis,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the Licence for the specific language governing permissions and
+* limitations under the Licence.
+*
+* Authors:
+*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
+*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
+*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
+*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
+*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
+*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
+*/
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
+{
+	public class ATShiftStrategyPolygonCalculator : IShiftPolygonCalculator
+	{
+		public ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio,
+			Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		{
+			return DeclarationData.TorqueConverter.ComputeShiftPolygon(
+				engineDataFullLoadCurve, i == 0, i >= gearboxGears.Count - 1);
+		}
+	}
+
+	public class ATShiftStrategy : BaseShiftStrategy
+	{
+		protected ATGearbox _gearbox;
+		protected readonly NextGearState _nextGear = new NextGearState();
+		private KilogramSquareMeter EngineInertia;
+		private IShiftPolygonCalculator _shiftPolygonCalculator;
+
+		public override IGearbox Gearbox
+		{
+			get => _gearbox;
+			set {
+				_gearbox = value as ATGearbox;
+				if (_gearbox == null) {
+					throw new VectoException("AT Shift strategy can only handle AT gearboxes, given: {0}", value.GetType());
+				}
+			}
+		}
+
+		public override GearshiftPosition NextGear => _nextGear.Gear;
+
+		public override ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio,
+			Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		{
+			return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType, i, engineDataFullLoadCurve,
+				gearboxGears, engineData, axlegearRatio, dynamicTyreRadius, electricMotorData);
+		}
+
+		public static string Name => "AT - Classic";
+
+		public ATShiftStrategy(IVehicleContainer dataBus) : base(dataBus)
+		{
+			EngineInertia = dataBus.RunData.EngineData?.Inertia ?? 0.SI<KilogramSquareMeter>();
+			ShiftPolygonCalculator.Create(Name, null);
+			if (Gears.Any(x => !x.TorqueConverterLocked.HasValue)) {
+				throw new VectoException("Gear list must have TC info for all gears! {0}", Gears.Join());
+			}
+
+			MaxStartGear = Gears.Any() ? Gears.First() : new GearshiftPosition(0);
+		}
+
+		public override GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
+		{
+			if (DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) {
+				// AT always starts in first gear and TC active!
+				_gearbox.Disengaged = true;
+				return Gears.First();
+			}
+
+			foreach (var gear in Gears.Reverse()) {
+				var response = _gearbox.Initialize(gear, torque, outAngularVelocity);
+
+				if (response.Engine.EngineSpeed > DataBus.EngineInfo.EngineRatedSpeed || response.Engine.EngineSpeed < DataBus.EngineInfo.EngineIdleSpeed) {
+					continue;
+				}
+
+				if (!IsBelowDownShiftCurve(gear, response.Engine.PowerRequest / response.Engine.EngineSpeed, response.Engine.EngineSpeed)) {
+					_gearbox.Disengaged = false;
+					return gear;
+				}
+			}
+
+			// fallback: start with first gear;
+			_gearbox.Disengaged = false;
+			return Gears.First();
+		}
+
+		public override GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			if (_nextGear.AbsTime != null && _nextGear.AbsTime.IsEqual(absTime)) {
+				//_gearbox.Gear = _nextGear.Gear;
+				_gearbox.Disengaged = _nextGear.Disengaged;
+				_nextGear.AbsTime = null;
+				return _nextGear.Gear;
+			}
+
+			_nextGear.AbsTime = null;
+			return _gearbox.Gear;
+		}
+
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			throw new System.NotImplementedException("AT Shift Strategy does not support disengaging.");
+		}
+
+		protected override bool DoCheckShiftRequired(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
+		{
+			// ENGAGE ---------------------------------------------------------
+			// 0 -> 1C: drive off after disengaged - engage first gear
+			if (_gearbox.Disengaged && outAngularVelocity.IsGreater(0.SI<PerSecond>())) {
+				Log.Debug("shift required: drive off after vehicle stopped");
+				_nextGear.SetState(absTime, disengaged: false, gear: Gears.First());
+				return true;
+			}
+
+			// DISENGAGE ------------------------------------------------------
+			// 1) _ -> 0: disengage before halting
+			var braking = DataBus.DriverInfo.DriverBehavior == DrivingBehavior.Braking;
+			var torqueNegative = outTorque.IsSmaller(0);
+			var slowerThanDisengageSpeed =
+				DataBus.VehicleInfo.VehicleSpeed.IsSmaller(GearboxModelData.DisengageWhenHaltingSpeed);
+			var disengageBeforeHalting = braking && torqueNegative && slowerThanDisengageSpeed;
+
+			// 2) L -> 0: disengage if inAngularVelocity == 0
+			var disengageAngularVelocityZero = _gearbox.TorqueConverterLocked && inAngularVelocity.IsEqual(0.SI<PerSecond>());
+
+			// 3) 1C -> 0: disengange when negative T_out and positive T_in
+			var gear1C = Gears.First().Equals(gear);
+			var disengageTOutNegativeAndTInPositive = DataBus.DriverInfo.DriverAcceleration <= 0 && gear1C && outTorque.IsSmaller(0) &&
+													inTorque.IsGreater(0);
+
+			var disengageTCEngineSpeedLowerIdle = braking && torqueNegative && gear1C &&
+												inAngularVelocity.IsSmallerOrEqual(DataBus.EngineInfo.EngineIdleSpeed);
+
+			if (disengageBeforeHalting || disengageTCEngineSpeedLowerIdle || disengageAngularVelocityZero ||
+				disengageTOutNegativeAndTInPositive) {
+				_nextGear.SetState(absTime, disengaged: true, gear: Gears.First());
+				return true;
+			}
+
+			// EMERGENCY SHIFTS ---------------------------------------
+			if (CheckEmergencyShift(absTime, outTorque, outAngularVelocity, inAngularVelocity, gear)) {
+				return true;
+			}
+
+			// UPSHIFT --------------------------------------------------------
+			if (CheckUpshift(
+				absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
+				lastShiftTime, response)) {
+				return true;
+			}
+
+			// DOWNSHIFT ------------------------------------------------------
+			if (CheckDownshift(
+				absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear,
+				lastShiftTime, response)) {
+				return true;
+			}
+
+			return false;
+		}
+
+		protected virtual bool CheckEmergencyShift(
+			Second absTime, NewtonMeter outTorque, PerSecond outAngularVelocity, PerSecond inAngularVelocity, GearshiftPosition gear)
+		{
+			// Emergency Downshift: if lower than engine idle speed
+			if (inAngularVelocity.IsSmaller(DataBus.EngineInfo.EngineIdleSpeed) && Gears.HasPredecessor(gear)) {
+				Log.Debug("engine speed would fall below idle speed - shift down");
+				Downshift(absTime, gear);
+				return true;
+			}
+
+			// Emergency Upshift: if higher than engine rated speed
+			if (inAngularVelocity.IsGreaterOrEqual(VectoMath.Min(GearboxModelData.Gears[gear.Gear].MaxSpeed, DataBus.EngineInfo.EngineN95hSpeed))) {
+				// check if upshift is possible
+				if (!Gears.HasSuccessor(gear)) {
+					return false;
+				}
+
+				PerSecond nextInAngularSpeed;
+				NewtonMeter nextInTorque;
+				if (GearboxModelData.Gears[gear.Gear].HasLockedGear) {
+					nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear].Ratio;
+					nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear].Ratio;
+				} else {
+					nextInAngularSpeed = outAngularVelocity * GearboxModelData.Gears[gear.Gear + 1].Ratio;
+					nextInTorque = outTorque / GearboxModelData.Gears[gear.Gear + 1].Ratio;
+				}
+
+				var nextGear = Gears.Successor(gear);
+				var acc = EstimateAccelerationForGear(nextGear, outAngularVelocity);
+				if ((acc > 0 || _gearbox.TCLocked) && !IsBelowDownShiftCurve(nextGear, nextInTorque, nextInAngularSpeed)) {
+					Log.Debug("engine speed would be above max speed / rated speed - shift up");
+					Upshift(absTime, gear);
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
+		protected virtual bool CheckUpshift(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
+		{
+			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts);
+			if (!shiftTimeReached) {
+				return false;
+			}
+
+			var currentGear = GearboxModelData.Gears[gear.Gear];
+
+			if (_gearbox.TorqueConverterLocked || currentGear.HasLockedGear) {
+				var result = CheckUpshiftToLocked(absTime, outAngularVelocity, inTorque, inAngularVelocity, gear);
+				if (result.HasValue) {
+					return result.Value;
+				}
+			}
+
+			// UPSHIFT - Special rule for 1C -> 2C
+			var nextGear = Gears.Successor(gear);
+			if (!gear.TorqueConverterLocked.Value && nextGear != null && !nextGear.TorqueConverterLocked.Value && outAngularVelocity.IsGreater(0)) {
+				var result = CheckUpshiftTcTc(
+					absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, currentGear, response);
+				if (result.HasValue) {
+					return result.Value;
+				}
+			}
+
+			if (Gears.HasSuccessor(gear)) {
+				var earlyUpshift = CheckEarlyUpshift(
+					absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response);
+				if (earlyUpshift.HasValue) {
+					return earlyUpshift.Value;
+				}
+			}
+
+			return false;
+		}
+
+		protected virtual bool? CheckEarlyUpshift(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
+		{
+			return null;
+		}
+
+		protected virtual bool? CheckUpshiftTcTc(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear, GearData currentGear, IResponse response)
+		{
+			// C -> C+1
+			var nextGearPos = Gears.Successor(gear); // GearboxModelData.Gears[gear + 1];
+			var nextGear = GearboxModelData.Gears[nextGearPos.Gear];
+			var gearRatio = nextGear.TorqueConverterRatio / currentGear.TorqueConverterRatio;
+			var minEngineSpeed = VectoMath.Min(700.RPMtoRad(), gearRatio * (DataBus.EngineInfo.EngineN80hSpeed - 150.RPMtoRad()));
+
+			var nextGearboxInSpeed = outAngularVelocity * nextGear.TorqueConverterRatio;
+			var nextGearboxInTorque = outTorque / nextGear.TorqueConverterRatio;
+			var shiftLosses = _gearbox.ComputeShiftLosses(outTorque, outAngularVelocity, nextGearPos) /
+							GearboxModelData.PowershiftShiftTime / nextGearboxInSpeed;
+			nextGearboxInTorque += shiftLosses;
+			var tcOperatingPoint =
+				_gearbox.TorqueConverter.FindOperatingPoint(absTime, dt, nextGearboxInTorque, nextGearboxInSpeed);
+
+			var engineSpeedOverMin = tcOperatingPoint.InAngularVelocity.IsGreater(minEngineSpeed);
+			var avgSpeed = (DataBus.EngineInfo.EngineSpeed + tcOperatingPoint.InAngularVelocity) / 2;
+			var engineMaxTorque = DataBus.EngineInfo.EngineStationaryFullPower(avgSpeed) / avgSpeed;
+			var engineInertiaTorque = Formulas.InertiaPower(
+										DataBus.EngineInfo.EngineSpeed, tcOperatingPoint.InAngularVelocity, _gearbox.EngineInertia, dt) / avgSpeed;
+			var engineTorqueBelowMax =
+				tcOperatingPoint.InTorque.IsSmallerOrEqual(engineMaxTorque - engineInertiaTorque);
+
+			var reachableAcceleration =
+				EstimateAcceleration(
+					outAngularVelocity, outTorque, inAngularVelocity, inTorque, gear.Gear, response); // EstimateAccelerationForGear(gear + 1, outAngularVelocity);
+			var minAcceleration = VectoMath.Min(
+				GearboxModelData.TorqueConverterData.CCUpshiftMinAcceleration,
+				DataBus.DriverInfo.DriverAcceleration);
+			var minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
+
+			if (engineSpeedOverMin && engineTorqueBelowMax && minAccelerationReachable) {
+				Upshift(absTime, gear);
+				return true;
+			}
+
+			return null;
+		}
+
+		protected virtual bool? CheckUpshiftToLocked(
+			Second absTime, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear)
+		{
+			// UPSHIFT - General Rule
+			// L -> L+1 
+			// C -> L
+			var nextGear = Gears.Successor(gear); // _gearbox.TorqueConverterLocked ? gear + 1 : gear;
+			if (nextGear == null || !GearboxModelData.Gears.ContainsKey(nextGear.Gear)) {
+				return false;
+			}
+
+			var nextEngineSpeed = outAngularVelocity * GearboxModelData.Gears[nextGear.Gear].Ratio;
+			if (nextEngineSpeed.IsEqual(0)) {
+				return false;
+			}
+
+			var currentEnginePower = inTorque * inAngularVelocity;
+			var nextEngineTorque = currentEnginePower / nextEngineSpeed;
+			var isAboveUpShift = IsAboveUpShiftCurve(gear, nextEngineTorque, nextEngineSpeed, _gearbox.TorqueConverterLocked);
+
+			var minAccelerationReachable = true;
+			if (DataBus.DriverInfo.DriverAcceleration.IsSmaller(0)) {
+				return null;
+			}
+			if (!DataBus.VehicleInfo.VehicleSpeed.IsEqual(0)) {
+				var reachableAcceleration = EstimateAccelerationForGear(nextGear, outAngularVelocity);
+				var minAcceleration = _gearbox.TorqueConverterLocked
+					? GearshiftParams.UpshiftMinAcceleration
+					: GearboxModelData.TorqueConverterData.CLUpshiftMinAcceleration;
+				minAcceleration = VectoMath.Min(
+					minAcceleration, VectoMath.Max(0.SI<MeterPerSquareSecond>(), DataBus.DriverInfo.DriverAcceleration));
+				minAccelerationReachable = reachableAcceleration.IsGreaterOrEqual(minAcceleration);
+			}
+
+			if (isAboveUpShift && minAccelerationReachable) {
+				Upshift(absTime, gear);
+				return true;
+			}
+
+			return null;
+		}
+
+		/// <summary>
+		/// Tests if the operating point is above (right of) the up-shift curve.
+		/// </summary>
+		/// <param name="gear">The gear.</param>
+		/// <param name="inTorque">The in torque.</param>
+		/// <param name="inEngineSpeed">The in engine speed.</param>
+		/// <param name="torqueConverterLocked">if true, the regular shift polygon is used, otherwise the shift polygon for the torque converter is used</param>
+		/// <returns><c>true</c> if the operating point is above the up-shift curve; otherwise, <c>false</c>.</returns>
+		protected virtual bool IsAboveUpShiftCurve(
+			GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed,
+			bool torqueConverterLocked)
+		{
+			var shiftPolygon = torqueConverterLocked
+				? GearboxModelData.Gears[gear.Gear].ShiftPolygon
+				: GearboxModelData.Gears[gear.Gear].TorqueConverterShiftPolygon;
+
+			return Gears.HasSuccessor(gear) && shiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
+		}
+
+		protected virtual void Upshift(Second absTime, GearshiftPosition gear)
+		{
+			if (!Gears.HasSuccessor(gear)) {
+				throw new VectoSimulationException(
+					"ShiftStrategy wanted to shift up but no higher gear available.");
+			}
+
+			_nextGear.SetState(absTime, false, Gears.Successor(gear));
+
+		}
+
+		[SuppressMessage("ReSharper", "UnusedParameter.Local")]
+		protected virtual bool CheckDownshift(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
+		{
+			var shiftTimeReached = (absTime - lastShiftTime).IsGreaterOrEqual(GearshiftParams.TimeBetweenGearshifts);
+
+			if (shiftTimeReached && IsBelowDownShiftCurve(gear, inTorque, inAngularVelocity)) {
+				Downshift(absTime, gear);
+				return true;
+			}
+
+			if (shiftTimeReached && DataBus.DriverInfo.DrivingAction == DrivingAction.Accelerate) {
+				if (DataBus.VehicleInfo.VehicleSpeed < DataBus.DrivingCycleInfo.CycleData.LeftSample.VehicleTargetSpeed - 10.KMPHtoMeterPerSecond() &&
+					DataBus.DriverInfo.DriverAcceleration < 0.SI<MeterPerSquareSecond>()) {
+					var tmpResponseCurr = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+					if (_gearbox.Gear > Gears.First()) {
+						// clone current state of _nextgear, set gearbox state to lower gear, issue request, restore old gearbox state
+						var tmp = _nextGear.Clone();
+						var gbxState = new NextGearState(absTime, _gearbox);
+						tmp.Gear = Gears.Predecessor(_gearbox.Gear);
+						SetGear(tmp);
+						var tmpResponseDs = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+						SetGear(gbxState);
+						// done
+						if (tmpResponseDs.DeltaFullLoad - Formulas.InertiaPower(
+								tmpResponseDs.Engine.EngineSpeed, DataBus.EngineInfo.EngineSpeed, EngineInertia, dt) < tmpResponseCurr.DeltaFullLoad) {
+							Downshift(absTime, gear);
+							return true;
+						}
+					}
+				}
+			}
+
+			if (shiftTimeReached && gear > Gears.First()) {
+				var earlyDownshift = CheckEarlyDownshift(
+					absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response);
+				if (earlyDownshift.HasValue) {
+					return earlyDownshift.Value;
+				}
+			}
+
+			return false;
+		}
+
+		protected virtual bool? CheckEarlyDownshift(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, GearshiftPosition gear, Second lastShiftTime, IResponse response)
+		{
+			return null;
+		}
+
+		protected virtual void SetGear(NextGearState gbxState)
+		{
+			_gearbox.Gear = gbxState.Gear;
+			//_gearbox.TorqueConverterLocked = gbxState.TorqueConverterLocked;
+			_gearbox.Disengaged = gbxState.Disengaged;
+		}
+
+		/// <summary>
+		/// Tests if the operating point is below (left of) the down-shift curve.
+		/// </summary>
+		/// <param name="gear">The gear.</param>
+		/// <param name="inTorque">The in torque.</param>
+		/// <param name="inEngineSpeed">The in engine speed.</param>
+		/// <returns><c>true</c> if the operating point is below the down-shift curv; otherwise, <c>false</c>.</returns>
+		protected virtual bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		{
+			return !Gears.First().Equals(gear) && GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed);
+		}
+
+		protected virtual void Downshift(Second absTime, GearshiftPosition gear)
+		{
+			if (!Gears.HasPredecessor(gear)) {
+				throw new VectoSimulationException(
+					"ShiftStrategy wanted to shift down but no lower gear available.");
+			}
+			_nextGear.SetState(absTime, false, Gears.Predecessor(gear));
+		}
+
+		protected MeterPerSquareSecond EstimateAcceleration(
+			PerSecond gbxOutSpeed, NewtonMeter gbxOutTorque, PerSecond tcInSpeed, NewtonMeter tcInTorque, uint currentGear, IResponse response)
+		{
+			var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed;
+			var avgSlope =
+			((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude -
+			DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>();
+
+			var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed;
+			var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
+
+			var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
+			var axleLoss = DataBus.AxlegearInfo.AxlegearLoss();
+
+			var tcLossesCurrentGear = tcInSpeed * tcInTorque - gbxOutSpeed * gbxOutTorque;
+
+			var nextTcOutSpeed = gbxOutSpeed * GearboxModelData.Gears[currentGear + 1].TorqueConverterRatio;
+			
+			var tcNext = GearboxModelData.TorqueConverterData.LookupOperatingPointOut(
+				nextTcOutSpeed, response.Engine.EngineSpeed, response.Engine.TorqueOutDemand);
+			var tcLossesNextGear = tcNext.InAngularVelocity * tcNext.InTorque - tcNext.OutAngularVelocity * tcNext.OutTorque;
+			var deltaTcLosses = tcLossesNextGear - tcLossesCurrentGear;
+
+			var accelerationPower = gbxOutSpeed * gbxOutTorque - deltaTcLosses - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss;
+
+			var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels);
+
+			return acceleration.Cast<MeterPerSquareSecond>();
+		}
+
+		protected class NextGearState
+		{
+			public Second AbsTime { get; internal set; }
+			public bool Disengaged { get; private set; }
+			public GearshiftPosition Gear { get; internal set; }
+
+			public NextGearState()
+			{
+				Gear = new GearshiftPosition(0);
+			}
+
+			private NextGearState(NextGearState nextGearState)
+			{
+				AbsTime = nextGearState.AbsTime;
+				Disengaged = nextGearState.Disengaged;
+				Gear = nextGearState.Gear;
+			}
+
+			public NextGearState(Second absTime, ATGearbox gearbox)
+			{
+				SetState(absTime, gearbox);
+			}
+
+			public void SetState(Second absTime, bool disengaged, GearshiftPosition gear)
+			{
+				AbsTime = absTime;
+				Disengaged = disengaged;
+				Gear = gear;
+			}
+			
+			public void SetState(Second absTime, ATGearbox gearbox)
+			{
+				AbsTime = absTime;
+				Disengaged = gearbox.Disengaged;
+				Gear = gearbox.Gear;
+			}
+
+			public NextGearState Clone()
+			{
+				return new NextGearState(this);
+			}
+		}
+	}
+}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
similarity index 95%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
index dbda13c068acc15ad117c4da3d36f8d50610c388..a1c4f828c0726d37590eb17cf9721f3a3bcceed7 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyOptimized.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyOptimized.cs
@@ -10,16 +10,42 @@ using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.Simulation.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
 
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 {
+	public class ATShiftStrategyOptimizedPolygonCalculator : IShiftPolygonCalculator
+	{
+		public ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio,
+			Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		{
+			var shiftLine = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon(
+				Math.Max(i, 2), engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius);
+
+			var upshift = new List<ShiftPolygon.ShiftPolygonEntry>();
+
+			if (i < gearboxGears.Count - 1)
+			{
+				var maxDragTorque = engineDataFullLoadCurve.MaxDragTorque * 1.1;
+				var maxTorque = engineDataFullLoadCurve.MaxTorque * 1.1;
+
+				var speed = engineData.FullLoadCurves[0].NP98hSpeed / gearboxGears[i].Ratio * gearboxGears[i + 1].Ratio;
+
+				upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, speed));
+				upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxTorque, speed));
+			}
+
+			return new ShiftPolygon(shiftLine.Downshift.ToList(), upshift);
+		}
+
+	}
+
 	public class ATShiftStrategyOptimized : ATShiftStrategy
 	{
 		private List<CombustionEngineFuelData> fcMap;
@@ -34,12 +60,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		private List<SchmittTrigger> LoadStageSteps = new List<SchmittTrigger>();
 		private ShiftLineSet UpshiftLineTCLocked = new ShiftLineSet();
+		private IShiftPolygonCalculator _shiftPolygonCalculator;
 
 		public new static string Name => "AT - EffShift";
 
 		public ATShiftStrategyOptimized(IVehicleContainer dataBus) : base(dataBus)
 		{
 			var runData = dataBus.RunData;
+	
 			if (runData.EngineData == null) {
 				return;
 			}
@@ -48,6 +76,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			fld = runData.EngineData.FullLoadCurves;
 			vehicleMass = runData.VehicleData.TotalVehicleMass;
 			shiftStrategyParameters = runData.GearshiftParameters;
+			_shiftPolygonCalculator = ShiftPolygonCalculator.Create(Name, shiftStrategyParameters);
 
 			MinMass = runData.VehicleData.MinimumVehicleMass;
 			MaxMass = runData.VehicleData.MaximumVehicleMass;
@@ -461,27 +490,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		#region Overrides of ATShiftStrategy
 
-		public override ShiftPolygon ComputeDeclarationShiftPolygon(
-			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
-			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio,
-			Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null)
+		public override ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius,
+			ElectricMotorData electricMotorData = null)
 		{
-			var shiftLine = DeclarationData.Gearbox.ComputeEfficiencyShiftPolygon(
-				Math.Max(i, 2), engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius);
-
-			var upshift = new List<ShiftPolygon.ShiftPolygonEntry>();
-
-			if (i < gearboxGears.Count - 1) {
-				var maxDragTorque = engineDataFullLoadCurve.MaxDragTorque * 1.1;
-				var maxTorque = engineDataFullLoadCurve.MaxTorque * 1.1;
-
-				var speed = engineData.FullLoadCurves[0].NP98hSpeed / gearboxGears[i].Ratio * gearboxGears[i + 1].Ratio;
-
-				upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, speed));
-				upshift.Add(new ShiftPolygon.ShiftPolygonEntry(maxTorque, speed));
-			}
-
-			return new ShiftPolygon(shiftLine.Downshift.ToList(), upshift);
+			return _shiftPolygonCalculator.ComputeDeclarationShiftPolygon(gearboxType,
+				i,
+				engineDataFullLoadCurve,
+				gearboxGears, 
+				engineData,
+				axlegearRatio, 
+				dynamicTyreRadius, electricMotorData);
 		}
 
 		#endregion
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyVoith.cs
similarity index 99%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyVoith.cs
index 60ed6796eb8f73ae222d680fd9af480dc32b2ddd..af718f0e896e0259f73a5ecee785ca5ec381f0eb 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategyVoith.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ATShiftStrategyVoith.cs
@@ -9,12 +9,11 @@ using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.Models.Simulation;
 using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
 using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
 
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 {
 	public class ATShiftStrategyVoith : ATShiftStrategy
 	{
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/BaseShiftStrategy.cs
similarity index 97%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/BaseShiftStrategy.cs
index c04dab62a027b87da1e39be6efabd994be84034e..5808569c0281c31b56366684bcff9ea2b9a17b46 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BaseShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/BaseShiftStrategy.cs
@@ -1,132 +1,132 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2019 European Union
-*
-* Developed by Graz University of Technology,
-*              Institute of Internal Combustion Engines and Thermodynamics,
-*              Institute of Technical Informatics
-*
-* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
-* by the European Commission - subsequent versions of the EUPL (the "Licence");
-* You may not use VECTO except in compliance with the Licence.
-* You may obtain a copy of the Licence at:
-*
-* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
-*
-* Unless required by applicable law or agreed to in writing, VECTO
-* distributed under the Licence is distributed on an "AS IS" basis,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Licence for the specific language governing permissions and
-* limitations under the Licence.
-*
-* Authors:
-*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
-*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
-*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
-*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
-*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
-*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
-*/
-
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.OutputData;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public abstract class BaseShiftStrategy : LoggingObject, IShiftStrategy
-	{
-		protected readonly IDataBus DataBus;
-		protected readonly GearboxData GearboxModelData;
-		protected readonly ShiftStrategyParameters GearshiftParams;
-
-		protected readonly GearList Gears;
-
-		protected BaseShiftStrategy(IVehicleContainer dataBus)
-		{
-			GearboxModelData = dataBus.RunData.GearboxData;
-			GearshiftParams = dataBus.RunData.GearshiftParameters;
-			DataBus = dataBus;
-
-			Gears = GearboxModelData.GearList;
-		}
-
-		public virtual bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque,
-			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear,
-			Second lastShiftTime, IResponse response)
-		{
-			CheckGearshiftRequired = true;
-			var retVal = DoCheckShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response);
-			CheckGearshiftRequired = false;
-			return retVal;
-		}
-
-		protected abstract bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque,
-			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear,
-			Second lastShiftTime, IResponse response);
-
-		public abstract GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity);
-		public abstract GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity);
-		public abstract void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity);
-		public abstract IGearbox Gearbox { get; set; }
-		public abstract GearshiftPosition NextGear { get; }
-
-		public bool CheckGearshiftRequired { get; protected set; }
-		public GearshiftPosition MaxStartGear { get; protected set; }
-
-		public virtual void Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
-		{ }
-
-		public virtual void WriteModalResults(IModalDataContainer container)
-		{
-			
-		}
-
-		public abstract ShiftPolygon ComputeDeclarationShiftPolygon(
-			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears,
-			CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null);
-
-		protected MeterPerSquareSecond EstimateAccelerationForGear(GearshiftPosition gear, PerSecond gbxAngularVelocityOut)
-		{
-			if (!Gears.Contains(gear)) {
-				throw new VectoSimulationException("EstimateAccelerationForGear: invalid gear: {0}", gear);
-			}
-
-			var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed;
-
-			var nextEngineSpeed = gbxAngularVelocityOut * GearboxModelData.Gears[gear.Gear].Ratio;
-			var maxEnginePower = DataBus.EngineInfo.EngineStationaryFullPower(nextEngineSpeed);
-
-			var avgSlope =
-				((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude -
-				DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>();
-
-			var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed;
-			var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
-			var gearboxLoss = GearboxModelData.Gears[gear.Gear].LossMap.GetTorqueLoss(gbxAngularVelocityOut,
-				maxEnginePower / nextEngineSpeed * GearboxModelData.Gears[gear.Gear].Ratio).Value * nextEngineSpeed;
-			//DataBus.GearboxLoss();
-			var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
-			var axleLoss = DataBus.AxlegearInfo.AxlegearLoss();
-
-			var accelerationPower = maxEnginePower - gearboxLoss - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss;
-
-			var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels);
-
-			return acceleration.Cast<MeterPerSquareSecond>();
-		}
-
-	}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2019 European Union
+*
+* Developed by Graz University of Technology,
+*              Institute of Internal Combustion Engines and Thermodynamics,
+*              Institute of Technical Informatics
+*
+* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
+* by the European Commission - subsequent versions of the EUPL (the "Licence");
+* You may not use VECTO except in compliance with the Licence.
+* You may obtain a copy of the Licence at:
+*
+* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
+*
+* Unless required by applicable law or agreed to in writing, VECTO
+* distributed under the Licence is distributed on an "AS IS" basis,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the Licence for the specific language governing permissions and
+* limitations under the Licence.
+*
+* Authors:
+*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
+*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
+*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
+*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
+*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
+*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
+*/
+
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.OutputData;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public abstract class BaseShiftStrategy : LoggingObject, IShiftStrategy
+	{
+		protected readonly IDataBus DataBus;
+		protected readonly GearboxData GearboxModelData;
+		protected readonly ShiftStrategyParameters GearshiftParams;
+
+		protected readonly GearList Gears;
+
+		protected BaseShiftStrategy(IVehicleContainer dataBus)
+		{
+			GearboxModelData = dataBus.RunData.GearboxData;
+			GearshiftParams = dataBus.RunData.GearshiftParameters;
+			DataBus = dataBus;
+
+			Gears = GearboxModelData.GearList;
+		}
+
+		public virtual bool ShiftRequired(Second absTime, Second dt, NewtonMeter outTorque,
+			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear,
+			Second lastShiftTime, IResponse response)
+		{
+			CheckGearshiftRequired = true;
+			var retVal = DoCheckShiftRequired(absTime, dt, outTorque, outAngularVelocity, inTorque, inAngularVelocity, gear, lastShiftTime, response);
+			CheckGearshiftRequired = false;
+			return retVal;
+		}
+
+		protected abstract bool DoCheckShiftRequired(Second absTime, Second dt, NewtonMeter outTorque,
+			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition gear,
+			Second lastShiftTime, IResponse response);
+
+		public abstract GearshiftPosition InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity);
+		public abstract GearshiftPosition Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity);
+		public abstract void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity);
+		public abstract IGearbox Gearbox { get; set; }
+		public abstract GearshiftPosition NextGear { get; }
+
+		public bool CheckGearshiftRequired { get; protected set; }
+		public GearshiftPosition MaxStartGear { get; protected set; }
+
+		public virtual void Request(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{ }
+
+		public virtual void WriteModalResults(IModalDataContainer container)
+		{
+			
+		}
+
+		public abstract ShiftPolygon ComputeDeclarationShiftPolygon(
+			GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve, IList<ITransmissionInputData> gearboxGears,
+			CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius, ElectricMotorData electricMotorData = null);
+
+		protected MeterPerSquareSecond EstimateAccelerationForGear(GearshiftPosition gear, PerSecond gbxAngularVelocityOut)
+		{
+			if (!Gears.Contains(gear)) {
+				throw new VectoSimulationException("EstimateAccelerationForGear: invalid gear: {0}", gear);
+			}
+
+			var vehicleSpeed = DataBus.VehicleInfo.VehicleSpeed;
+
+			var nextEngineSpeed = gbxAngularVelocityOut * GearboxModelData.Gears[gear.Gear].Ratio;
+			var maxEnginePower = DataBus.EngineInfo.EngineStationaryFullPower(nextEngineSpeed);
+
+			var avgSlope =
+				((DataBus.DrivingCycleInfo.CycleLookAhead(Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Altitude -
+				DataBus.DrivingCycleInfo.Altitude) / Constants.SimulationSettings.GearboxLookaheadForAccelerationEstimation).Value().SI<Radian>();
+
+			var airDragLoss = DataBus.VehicleInfo.AirDragResistance(vehicleSpeed, vehicleSpeed) * DataBus.VehicleInfo.VehicleSpeed;
+			var rollResistanceLoss = DataBus.VehicleInfo.RollingResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
+			var gearboxLoss = GearboxModelData.Gears[gear.Gear].LossMap.GetTorqueLoss(gbxAngularVelocityOut,
+				maxEnginePower / nextEngineSpeed * GearboxModelData.Gears[gear.Gear].Ratio).Value * nextEngineSpeed;
+			//DataBus.GearboxLoss();
+			var slopeLoss = DataBus.VehicleInfo.SlopeResistance(avgSlope) * DataBus.VehicleInfo.VehicleSpeed;
+			var axleLoss = DataBus.AxlegearInfo.AxlegearLoss();
+
+			var accelerationPower = maxEnginePower - gearboxLoss - axleLoss - airDragLoss - rollResistanceLoss - slopeLoss;
+
+			var acceleration = accelerationPower / DataBus.VehicleInfo.VehicleSpeed / (DataBus.VehicleInfo.TotalMass + DataBus.WheelsInfo.ReducedMassWheels);
+
+			return acceleration.Cast<MeterPerSquareSecond>();
+		}
+
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
similarity index 95%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
index a390b6d8ab318b5caaf021e84ac9d27b70293490..eb5215e876e4df9c408b66599fb9d88ba0a8b4c3 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/MTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/MTShiftStrategy.cs
@@ -1,139 +1,137 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2019 European Union
-*
-* Developed by Graz University of Technology,
-*              Institute of Internal Combustion Engines and Thermodynamics,
-*              Institute of Technical Informatics
-*
-* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
-* by the European Commission - subsequent versions of the EUPL (the "Licence");
-* You may not use VECTO except in compliance with the Licence.
-* You may obtain a copy of the Licence at:
-*
-* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
-*
-* Unless required by applicable law or agreed to in writing, VECTO
-* distributed under the Licence is distributed on an "AS IS" basis,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Licence for the specific language governing permissions and
-* limitations under the Licence.
-*
-* Authors:
-*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
-*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
-*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
-*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
-*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
-*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
-*/
-
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	public class MTShiftStrategy : AMTShiftStrategy
-	{
-		public MTShiftStrategy(IVehicleContainer bus) : base(bus)
-		{
-			EarlyShiftUp = false;
-			SkipGears = true;
-		}
-
-		public new static string Name => "MT Shift Strategy";
-
-		protected override GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
-			NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
-		{
-			// upshift
-			if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				currentGear = Gears.Successor(currentGear);
-
-				while (SkipGears && currentGear.Gear < GearboxModelData.Gears.Count) {
-					currentGear = Gears.Successor(currentGear);
-					var tmpGear = Gearbox.Gear;
-					_gearbox.Gear = currentGear;
-					var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-					_gearbox.Gear = tmpGear;
-
-					inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity;
-					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
-
-					var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2),
-						currentGear.Gear > 1
-							? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed)
-							: double.MaxValue.SI<NewtonMeter>());
-					var reserve = 1 - inTorque / maxTorque;
-
-					if (reserve >= GearshiftParams.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-						continue;
-					}
-
-					currentGear = Gears.Predecessor(currentGear);
-					break;
-				}
-			}
-
-			// early up shift to higher gear ---------------------------------------
-			if (EarlyShiftUp && currentGear.Gear < GearboxModelData.Gears.Count) {
-				// try if next gear would provide enough torque reserve
-				var tryNextGear = Gears.Successor(currentGear);
-				var tmpGear = Gearbox.Gear;
-				_gearbox.Gear = tryNextGear;
-				var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-				_gearbox.Gear = tmpGear;
-
-				inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
-				inTorque = response.Clutch.PowerRequest / inAngularVelocity;
-
-				// if next gear supplied enough power reserve: take it
-				// otherwise take
-				if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
-					var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad;
-					var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
-
-					if (reserve >= GearshiftParams.TorqueReserve) {
-						currentGear = tryNextGear;
-					}
-				}
-			}
-			return currentGear;
-		}
-
-		protected override GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque,
-			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
-		{
-			// down shift
-			if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-				currentGear = Gears.Predecessor(currentGear);
-				while (SkipGears && currentGear.Gear > 1) {
-					currentGear = Gears.Predecessor(currentGear);
-					var tmpGear = Gearbox.Gear;
-					_gearbox.Gear = currentGear;
-					var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
-					_gearbox.Gear = tmpGear;
-
-					inAngularVelocity = GearboxModelData.Gears[currentGear.Gear].Ratio * outAngularVelocity;
-					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
-					var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2),
-						currentGear.Gear > 1
-							? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed)
-							: double.MaxValue.SI<NewtonMeter>());
-					var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value();
-					if (reserve >= GearshiftParams.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
-						continue;
-					}
-					currentGear = Gears.Successor(currentGear);
-					break;
-				}
-			}
-			return currentGear;
-		}
-	}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2019 European Union
+*
+* Developed by Graz University of Technology,
+*              Institute of Internal Combustion Engines and Thermodynamics,
+*              Institute of Technical Informatics
+*
+* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
+* by the European Commission - subsequent versions of the EUPL (the "Licence");
+* You may not use VECTO except in compliance with the Licence.
+* You may obtain a copy of the Licence at:
+*
+* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
+*
+* Unless required by applicable law or agreed to in writing, VECTO
+* distributed under the Licence is distributed on an "AS IS" basis,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the Licence for the specific language governing permissions and
+* limitations under the Licence.
+*
+* Authors:
+*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
+*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
+*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
+*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
+*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
+*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
+*/
+
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
+{
+	public class MTShiftStrategy : AMTShiftStrategy
+	{
+		public MTShiftStrategy(IVehicleContainer bus) : base(bus)
+		{
+			EarlyShiftUp = false;
+			SkipGears = true;
+		}
+
+		public new static string Name => "MT Shift Strategy";
+
+		protected override GearshiftPosition DoCheckUpshift(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity,
+			NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
+		{
+			// upshift
+			if (IsAboveUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				currentGear = Gears.Successor(currentGear);
+
+				while (SkipGears && currentGear.Gear < GearboxModelData.Gears.Count) {
+					currentGear = Gears.Successor(currentGear);
+					var tmpGear = Gearbox.Gear;
+					_gearbox.Gear = currentGear;
+					var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+					_gearbox.Gear = tmpGear;
+
+					inAngularVelocity = response.Engine.EngineSpeed; //ModelData.Gears[currentGear].Ratio * outAngularVelocity;
+					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
+
+					var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2),
+						currentGear.Gear > 1
+							? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed)
+							: double.MaxValue.SI<NewtonMeter>());
+					var reserve = 1 - inTorque / maxTorque;
+
+					if (reserve >= GearshiftParams.TorqueReserve && IsAboveDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+						continue;
+					}
+
+					currentGear = Gears.Predecessor(currentGear);
+					break;
+				}
+			}
+
+			// early up shift to higher gear ---------------------------------------
+			if (EarlyShiftUp && currentGear.Gear < GearboxModelData.Gears.Count) {
+				// try if next gear would provide enough torque reserve
+				var tryNextGear = Gears.Successor(currentGear);
+				var tmpGear = Gearbox.Gear;
+				_gearbox.Gear = tryNextGear;
+				var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+				_gearbox.Gear = tmpGear;
+
+				inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
+				inTorque = response.Clutch.PowerRequest / inAngularVelocity;
+
+				// if next gear supplied enough power reserve: take it
+				// otherwise take
+				if (!IsBelowDownShiftCurve(tryNextGear, inTorque, inAngularVelocity)) {
+					var fullLoadPower = response.Engine.PowerRequest - response.DeltaFullLoad;
+					var reserve = 1 - response.Engine.PowerRequest / fullLoadPower;
+
+					if (reserve >= GearshiftParams.TorqueReserve) {
+						currentGear = tryNextGear;
+					}
+				}
+			}
+			return currentGear;
+		}
+
+		protected override GearshiftPosition DoCheckDownshift(Second absTime, Second dt, NewtonMeter outTorque,
+			PerSecond outAngularVelocity, NewtonMeter inTorque, PerSecond inAngularVelocity, GearshiftPosition currentGear, IResponse response1)
+		{
+			// down shift
+			if (IsBelowDownShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+				currentGear = Gears.Predecessor(currentGear);
+				while (SkipGears && currentGear.Gear > 1) {
+					currentGear = Gears.Predecessor(currentGear);
+					var tmpGear = Gearbox.Gear;
+					_gearbox.Gear = currentGear;
+					var response = (ResponseDryRun)_gearbox.Request(absTime, dt, outTorque, outAngularVelocity, true);
+					_gearbox.Gear = tmpGear;
+
+					inAngularVelocity = GearboxModelData.Gears[currentGear.Gear].Ratio * outAngularVelocity;
+					inTorque = response.Clutch.PowerRequest / inAngularVelocity;
+					var maxTorque = VectoMath.Min(response.Engine.DynamicFullLoadPower / ((DataBus.EngineInfo.EngineSpeed + response.Engine.EngineSpeed) / 2),
+						currentGear.Gear > 1
+							? GearboxModelData.Gears[currentGear.Gear].ShiftPolygon.InterpolateDownshift(response.Engine.EngineSpeed)
+							: double.MaxValue.SI<NewtonMeter>());
+					var reserve = maxTorque.IsEqual(0) ? -1 : (1 - inTorque / maxTorque).Value();
+					if (reserve >= GearshiftParams.TorqueReserve && IsBelowUpShiftCurve(currentGear, inTorque, inAngularVelocity)) {
+						continue;
+					}
+					currentGear = Gears.Successor(currentGear);
+					break;
+				}
+			}
+			return currentGear;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs
similarity index 89%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs
index c441b6e66c7928b1ab0d838551784293e8e1a6e6..4cc028a223913212b17db2eea5070b3563422d87 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/PEVAMTShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/PEVAMTShiftStrategy.cs
@@ -5,7 +5,6 @@ using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
 using TUGraz.VectoCore.InputData.Reader.DataObjectAdapter;
 using TUGraz.VectoCore.Models.Connector.Ports.Impl;
 using TUGraz.VectoCore.Models.Declaration;
@@ -17,13 +16,46 @@ using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.ElectricMotor;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.Models.SimulationComponent.Strategies;
 using TUGraz.VectoCore.OutputData;
 using TUGraz.VectoCore.Utils;
 
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
 {
 
+	public class PEVAMTShiftStrategyPolygonCreator : IShiftPolygonCalculator
+	{
+		private ShiftStrategyParameters _shiftStrategyParameters;
+
+		public PEVAMTShiftStrategyPolygonCreator(ShiftStrategyParameters shiftStrategyparamets)
+		{
+			_shiftStrategyParameters = shiftStrategyparamets;
+		}
+
+		public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius,
+			ElectricMotorData electricMotorData = null)
+		{
+			if (electricMotorData == null)
+			{
+				throw new VectoException("ElectricMotorData is required to calculate Shift Polygon!");
+			}
+			var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
+			return ComputeDeclarationShiftPolygon(i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData,
+				_shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
+		}
+
+
+		public ShiftPolygon ComputeDeclarationShiftPolygon(int i,
+			IList<ITransmissionInputData> gearboxGears, double axlegearRatio,
+			Meter dynamicTyreRadius,
+			ElectricMotorData electricMotorData, PerSecond downshiftMaxSpeed, PerSecond downshiftMinSpeed)
+		{
+			return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i,
+				electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC,
+				gearboxGears, axlegearRatio, dynamicTyreRadius, downshiftMaxSpeed, downshiftMinSpeed);
+		}
+	}
+
 	public class PEVAMTShiftStrategy : LoggingObject, IShiftStrategy
 	{
 		protected IDataBus DataBus;
@@ -32,7 +64,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		protected Gearbox _gearbox;
 		protected GearshiftPosition _nextGear;
 
-		private ShiftStrategyParameters shiftStrategyParameters;
+		private readonly ShiftStrategyParameters _shiftStrategyParameters;
 		protected readonly VelocityRollingLookup VelocityDropData = new VelocityRollingLookup();
 		private SimplePowertrainContainer TestContainer;
 		private Gearbox TestContainerGbx;
@@ -50,6 +82,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		private double EMRatio;
 
 		protected PowertrainPosition EMPos;
+		private PEVAMTShiftStrategyPolygonCreator _shiftPolygonImplementation;
 
 		public static string Name => "AMT - EffShift (BEV)";
 
@@ -62,6 +95,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				return;
 			}
 
+			
+
 			EMPos = dataBus.RunData.ElectricMachinesData.FirstOrDefault(x =>
 				x.Item1 == PowertrainPosition.BatteryElectricE2 || x.Item1 == PowertrainPosition.IEPC)?.Item1 ?? PowertrainPosition.HybridPositionNotSet;
 			SetupVelocityDropPreprocessor(dataBus);
@@ -71,7 +106,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		{
 			DataBus = dataBus;
 			var runData = dataBus.RunData;
-			shiftStrategyParameters = runData.GearshiftParameters;
+			_shiftStrategyParameters = runData.GearshiftParameters;
+			_shiftPolygonImplementation =
+				ShiftPolygonCalculator.Create(Name, _shiftStrategyParameters) as PEVAMTShiftStrategyPolygonCreator;
 			if (runData.VehicleData == null) {
 				return;
 			}
@@ -90,7 +127,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 								(runData.AngledriveData?.Angledrive.Ratio ?? 1.0) /
 								runData.VehicleData.DynamicTyreRadius;
 
-			if (shiftStrategyParameters == null) {
+			if (_shiftStrategyParameters == null) {
 				throw new VectoException("Parameters for shift strategy missing!");
 			}
 
@@ -129,32 +166,34 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				new VelocitySpeedGearshiftPreprocessorE2(VelocityDropData, runData.GearboxData.TractionInterruption, TestContainer, -grad, grad, 2));
 		}
 
-		#region Implementation of IShiftPolygonCalculator
 
-		public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
-			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius,
-			ElectricMotorData electricMotorData = null)
-		{
-			if (electricMotorData == null) {
-				throw new VectoException("ElectricMotorData is required to calculate Shift Polygon!");
-			}
-			var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
-			return ComputeDeclarationShiftPolygon(i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData,
-				shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
-		}
 
+		//#region Implementation of IShiftPolygonCalculator
 
-		public ShiftPolygon ComputeDeclarationShiftPolygon(int i,
-			IList<ITransmissionInputData> gearboxGears, double axlegearRatio,
-			Meter dynamicTyreRadius,
-			ElectricMotorData electricMotorData, PerSecond downshiftMaxSpeed, PerSecond downshiftMinSpeed)
-		{
-			return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i,
-				electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC,
-				gearboxGears, axlegearRatio, dynamicTyreRadius, downshiftMaxSpeed, downshiftMinSpeed);
-		}
+		//public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+		//	IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius,
+		//	ElectricMotorData electricMotorData = null)
+		//{
+		//	if (electricMotorData == null) {
+		//		throw new VectoException("ElectricMotorData is required to calculate Shift Polygon!");
+		//	}
+		//	var emFld = electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve;
+		//	return ComputeDeclarationShiftPolygon(i, gearboxGears, axlegearRatio, dynamicTyreRadius, electricMotorData,
+		//		_shiftStrategyParameters.PEV_DownshiftSpeedFactor.LimitTo(0, 1) * emFld.RatedSpeed, _shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
+		//}
 
-		#endregion
+
+		//private ShiftPolygon ComputeDeclarationShiftPolygon(int i,
+		//	IList<ITransmissionInputData> gearboxGears, double axlegearRatio,
+		//	Meter dynamicTyreRadius,
+		//	ElectricMotorData electricMotorData, PerSecond downshiftMaxSpeed, PerSecond downshiftMinSpeed)
+		//{
+		//	return DeclarationData.Gearbox.ComputeElectricMotorShiftPolygon(i,
+		//		electricMotorData.EfficiencyData.VoltageLevels.First().FullLoadCurve, electricMotorData.RatioADC,
+		//		gearboxGears, axlegearRatio, dynamicTyreRadius, downshiftMaxSpeed, downshiftMinSpeed);
+		//}
+
+		//#endregion
 
 		protected internal Dictionary<uint, ShiftPolygon> CalculateDeratedShiftLines(ElectricMotorData em,
 			IList<ITransmissionInputData> gearData, Meter rDyn, double axleGearRatio, GearboxType gearboxType)
@@ -185,10 +224,10 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					}
 				};
 
-				var shiftPolygon = ComputeDeclarationShiftPolygon((int)i,
+				var shiftPolygon = _shiftPolygonImplementation.ComputeDeclarationShiftPolygon((int)i,
 					gearData, axleGearRatio,
-					rDyn, limitedEm, shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor * emFld.RatedSpeed,
-					shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
+					rDyn, limitedEm, _shiftStrategyParameters.PEV_DeRatedDownshiftSpeedFactor * emFld.RatedSpeed,
+					_shiftStrategyParameters.PEV_DownshiftMinSpeedFactor * emFld.RatedSpeed);
 				retVal[i + 1] = shiftPolygon;
 			}
 
@@ -334,7 +373,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			var vDrop = DataBus.VehicleInfo.VehicleSpeed - estimatedVelocityPostShift;
 			var vehicleSpeedPostShift =
-				DataBus.VehicleInfo.VehicleSpeed - vDrop * shiftStrategyParameters.VelocityDropFactor;
+				DataBus.VehicleInfo.VehicleSpeed - vDrop * _shiftStrategyParameters.VelocityDropFactor;
 
 			var totalTransmissionRatio =
 				DataBus.ElectricMotorInfo(EMPos).ElectricMotorSpeed /
@@ -342,7 +381,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			var results = new List<Tuple<GearshiftPosition, double>>();
 			foreach (var tryNextGear in GearList.IterateGears(GearList.Successor(currentGear),
-				GearList.Successor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) {
+				GearList.Successor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) {
 				var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear);
 
 				var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
@@ -354,7 +393,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 				var estimatedEngineSpeed = vehicleSpeedPostShift * (totalTransmissionRatio /
 						GearboxModelData.Gears[currentGear.Gear].Ratio * GearboxModelData.Gears[tryNextGear.Gear].Ratio);
-				if (estimatedEngineSpeed.IsSmaller(shiftStrategyParameters.MinEngineSpeedPostUpshift)) {
+				if (estimatedEngineSpeed.IsSmaller(_shiftStrategyParameters.MinEngineSpeedPostUpshift)) {
 					continue;
 				}
 
@@ -379,8 +418,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var minFc = results.MaxBy(x => x.Item2);
 
 			var ratingFactor = outTorque < 0
-				? 1 / shiftStrategyParameters.RatingFactorCurrentGear
-				: shiftStrategyParameters.RatingFactorCurrentGear;
+				? 1 / _shiftStrategyParameters.RatingFactorCurrentGear
+				: _shiftStrategyParameters.RatingFactorCurrentGear;
 
 			if (minFc.Item2.IsGreater(fcCurrent * ratingFactor)) {
 				return minFc.Item1;
@@ -483,7 +522,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			var ratedSpeed = VoltageLevels.VoltageLevels.First().FullLoadCurve.RatedSpeed;
 			var maxSpeedNorm = VoltageLevels.MaxSpeed / ratedSpeed;
-			var targetMotor = (shiftStrategyParameters.PEV_TargetSpeedBrakeNorm * (maxSpeedNorm - 1) + 1) * ratedSpeed;
+			var targetMotor = (_shiftStrategyParameters.PEV_TargetSpeedBrakeNorm * (maxSpeedNorm - 1) + 1) * ratedSpeed;
 
 			if (candidates.Any(x => x.Value > targetMotor && x.Value < VoltageLevels.MaxSpeed)) {
 				var best = candidates.Where(x => x.Value > targetMotor && x.Value < VoltageLevels.MaxSpeed)
@@ -510,7 +549,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			var results = new List<Tuple<GearshiftPosition, double>>();
 			foreach (var tryNextGear in GearList.IterateGears(GearList.Predecessor(currentGear),
-				GearList.Predecessor(currentGear, (uint)shiftStrategyParameters.AllowedGearRangeFC))) {
+				GearList.Predecessor(currentGear, (uint)_shiftStrategyParameters.AllowedGearRangeFC))) {
 
 				var response = RequestDryRunWithGear(absTime, dt, outTorque, outAngularVelocity, tryNextGear);
 				var inAngularVelocity = GearboxModelData.Gears[tryNextGear.Gear].Ratio * outAngularVelocity;
@@ -532,8 +571,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			var fcCurrent = GetFCRating(responseCurrent);
 			var minFc = results.MinBy(x => x.Item2);
 			var ratingFactor = outTorque < 0
-				? 1 / shiftStrategyParameters.RatingFactorCurrentGear
-				: shiftStrategyParameters.RatingFactorCurrentGear;
+				? 1 / _shiftStrategyParameters.RatingFactorCurrentGear
+				: _shiftStrategyParameters.RatingFactorCurrentGear;
 
 			if (minFc.Item2.IsGreater(fcCurrent * ratingFactor)) {
 				return minFc.Item1;
@@ -860,5 +899,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			#endregion
 		}
+
+		#region Implementation of IShiftPolygonCalculator
+
+		public ShiftPolygon ComputeDeclarationShiftPolygon(GearboxType gearboxType, int i, EngineFullLoadCurve engineDataFullLoadCurve,
+			IList<ITransmissionInputData> gearboxGears, CombustionEngineData engineData, double axlegearRatio, Meter dynamicTyreRadius,
+			ElectricMotorData electricMotorData = null)
+		{
+			return _shiftPolygonImplementation.ComputeDeclarationShiftPolygon(gearboxType, i, engineDataFullLoadCurve, gearboxGears, engineData, axlegearRatio, dynamicTyreRadius, electricMotorData);
+		}
+
+		#endregion
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCreator.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCreator.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5aa59950a5e62b47a0bc85965122292b2338008f
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftPolygonCreator.cs
@@ -0,0 +1,48 @@
+using System;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCore.Models.Simulation.Data;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
+{
+	public abstract class ShiftPolygonCalculator
+	{
+		public static IShiftPolygonCalculator Create(string name, ShiftStrategyParameters shiftStrategyParameters)
+		{
+			if (name == AMTShiftStrategyOptimized.Name) {
+				return new AMTShiftStrategyOptimizedPolygonCalculator();
+			}
+
+			if (name == PEVAMTShiftStrategy.Name) {
+				if (shiftStrategyParameters == null) {
+					throw new ArgumentException($"{nameof(shiftStrategyParameters)} required for {name}");
+				}
+				return new PEVAMTShiftStrategyPolygonCreator(shiftStrategyParameters);
+			}
+
+			if (name == MTShiftStrategy.Name) {
+				return new AMTShiftStrategyPolygonCalculator();
+			}
+
+			if (name == ATShiftStrategyOptimized.Name) {
+				return new ATShiftStrategyOptimizedPolygonCalculator();
+			}
+
+			if (name == APTNShiftStrategy.Name) {
+				if (shiftStrategyParameters == null)
+				{
+					throw new ArgumentException($"{nameof(shiftStrategyParameters)} required for {name}");
+				}
+				return new PEVAMTShiftStrategyPolygonCreator(shiftStrategyParameters);
+			}
+
+
+
+
+			throw new ArgumentException($"Could not create ShiftPolygonCalculator for {name}");
+
+
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftStrategy.cs
similarity index 83%
rename from VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
rename to VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftStrategy.cs
index e7cb660c2c3d5c48c3fba2ecb7fe4986761df1d6..6aaf26834191e3a991169e3cfee8aab98e6ddb57 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/ShiftStrategy.cs
@@ -1,109 +1,136 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2019 European Union
-*
-* Developed by Graz University of Technology,
-*              Institute of Internal Combustion Engines and Thermodynamics,
-*              Institute of Technical Informatics
-*
-* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
-* by the European Commission - subsequent versions of the EUPL (the "Licence");
-* You may not use VECTO except in compliance with the Licence.
-* You may obtain a copy of the Licence at:
-*
-* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
-*
-* Unless required by applicable law or agreed to in writing, VECTO
-* distributed under the Licence is distributed on an "AS IS" basis,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Licence for the specific language governing permissions and
-* limitations under the Licence.
-*
-* Authors:
-*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
-*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
-*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
-*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
-*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
-*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
-*/
-
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-
-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 : BaseShiftStrategy
-	{
-		protected bool SkipGears;
-		protected bool EarlyShiftUp;
-		protected Gearbox _gearbox;
-
-		protected ShiftStrategy(IVehicleContainer dataBus) : base(dataBus) {}
-
-		public override IGearbox Gearbox
-		{
-			get => _gearbox;
-			set {
-				var myGearbox = value as Gearbox;
-				if (myGearbox == null) {
-					throw new VectoException("This shift strategy can't handle gearbox of type {0}", value.GetType());
-				}
-				_gearbox = myGearbox;
-			}
-		}
-
-		/// <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 bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
-		{
-			if (!Gears.HasPredecessor(gear)) {
-				return false;
-			}
-			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed);
-		}
-
-		protected bool IsAboveDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
-		{
-			if (!Gears.HasPredecessor(gear)) {
-				return true;
-			}
-			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveDownshiftCurve(inTorque, inEngineSpeed);
-		}
-
-
-		/// <summary>
-		/// 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 bool IsAboveUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
-		{
-			if (!Gears.HasSuccessor(gear)) {
-				return false;
-			}
-			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
-		}
-
-		protected bool IsBelowUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
-		{
-			if (!Gears.HasSuccessor(gear)) {
-				return true;
-			}
-			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowUpshiftCurve(inTorque, inEngineSpeed);
-		}
-	}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2019 European Union
+*
+* Developed by Graz University of Technology,
+*              Institute of Internal Combustion Engines and Thermodynamics,
+*              Institute of Technical Informatics
+*
+* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
+* by the European Commission - subsequent versions of the EUPL (the "Licence");
+* You may not use VECTO except in compliance with the Licence.
+* You may obtain a copy of the Licence at:
+*
+* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
+*
+* Unless required by applicable law or agreed to in writing, VECTO
+* distributed under the Licence is distributed on an "AS IS" basis,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the Licence for the specific language governing permissions and
+* limitations under the Licence.
+*
+* Authors:
+*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
+*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
+*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
+*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
+*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
+*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
+*/
+
+using System;
+using Newtonsoft.Json;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Simulation;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies
+{
+	/// <summary>
+	/// Class ShiftStrategy is a base class for shift strategies. Implements some helper methods for checking the shift curves.
+	/// </summary>
+	public abstract class ShiftStrategy : BaseShiftStrategy
+	{
+		protected bool SkipGears;
+		protected bool EarlyShiftUp;
+		protected Gearbox _gearbox;
+
+		public static IShiftStrategy Create(IVehicleContainer container, string name)
+		{
+			
+			if (name == AMTShiftStrategyOptimized.Name) {
+				return new AMTShiftStrategyOptimized(container);
+			}
+
+			if (name == PEVAMTShiftStrategy.Name) {
+				return new PEVAMTShiftStrategy(container);
+			}
+
+			if (name == MTShiftStrategy.Name) {
+				return new MTShiftStrategy(container);
+			}
+
+			if (name == ATShiftStrategyOptimized.Name) {
+				return new ATShiftStrategyOptimized(container);
+			}
+
+			if (name == APTNShiftStrategy.Name) {
+				return new APTNShiftStrategy(container);
+			}
+
+			throw new ArgumentOutOfRangeException(nameof(name), $@"Could not create shift strategy {name}");
+		}
+
+		protected ShiftStrategy(IVehicleContainer dataBus) : base(dataBus) {}
+
+		public override IGearbox Gearbox
+		{
+			get => _gearbox;
+			set {
+				var myGearbox = value as Gearbox;
+				if (myGearbox == null) {
+					throw new VectoException("This shift strategy can't handle gearbox of type {0}", value.GetType());
+				}
+				_gearbox = myGearbox;
+			}
+		}
+
+		/// <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 bool IsBelowDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		{
+			if (!Gears.HasPredecessor(gear)) {
+				return false;
+			}
+			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowDownshiftCurve(inTorque, inEngineSpeed);
+		}
+
+		protected bool IsAboveDownShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		{
+			if (!Gears.HasPredecessor(gear)) {
+				return true;
+			}
+			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveDownshiftCurve(inTorque, inEngineSpeed);
+		}
+
+
+		/// <summary>
+		/// 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 bool IsAboveUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		{
+			if (!Gears.HasSuccessor(gear)) {
+				return false;
+			}
+			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsAboveUpshiftCurve(inTorque, inEngineSpeed);
+		}
+
+		protected bool IsBelowUpShiftCurve(GearshiftPosition gear, NewtonMeter inTorque, PerSecond inEngineSpeed)
+		{
+			if (!Gears.HasSuccessor(gear)) {
+				return true;
+			}
+			return GearboxModelData.Gears[gear.Gear].ShiftPolygon.IsBelowUpshiftCurve(inTorque, inEngineSpeed);
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/Shiftstrategies.cd b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/Shiftstrategies.cd
new file mode 100644
index 0000000000000000000000000000000000000000..40c35fc94bdb941c6cb718241aaa171b0ff71ab3
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Shiftstrategies/Shiftstrategies.cd
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ShiftStrategy">
+    <Position X="1.5" Y="2.25" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>EEAEAAAIACABAAAAAAAAAAAAAAAAAEAgAAAAAAAAAAE=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.BaseShiftStrategy" Collapsed="true">
+    <Position X="3.75" Y="0.75" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>AAAEAAAAAAIAECAIABgAYAmAAAAAgAAEAIAAAACAAAg=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\BaseShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+    <Lollipop Position="0.2" />
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.AMTShiftStrategy">
+    <Position X="1" Y="6.25" Width="2.5" />
+    <TypeIdentifier>
+      <HashCode>KAAAAgAAAAIAAAAAALCgYA0AAAGAAAAAIIAAAAAABAA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\AMTShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController" Collapsed="true">
+    <Position X="10.75" Y="0.75" Width="1.5" />
+    <Compartments>
+      <Compartment Name="Nested Types" Collapsed="false" />
+    </Compartments>
+    <NestedTypes>
+      <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridCtlShiftStrategy" Collapsed="true">
+        <TypeIdentifier>
+          <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName>
+        </TypeIdentifier>
+      </Class>
+      <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridControllerState" Collapsed="true">
+        <TypeIdentifier>
+          <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName>
+        </TypeIdentifier>
+      </Class>
+      <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.ElectricMotorController" Collapsed="true">
+        <TypeIdentifier>
+          <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName>
+        </TypeIdentifier>
+        <Lollipop Position="0.2" />
+      </Class>
+      <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridCtlATShiftStrategy" Collapsed="true">
+        <TypeIdentifier>
+          <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName>
+        </TypeIdentifier>
+      </Class>
+      <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.HybridController.HybridCtlIHPCShiftStrategy" Collapsed="true">
+        <TypeIdentifier>
+          <NewMemberFileName>Models\SimulationComponent\Impl\HybridController.cs</NewMemberFileName>
+        </TypeIdentifier>
+      </Class>
+    </NestedTypes>
+    <TypeIdentifier>
+      <HashCode>BAAEAAAQAAIAAwgAAIA0ABDAAQCMhAAUBAAAABCAMAA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\HybridController.cs</FileName>
+    </TypeIdentifier>
+    <Lollipop Position="0.2" />
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ATShiftStrategyOptimized">
+    <Position X="5" Y="3.75" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>CAAAAgACDAABAAEAJLgAgAQACAAAABAQAYAAAAAAhQA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ATShiftStrategyOptimized.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.AMTShiftStrategyOptimized" Collapsed="true">
+    <Position X="0.5" Y="12.25" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>CAAAAgAKAAAAAAEAJJAAAAQACAAACAAAIAAAAAAABQA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\AMTShiftStrategyOptimized.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.APTNShiftStrategy" Collapsed="true">
+    <Position X="9.5" Y="6.25" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>AAAAAgACAAAAAAAAAAAgAAQAAAAAAAAAAAAAAAAAAAA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\APTNShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ATShiftStrategy" Collapsed="true">
+    <Position X="6" Y="2.25" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>OAAESgACACIAAAAAABAAcA0ABAAAAIAAAoAABAAAAAE=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ATShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.ATShiftStrategyVoith" Collapsed="true">
+    <Position X="7.25" Y="3.75" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>IAAAAAgADQCAEAAYABgEBAUBAAAAgBAMQIAAAAAAgAA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\ATShiftStrategyVoith.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.MTShiftStrategy" Collapsed="true">
+    <Position X="2.75" Y="12.25" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>AAAAAAAAAAAAAAAAAAAgAAQAAAAAAAAAIAAAAAAAAAA=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\MTShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Class>
+  <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.PEVAMTShiftStrategy" Collapsed="true">
+    <Position X="9.5" Y="3.75" Width="1.5" />
+    <NestedTypes>
+      <Class Name="TUGraz.VectoCore.Models.SimulationComponent.Impl.Shiftstrategies.PEVAMTShiftStrategy.PEVInitControl" Collapsed="true">
+        <TypeIdentifier>
+          <NewMemberFileName>Models\SimulationComponent\Impl\Shiftstrategies\PEVAMTShiftStrategy.cs</NewMemberFileName>
+        </TypeIdentifier>
+        <Lollipop Position="0.2" />
+      </Class>
+    </NestedTypes>
+    <TypeIdentifier>
+      <HashCode>OJCEIgAKACIAECAMJLCgbA2ADABAiEA0AIAAEBBAAAk=</HashCode>
+      <FileName>Models\SimulationComponent\Impl\Shiftstrategies\PEVAMTShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+    <Lollipop Position="0.2" />
+  </Class>
+  <Interface Name="TUGraz.VectoCore.Models.SimulationComponent.IShiftStrategy">
+    <Position X="12.5" Y="5.25" Width="1.5" />
+    <InheritanceLine Type="TUGraz.VectoCore.Models.SimulationComponent.IShiftPolygonCalculator" FixedToPoint="true">
+      <Path>
+        <Point X="13.25" Y="3.603" />
+        <Point X="13.25" Y="4.875" />
+        <Point X="13.5" Y="4.875" />
+        <Point X="13.5" Y="5.25" />
+      </Path>
+    </InheritanceLine>
+    <TypeIdentifier>
+      <HashCode>AAAEAAAAAAIAECAAAAAAQAgAAAAAgAAEAIAAAAAAAAg=</HashCode>
+      <FileName>Models\SimulationComponent\IShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Interface>
+  <Interface Name="TUGraz.VectoCore.Models.SimulationComponent.IShiftPolygonCalculator">
+    <Position X="12.5" Y="2.5" Width="1.5" />
+    <TypeIdentifier>
+      <HashCode>AAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+      <FileName>Models\SimulationComponent\IShiftStrategy.cs</FileName>
+    </TypeIdentifier>
+  </Interface>
+  <Font Name="Segoe UI" Size="9" />
+</ClassDiagram>
\ No newline at end of file