diff --git a/VectoCommon/VectoCommon/Utils/EnumberableExtensionMethods.cs b/VectoCommon/VectoCommon/Utils/EnumberableExtensionMethods.cs
index c00dcf6cb4dc3ce6f3f5ba6b4d9b845903fd25e1..e201aff1d90a524fd344c584910348b169a5e94d 100644
--- a/VectoCommon/VectoCommon/Utils/EnumberableExtensionMethods.cs
+++ b/VectoCommon/VectoCommon/Utils/EnumberableExtensionMethods.cs
@@ -188,5 +188,22 @@ namespace TUGraz.VectoCommon.Utils
 				return min;
 			}
 		}
+
+
+		public static IEnumerable<TResult> Pairwise<TSource, TResult>(this IEnumerable<TSource> source,
+			Func<TSource, TSource, TResult> resultSelector)
+		{
+			var previous = default(TSource);
+
+			using (var it = source.GetEnumerator()) {
+				if (it.MoveNext()) {
+					previous = it.Current;
+				}
+
+				while (it.MoveNext()) {
+					yield return resultSelector(previous, previous = it.Current);
+				}
+			}
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs
index 0e7f597d31eb18b310a9390f0ff10dc9da14785c..c0ee9b9bf2a553bb4013fe100761dac76760aa39 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs
@@ -33,6 +33,7 @@ using System.Collections.Generic;
 using System.Data;
 using System.Linq;
 using Newtonsoft.Json.Linq;
+using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
@@ -74,15 +75,26 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public virtual double Ratio
 		{
-			get { return Body.GetEx(JsonKeys.Gearbox_Gears)[0].GetEx<double>(JsonKeys.Gearbox_Gear_Ratio); }
+			get
+			{
+				var gears = Body.GetEx(JsonKeys.Gearbox_Gears);
+				if (!gears.Any()) {
+					throw new VectoSimulationException("At least one Gear-Entry must be defined in Gearbox!");
+				}
+				return gears[0].GetEx<double>(JsonKeys.Gearbox_Gear_Ratio);
+			}
 		}
 
 		public DataTable LossMap
 		{
 			get
 			{
+				var gears = Body.GetEx(JsonKeys.Gearbox_Gears);
+				if (!gears.Any()) {
+					throw new VectoSimulationException("At least one Gear-Entry must be defined in Gearbox!");
+				}
 				return ReadTableData(
-					Body.GetEx(JsonKeys.Gearbox_Gears)[0].GetEx<string>(JsonKeys.Gearbox_Gear_LossMapFile), "AxleGear");
+					gears[0].GetEx<string>(JsonKeys.Gearbox_Gear_LossMapFile), "AxleGear");
 			}
 		}
 
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs
index 58846a5fddffb7ef28eb2ea75904175d624036f5..f5bcee9adeb2a0e02c28a40bafefdc374a8f5946 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputDataFactory.cs
@@ -39,7 +39,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 {
 	public class JSONInputDataFactory
 	{
-		protected static JObject ReadFile(string fileName)
+		protected internal static JObject ReadFile(string fileName)
 		{
 			if (!File.Exists(fileName)) {
 				throw new FileNotFoundException("failed to load file: " + fileName, fileName);
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/DeclarationDataAdapter.cs
index 002185db2e864864d303bf1b7e29efca3223bdd1..950694bb018e2ce49e17be0fcf8e65f59235f540 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/DeclarationDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/DeclarationDataAdapter.cs
@@ -155,7 +155,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdaper
 			return retVal;
 		}
 
-		internal GearboxData CreateGearboxData(IGearboxDeclarationInputData gearbox, CombustionEngineData engine)
+		internal GearboxData CreateGearboxData(IGearboxDeclarationInputData gearbox, CombustionEngineData engine,
+			double axlegearRatio, Meter dynamicTyreRadius)
 		{
 			if (!gearbox.SavedInDeclarationMode) {
 				WarnDeclarationMode("GearboxData");
@@ -194,7 +195,9 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdaper
 					: FullLoadCurve.Create(gear.FullLoadCurve, true);
 
 				var fullLoadCurve = IntersectFullLoadCurves(engine.FullLoadCurve, gearFullLoad);
-				var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(fullLoadCurve, engine.IdleSpeed);
+				var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(i, fullLoadCurve, gears, engine, axlegearRatio,
+					dynamicTyreRadius);
+
 				return new KeyValuePair<uint, GearData>((uint)i + 1,
 					new GearData {
 						LossMap = gearLossMap,
@@ -207,7 +210,6 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdaper
 			return retVal;
 		}
 
-
 		public IList<VectoRunData.AuxData> CreateAuxiliaryData(IAuxiliariesDeclarationInputData auxInputData,
 			MissionType mission, VehicleClass hvdClass)
 		{
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs
index d25dd8fd903c2de4ba18b80a7963ec28c1897076..09a4fa4c70a1a4b57cebb7ef7d7fdf85469046f0 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdaper/EngineeringDataAdapter.cs
@@ -36,6 +36,7 @@ using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
@@ -115,7 +116,8 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdaper
 			return retVal;
 		}
 
-		internal GearboxData CreateGearboxData(IGearboxEngineeringInputData gearbox, CombustionEngineData engineData)
+		internal GearboxData CreateGearboxData(IGearboxEngineeringInputData gearbox, CombustionEngineData engineData,
+			double axlegearRatio, Meter dynamicTyreRadius)
 		{
 			if (gearbox.SavedInDeclarationMode) {
 				WarnEngineeringMode("GearboxData");
@@ -151,7 +153,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdaper
 				var fullLoadCurve = IntersectFullLoadCurves(engineData.FullLoadCurve, gearFullLoad);
 				var shiftPolygon = gear.ShiftPolygon != null
 					? ShiftPolygon.Create(gear.ShiftPolygon)
-					: DeclarationData.Gearbox.ComputeShiftPolygon(fullLoadCurve, engineData.IdleSpeed);
+					: DeclarationData.Gearbox.ComputeShiftPolygon(i, fullLoadCurve, gears, engineData, axlegearRatio, dynamicTyreRadius);
 
 				return new KeyValuePair<uint, GearData>((uint)(i + 1), new GearData {
 					LossMap = lossMap,
diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs
index 67ff25d380bdf10b538cfa3efc2ad21f1a4ff8e9..140f5e088aad13cf49e54e9e15614346ff6fd4dd 100644
--- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs
+++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationModeVectoRunDataFactory.cs
@@ -68,9 +68,11 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
 			var driverdata = dao.CreateDriverData(InputDataProvider.DriverInputData);
 			driverdata.AccelerationCurve = AccelerationCurveData.ReadFromStream(segment.AccelerationFile);
 
+			var tempVehicle = dao.CreateVehicleData(InputDataProvider.VehicleInputData, segment.Missions.First(), segment.Missions.First().Loadings.First().Value);
 			var engineData = dao.CreateEngineData(InputDataProvider.EngineInputData);
-			var gearboxData = dao.CreateGearboxData(InputDataProvider.GearboxInputData, engineData);
 			var axlegearData = dao.CreateAxleGearData(InputDataProvider.AxleGearInputData);
+			var gearboxData = dao.CreateGearboxData(InputDataProvider.GearboxInputData, engineData, axlegearData.AxleGear.Ratio,
+				tempVehicle.DynamicTyreRadius);
 			var retarderData = dao.CreateRetarderData(InputDataProvider.RetarderInputData, InputDataProvider.VehicleInputData);
 
 			if (Report != null) {
diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs
index b2622c961be1625999be5ed7129294c60fc45ca2..4b36932370ff9c705bbaacf9b12f4be81b0195f3 100644
--- a/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs
+++ b/VectoCore/VectoCore/InputData/Reader/Impl/EngineeringModeVectoRunDataFactory.cs
@@ -63,15 +63,19 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
 			var driver = dao.CreateDriverData(InputDataProvider.DriverInputData);
 			var engineData = dao.CreateEngineData(InputDataProvider.EngineInputData);
 
-			var vehicleInputData = InputDataProvider.VehicleInputData;
+			var tempVehicle = dao.CreateVehicleData(InputDataProvider.VehicleInputData);
 
+			var vehicleInputData = InputDataProvider.VehicleInputData;
+			var axlegearData = dao.CreateAxleGearData(InputDataProvider.AxleGearInputData);
+			var gearboxData = dao.CreateGearboxData(InputDataProvider.GearboxInputData, engineData, axlegearData.AxleGear.Ratio,
+				tempVehicle.DynamicTyreRadius);
 			var crossWindRequired = vehicleInputData.CrossWindCorrectionMode == CrossWindCorrectionMode.VAirBetaLookupTable;
 
 			return InputDataProvider.JobInputData().Cycles.Select(cycle => new VectoRunData {
 				JobName = InputDataProvider.JobInputData().JobName,
 				EngineData = engineData,
-				GearboxData = dao.CreateGearboxData(InputDataProvider.GearboxInputData, engineData),
-				AxleGearData = dao.CreateAxleGearData(InputDataProvider.AxleGearInputData),
+				GearboxData = gearboxData,
+				AxleGearData = axlegearData,
 				VehicleData = dao.CreateVehicleData(vehicleInputData),
 				DriverData = driver,
 				Aux = dao.CreateAuxiliaryData(InputDataProvider.AuxiliaryInputData()),
diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
index e073fef2fc7001b1ebcfc74d6383fb84ab04fec9..16a12d58dd5afafb00a00331e3c9d936cd71b751 100644
--- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
@@ -31,12 +31,20 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net.NetworkInformation;
+using iTextSharp.text.pdf;
+using iTextSharp.text.pdf.interfaces;
 using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Configuration;
+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.Declaration
 {
@@ -85,15 +93,15 @@ namespace TUGraz.VectoCore.Models.Declaration
 		{
 			var wheelsEntry = Wheels.Lookup(wheels.RemoveWhitespace());
 			try {
-				var rimsEntry = Rims.Lookup(rims);
+			var rimsEntry = Rims.Lookup(rims);
 
-				var correction = wheelsEntry.SizeClass != "a" ? rimsEntry.F_b : rimsEntry.F_a;
+			var correction = wheelsEntry.SizeClass != "a" ? rimsEntry.F_b : rimsEntry.F_a;
 
-				return wheelsEntry.DynamicTyreRadius * correction / (2 * Math.PI);
+			return wheelsEntry.DynamicTyreRadius * correction / (2 * Math.PI);
 			} catch (KeyNotFoundException) {
 				throw new VectoException(
 					"Calculating Dynamic Tyre Radius not possible: Declaration Lookup could not find Key '{0}' for rim.", rims);
-			}
+		}
 		}
 
 		public static Fan Fan
@@ -220,37 +228,192 @@ namespace TUGraz.VectoCore.Models.Declaration
 			public static readonly MeterPerSquareSecond StartAcceleration = 0.6.SI<MeterPerSquareSecond>();
 			public static readonly KilogramSquareMeter Inertia = 0.SI<KilogramSquareMeter>();
 
+			public static readonly MeterPerSecond TruckMaxAllowedSpeed = 85.KMPHtoMeterPerSecond();
+			public static double ShiftPolygonRPMMargin = 7;
+			private static double ShiftPolygonEngineFldMargin = 0.98;
+
 			public static readonly Second MinTimeBetweenGearshifts = 2.SI<Second>();
 
-			internal static ShiftPolygon ComputeShiftPolygon(EngineFullLoadCurve fullLoadCurve, PerSecond engineIdleSpeed)
+			/// <summary>
+			/// computes the shift polygons for a single gear according to the whitebook 2016
+			/// </summary>
+			/// <param name="gear">index of the gear to compute the shift polygons for</param>
+			/// <param name="fullLoadCurve">engine full load curve, potentially limited by the gearbox</param>
+			/// <param name="gears">list of gears</param>
+			/// <param name="engine">engine data</param>
+			/// <param name="axlegearRatio"></param>
+			/// <param name="dynamicTyreRadius"></param>
+			/// <returns></returns>
+			public static ShiftPolygon ComputeShiftPolygon(int gear, FullLoadCurve fullLoadCurve,
+				IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius)
 			{
-				var maxTorque = fullLoadCurve.MaxLoadTorque;
+				var engineSpeed85kmhLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 1], axlegearRatio, dynamicTyreRadius,
+					engine);
+				var engineSpeed85kmhSecondToLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 2], axlegearRatio,
+					dynamicTyreRadius, engine);
+
+				var maxDragTorque = engine.FullLoadCurve.MaxDragTorque * 1.1;
+
+				var p1 = new Point(engine.IdleSpeed.Value() / 2, 0);
+				var p2 = new Point(engine.IdleSpeed.Value() * 1.1, 0);
+				var p3 = new Point(engineSpeed85kmhLastGear.Value() * 0.9,
+					fullLoadCurve.FullLoadStationaryTorque(engineSpeed85kmhLastGear * 0.9).Value());
+
+				var p4 =
+					new Point((engineSpeed85kmhLastGear + (engineSpeed85kmhSecondToLastGear - engineSpeed85kmhLastGear) / 3).Value(), 0);
+				var p5 = new Point(fullLoadCurve.RatedSpeed.Value() * 0.95, fullLoadCurve.MaxTorque.Value());
+
+				var p6 = new Point(p2.X, VectoMath.Interpolate(p1, p3, p2.X));
+				var p7 = new Point(p4.X, VectoMath.Interpolate(p2, p5, p4.X));
+
+				var fldMargin = ShiftPolygonFldMargin(fullLoadCurve.FullLoadEntries, engineSpeed85kmhLastGear * 0.9);
+				var downshiftCorr = MoveDownshiftBelowFld(Edge.Create(p6, p3), fldMargin, 1.1 * fullLoadCurve.MaxTorque);
+				var downShift =
+					new[] { p2, downshiftCorr.P1, downshiftCorr.P2 }.Select(
+						point => new ShiftPolygon.ShiftPolygonEntry() {
+							AngularSpeed = point.X.SI<PerSecond>(),
+							Torque = point.Y.SI<NewtonMeter>()
+						}).ToList();
+
+				downShift[0].Torque = maxDragTorque;
+
+				var upShift = new List<ShiftPolygon.ShiftPolygonEntry>();
+				if (gear >= gears.Count - 1) {
+					return new ShiftPolygon(downShift, upShift);
+				}
+
+				var gearRatio = gears[gear].Ratio / gears[gear + 1].Ratio;
+				var rpmMarginFactor = 1 + DeclarationData.Gearbox.ShiftPolygonRPMMargin / 100.0;
+
+				var p2p = new Point(p2.X * gearRatio * rpmMarginFactor, p2.Y / gearRatio);
+				var p3p = new Point(p3.X * gearRatio * rpmMarginFactor, p3.Y / gearRatio);
+				var p6p = new Point(p6.X * gearRatio * rpmMarginFactor, p6.Y / gearRatio);
+				var edgeP6pP3p = new Edge(p6p, p3p);
+				var p3pExt = new Point((1.1 * p5.Y - edgeP6pP3p.OffsetXY) / edgeP6pP3p.SlopeXY, 1.1 * p5.Y);
+
+				upShift = IntersectShiftPolygon(new[] { p4, p7, p5 }.ToList(), new[] { p2p, p6p, p3pExt }.ToList())
+					.Select(point => new ShiftPolygon.ShiftPolygonEntry() {
+						AngularSpeed = point.X.SI<PerSecond>(),
+						Torque = point.Y.SI<NewtonMeter>()
+					}).ToList();
+				upShift[0].Torque = maxDragTorque;
+				return new ShiftPolygon(downShift, upShift);
+			}
 
-				var entriesDown = new List<ShiftPolygon.ShiftPolygonEntry>();
-				var entriesUp = new List<ShiftPolygon.ShiftPolygonEntry>();
+			/// <summary>
+			/// ensures the original downshift line is below the (already reduced) full-load curve
+			/// </summary>
+			/// <param name="shiftLine">second part of the shift polygon (slope)</param>
+			/// <param name="fldMargin">reduced full-load curve</param>
+			/// <param name="maxTorque">max torque</param>
+			/// <returns>returns a corrected shift polygon segment (slope) that is below the full load curve and reaches given maxTorque. the returned segment has the same slope</returns>
+			internal static Edge MoveDownshiftBelowFld(Edge shiftLine, IEnumerable<Point> fldMargin, NewtonMeter maxTorque)
+			{
+				var slope = shiftLine.SlopeXY;
+				var d = shiftLine.P2.Y - slope * shiftLine.P2.X;
 
-				entriesDown.Add(new ShiftPolygon.ShiftPolygonEntry {
-					AngularSpeed = engineIdleSpeed,
-					Torque = 0.SI<NewtonMeter>()
-				});
+				d = fldMargin.Select(point => point.Y - slope * point.X).Concat(new[] { d }).Min();
+				var p6Corr = new Point(shiftLine.P1.X, shiftLine.P1.X * slope + d);
+				var p3Corr = new Point((maxTorque.Value() - d) / slope, maxTorque.Value());
+				return Edge.Create(p6Corr, p3Corr);
+			}
 
-				var tq1 = maxTorque * engineIdleSpeed / (fullLoadCurve.PreferredSpeed + fullLoadCurve.LoSpeed - engineIdleSpeed);
-				entriesDown.Add(new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = engineIdleSpeed, Torque = tq1 });
+			/// <summary>
+			/// reduce the torque of the full load curve up to the given rpms
+			/// </summary>
+			/// <param name="fullLoadCurve"></param>
+			/// <param name="rpmLimit"></param>
+			/// <returns></returns>
+			internal static IEnumerable<Point> ShiftPolygonFldMargin(List<FullLoadCurve.FullLoadCurveEntry> fullLoadCurve,
+				PerSecond rpmLimit)
+			{
+				return
+					fullLoadCurve.TakeWhile(fldEntry => fldEntry.EngineSpeed < rpmLimit)
+						.Select(
+							fldEntry =>
+								new Point(fldEntry.EngineSpeed.Value(), fldEntry.TorqueFullLoad.Value() * ShiftPolygonEngineFldMargin))
+						.ToList();
+			}
 
-				var speed1 = (fullLoadCurve.PreferredSpeed + fullLoadCurve.LoSpeed) / 2;
-				entriesDown.Add(new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = speed1, Torque = maxTorque });
 
-				entriesUp.Add(new ShiftPolygon.ShiftPolygonEntry {
-					AngularSpeed = fullLoadCurve.PreferredSpeed,
-					Torque = 0.SI<NewtonMeter>()
-				});
+			internal static PerSecond ComputeEngineSpeed85kmh(ITransmissionInputData gear, double axleRatio,
+				Meter dynamicTyreRadius, CombustionEngineData engine)
+			{
+				var engineSpeed = TruckMaxAllowedSpeed / dynamicTyreRadius * axleRatio * gear.Ratio;
+				if (engineSpeed < engine.IdleSpeed) {
+					throw new VectoException("engine speed at velocity {0} in gear {1} is below engine's idle speed! {2}",
+						DeclarationData.Gearbox.TruckMaxAllowedSpeed, gear.Gear, engineSpeed);
+				}
+				if (engineSpeed > engine.FullLoadCurve.FullLoadEntries.Last().EngineSpeed) {
+					throw new VectoException("engine speed at velocity {0} in gear {1} is above engine's max speed! {2}",
+						DeclarationData.Gearbox.TruckMaxAllowedSpeed, gear.Gear, engineSpeed);
+				}
+				return engineSpeed;
+			}
 
-				tq1 = maxTorque * (fullLoadCurve.PreferredSpeed - engineIdleSpeed) / (fullLoadCurve.N95hSpeed - engineIdleSpeed);
-				entriesUp.Add(new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = fullLoadCurve.PreferredSpeed, Torque = tq1 });
 
-				entriesUp.Add(new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = fullLoadCurve.N95hSpeed, Torque = maxTorque });
+			internal static List<Point> IntersectShiftPolygon(List<Point> orig, List<Point> transformedDownshift)
+			{
+				var intersections = new List<Point>();
+				// compute all intersection points between both line segments
+				foreach (var origLine in orig.Pairwise(Edge.Create)) {
+					foreach (var transformedLine in transformedDownshift.Pairwise(Edge.Create)) {
+						var isect = VectoMath.Intersect(origLine, transformedLine);
+						if (isect != null) {
+							intersections.Add(isect);
+						}
+					}
+				}
+
+				// add all points (i.e. intersecting points and both line segments) to a single list
+				var pointSet = new List<Point>(orig);
+				pointSet.AddRange(transformedDownshift);
+				pointSet.AddRange(intersections);
+				pointSet.AddRange(ProjectPointsToLineSegments(orig, transformedDownshift));
+				pointSet.AddRange(ProjectPointsToLineSegments(transformedDownshift, orig));
+
+				// line sweeping from max_X to 0: select point with lowest Y coordinate, abort if a point has Y = 0
+				var shiftPolygon = new List<Point>();
+				foreach (var xCoord in pointSet.Select(pt => pt.X).Distinct().OrderBy(x => x).Reverse()) {
+					var coord = xCoord;
+					var xPoints = pointSet.Where(pt => pt.X.IsEqual(coord) && !pt.Y.IsEqual(0)).ToList();
+					shiftPolygon.Add(xPoints.MinBy(pt => pt.Y));
+					var tmp = pointSet.Where(pt => pt.X.IsEqual(coord)).Where(pt => pt.Y.IsEqual(0)).ToList();
+					if (!tmp.Any()) {
+						continue;
+					}
+					shiftPolygon.Add(tmp.First());
+					break;
+				}
+
+				// find and remove colinear points
+				var toRemove = new List<Point>();
+				for (var i = 0; i < shiftPolygon.Count - 2; i++) {
+					var edge = new Edge(shiftPolygon[i], shiftPolygon[i + 2]);
+					if (edge.ContainsXY(shiftPolygon[i + 1])) {
+						toRemove.Add(shiftPolygon[i + 1]);
+					}
+				}
+				foreach (var point in toRemove) {
+					shiftPolygon.Remove(point);
+				}
+
+				// order points first by x coordinate and the by Y coordinate ASC
+				return shiftPolygon.OrderBy(pt => pt.X).ThenBy(pt => pt.Y).ToList();
+			}
 
-				return new ShiftPolygon(entriesDown, entriesUp);
+			private static List<Point> ProjectPointsToLineSegments(List<Point> lineSegments, List<Point> points)
+			{
+				var pointSet = new List<Point>();
+				foreach (var segment in lineSegments.Pairwise(Edge.Create)) {
+					if (segment.P1.X.IsEqual(segment.P2.X)) {
+						continue;
+					}
+					var k = segment.SlopeXY;
+					var d = segment.P1.Y - segment.P1.X * k;
+					pointSet.AddRange(points.Select(point => new Point(point.X, point.X * k + d)));
+				}
+				return pointSet;
 			}
 		}
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/FullLoadCurve.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/FullLoadCurve.cs
index f8bb5f00aa223a0f8ab46de33f54627a22d863bc..9f6da3d51ec566fd7740fce368dec21529c0bb5c 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/FullLoadCurve.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/FullLoadCurve.cs
@@ -54,6 +54,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 		private SortedList<PerSecond, int> _quickLookup;
 
 		[Required] internal LookupData<PerSecond, Second> PT1Data;
+		private NewtonMeter _maxTorque;
 
 		/// <summary>
 		/// Get the rated speed from the given full-load curve (i.e. speed with max. power)
@@ -73,6 +74,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 			get { return _maxPower ?? ComputeRatedSpeed().Item2; }
 		}
 
+		public NewtonMeter MaxTorque
+		{
+			get { return _maxTorque ?? FindMaxTorque(); }
+		}
+
+		private NewtonMeter FindMaxTorque()
+		{
+			_maxTorque = FullLoadEntries.Max(x => x.TorqueFullLoad);
+			return _maxTorque;
+		}
+
 		public static FullLoadCurve ReadFromFile(string fileName, bool declarationMode = false, bool engineFld = false)
 		{
 			try {
diff --git a/VectoCore/VectoCore/Utils/VectoMath.cs b/VectoCore/VectoCore/Utils/VectoMath.cs
index 3ccd9824eb6168a587134d621a9849959db56b0e..bbc4d81e07f56391e47ec40de78538748a582ec0 100644
--- a/VectoCore/VectoCore/Utils/VectoMath.cs
+++ b/VectoCore/VectoCore/Utils/VectoMath.cs
@@ -80,6 +80,10 @@ namespace TUGraz.VectoCore.Utils
 			return ((xint - x1) * (y2 - y1) / (x2 - x1) + y1);
 		}
 
+		public static double Interpolate(Point p1, Point p2, double x)
+		{
+			return Interpolate(p1.X, p2.X, p1.Y, p2.Y, x);
+		}
 
 		/// <summary>
 		/// Returns the absolute value.
@@ -152,6 +156,36 @@ namespace TUGraz.VectoCore.Utils
 			}
 			return retVal;
 		}
+
+		public static Point Intersect(Edge line1, Edge line2)
+		{
+			var s10X = line1.P2.X - line1.P1.X;
+			var s10Y = line1.P2.Y - line1.P1.Y;
+			var s32X = line2.P2.X - line2.P1.X;
+			var s32Y = line2.P2.Y - line2.P1.Y;
+
+			var denom = s10X * s32Y - s32X * s10Y;
+			if (denom.IsEqual(0)) {
+				return null;
+			}
+
+			var s02X = line1.P1.X - line2.P1.X;
+			var s02Y = line1.P1.Y - line2.P1.Y;
+			var sNumer = s10X * s02Y - s10Y * s02X;
+			if ((sNumer < 0) == (denom > 0)) {
+				return null;
+			}
+			var tNumer = s32X * s02Y - s32Y * s02X;
+			if ((tNumer < 0) == (denom > 0)) {
+				return null;
+			}
+			if (((sNumer > denom) == (denom > 0)) || ((tNumer > denom) == (denom > 0))) {
+				return null;
+			}
+			var t = tNumer / denom;
+
+			return new Point(line1.P1.X + (t * s10X), line1.P1.Y + t * s10Y);
+		}
 	}
 
 	[DebuggerDisplay("(X:{X}, Y:{Y}, Z:{Z})")]
@@ -440,6 +474,16 @@ namespace TUGraz.VectoCore.Utils
 			get { return _vector ?? (_vector = P2 - P1); }
 		}
 
+		public double SlopeXY
+		{
+			get { return Vector.Y / Vector.X; }
+		}
+
+		public double OffsetXY
+		{
+			get { return P2.Y - SlopeXY * P2.X; }
+		}
+
 		#region Equality members
 
 		protected bool Equals(Edge other)
@@ -464,5 +508,15 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		#endregion
+
+		public static Edge Create(Point arg1, Point arg2)
+		{
+			return new Edge(arg1, arg2);
+		}
+
+		public bool ContainsXY(Point point)
+		{
+			return (SlopeXY * point.X + (P1.Y - SlopeXY * P1.X) - point.Y).IsEqual(0, 1E-9);
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs b/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs
index a5dfdb0aed79f314cb680128f8c4ff955069e0f9..cc1bfcc0171f556fa0b5aafd7cee394528331820 100644
--- a/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs
+++ b/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs
@@ -97,8 +97,8 @@ namespace TUGraz.VectoCore.Tests.FileIO
 
 			Assert.AreEqual(3.7890, runData.EngineData.Inertia.Value());
 
-			var downshiftSpeeds = new[] { 600, 600, 1310.6673 };
-			var downshiftTorque = new[] { 0, 266.85346, 899 };
+			var downshiftSpeeds = new[] { 660, 660, 1681.4261 };
+			var downshiftTorque = new[] { -163.9, 257.7076, 988.9 };
 
 			Assert.AreEqual(downshiftSpeeds.Length, runData.GearboxData.Gears[1].ShiftPolygon.Downshift.Count);
 			for (var i = 0; i < downshiftSpeeds.Length; i++) {
@@ -107,8 +107,8 @@ namespace TUGraz.VectoCore.Tests.FileIO
 				Assert.AreEqual(downshiftTorque[i], runData.GearboxData.Gears[1].ShiftPolygon.Downshift[i].Torque.Value(), Tolerance);
 			}
 
-			var upshiftSpeed = new[] { 1531.230044, 1531.230044, 2420.505793661 };
-			var upshiftTorque = new[] { 0, 459.8588, 899 };
+			var upshiftSpeed = new[] { 1891.2419, 1891.2419, 5798.4116 };
+			var upshiftTorque = new[] { -163.9, 245.3663, 988.9 };
 
 			Assert.AreEqual(upshiftSpeed.Length, runData.GearboxData.Gears[1].ShiftPolygon.Downshift.Count);
 			for (var i = 0; i < downshiftSpeeds.Length; i++) {
diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b2b11f045089920b6b1b7e837b2f42a7160d6cfe
--- /dev/null
+++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
@@ -0,0 +1,364 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NUnit.Framework;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData.FileIO.JSON;
+using TUGraz.VectoCore.InputData.Reader.DataObjectAdaper;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Utils;
+using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
+using Point = TUGraz.VectoCore.Utils.Point;
+
+namespace TUGraz.VectoCore.Tests.Models.Declaration
+{
+	[TestClass]
+	public class ShiftPolygonTest
+	{
+		[TestMethod]
+		public void IntersectShiftLines1()
+		{
+			var upShift = new[] {
+				new Point(10, 0),
+				new Point(10, 10),
+				new Point(20, 20),
+			};
+
+			var transformed = new[] {
+				new Point(8, 0),
+				new Point(8, 8),
+				new Point(18, 22)
+			};
+
+			var expected = new[] {
+				new Point(10, 0),
+				new Point(10, 10),
+				new Point(20, 20),
+			};
+
+			var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift.ToList(), transformed.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
+			}
+		}
+
+		[TestMethod]
+		public void IntersectShiftLines2()
+		{
+			var upShift = new[] {
+				new Point(10, 0),
+				new Point(10, 10),
+				new Point(20, 20),
+			};
+
+			var transformed = new[] {
+				new Point(8, 0),
+				new Point(8, 6),
+				new Point(18, 14)
+			};
+
+			var expected = new[] {
+				new Point(10, 0),
+				new Point(10, 7.6),
+				new Point(20, 15.6),
+			};
+
+			var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift.ToList(), transformed.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
+			}
+
+			result = DeclarationData.Gearbox.IntersectShiftPolygon(transformed.ToList(), upShift.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
+			}
+		}
+
+
+		[TestMethod]
+		public void IntersectShiftLines3()
+		{
+			var upShift = new[] {
+				new Point(10, 0),
+				new Point(10, 10),
+				new Point(20, 20),
+			};
+
+			var transformed = new[] {
+				new Point(8, 0),
+				new Point(8, 4),
+				new Point(18, 22)
+			};
+
+			var expected = new[] {
+				new Point(10, 0),
+				new Point(10, 7.6),
+				new Point(13, 13),
+				new Point(20, 20),
+			};
+
+			var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift.ToList(), transformed.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
+			}
+
+			result = DeclarationData.Gearbox.IntersectShiftPolygon(transformed.ToList(), upShift.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y);
+			}
+		}
+
+		[TestMethod]
+		public void IntersectShiftLines4()
+		{
+			var upShift = new[] {
+				new Point(10, 0),
+				new Point(10, 10),
+				new Point(20, 20),
+			};
+
+			var transformed = new[] {
+				new Point(8, 0),
+				new Point(8, 12),
+				new Point(18, 16)
+			};
+
+			var expected = new[] {
+				new Point(10, 0),
+				new Point(10, 10),
+				new Point(14.6666, 14.6666),
+				new Point(20, 16.8),
+			};
+
+			var result = DeclarationData.Gearbox.IntersectShiftPolygon(upShift.ToList(), transformed.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
+			}
+
+			result = DeclarationData.Gearbox.IntersectShiftPolygon(transformed.ToList(), upShift.ToList());
+
+			Assert.AreEqual(expected.Length, result.Count);
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
+			}
+		}
+
+		[TestMethod]
+		public void ShiftPolygonFldMarginTest()
+		{
+			var engineFld = new[] {
+				new Point(8, 10),
+				new Point(9, 11),
+				new Point(10, 11.5),
+				new Point(11, 12),
+				new Point(12, 12.5),
+				new Point(13, 13),
+				new Point(14, 13.5),
+				new Point(15, 14),
+				new Point(16, 14.5),
+				new Point(17, 15),
+				new Point(18, 16.5),
+				new Point(19, 18),
+				new Point(20, 19.5),
+				new Point(21, 21),
+				new Point(22, 22.5),
+			};
+
+			var expected = new[] {
+				new Point(8, 9.8),
+				new Point(9, 10.78),
+				new Point(10, 11.27),
+				new Point(11, 11.76),
+				new Point(12, 12.25),
+				new Point(13, 12.74),
+				new Point(14, 13.23),
+				new Point(15, 13.72),
+				new Point(16, 14.21),
+				new Point(17, 14.7),
+				new Point(18, 16.17),
+				new Point(19, 17.64),
+				new Point(20, 19.11),
+				new Point(21, 20.58),
+				new Point(22, 22.05),
+			};
+
+			var result =
+				DeclarationData.Gearbox.ShiftPolygonFldMargin(
+					engineFld.Select(
+						p =>
+							new FullLoadCurve.FullLoadCurveEntry() {
+								EngineSpeed = p.X.SI<PerSecond>(),
+								TorqueFullLoad = p.Y.SI<NewtonMeter>()
+							}).ToList(),
+					23.SI<PerSecond>());
+
+			foreach (var tuple in expected.Zip(result, Tuple.Create)) {
+				Assert.AreEqual(tuple.Item1.X, tuple.Item2.X, 1e-3);
+				Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Y, 1e-3);
+			}
+		}
+
+		[TestMethod]
+		public void CorrectDownShiftByEngineFldTest()
+		{
+			var downshift = Edge.Create(new Point(10, 10), new Point(22, 20));
+			var engineFldCorr = new[] {
+				new Point(8, 9.8),
+				new Point(9, 10.78),
+				new Point(10, 11.27),
+				new Point(11, 11.76),
+				new Point(12, 12.25),
+				new Point(13, 12.74),
+				new Point(14, 13.23),
+				new Point(15, 13.72),
+				new Point(16, 14.21),
+				new Point(17, 14.7),
+				new Point(18, 16.17),
+				new Point(19, 17.64),
+				new Point(20, 19.11),
+				new Point(21, 20.58),
+				new Point(22, 22.05),
+			};
+
+			var corrected = DeclarationData.Gearbox.MoveDownshiftBelowFld(downshift, engineFldCorr, 20.SI<NewtonMeter>());
+
+			Assert.AreEqual(10, corrected.P1.X, 1e-3);
+			Assert.AreEqual(8.86666, corrected.P1.Y, 1e-3);
+			Assert.AreEqual(23.36, corrected.P2.X, 1e-3);
+			Assert.AreEqual(20, corrected.P2.Y, 1e-3);
+		}
+
+		[TestMethod]
+		public void CompueShiftPolygonDeclarationTest()
+		{
+			var engineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
+			var gearboxFile = @"TestData\Components\40t_Long_Haul_Truck.vgbx";
+
+			var rdyn = 0.4882675.SI<Meter>();
+			var axlegearRatio = 2.59;
+
+			var expectedDownshift = new[] {
+				// Gear 1
+				new[] {
+					new Point(64.50736915, -352),
+					new Point(64.50736915, 970.37),
+					new Point(121.059, 2530),
+				},
+				// Gear 2
+				new[] {
+					new Point(64.50736915, -352),
+					new Point(64.50736915, 970.37),
+					new Point(121.059, 2530),
+				},
+				// Gear 3
+				new[] {
+					new Point(64.50736915, -352),
+					new Point(64.50736915, 970.37),
+					new Point(121.059, 2530),
+				},
+			};
+			var expectedUpshift = new[] {
+				// Gear 1
+				new[] {
+					new Point(136.9338946, -352),
+					new Point(136.9338946, 1492.7289),
+					new Point(203.9530637, 2530),
+				},
+				// Gear 2
+				new[] {
+					new Point(136.9338946, -352),
+					new Point(136.9338946, 1518.81917),
+					new Point(201.3375424, 2530),
+				},
+				// Gear 3
+				new[] {
+					new Point(136.9338946, -352),
+					new Point(136.9338946, 1538.9278),
+					new Point(153.606666, 1893.19273),
+					new Point(192.102071, 2530),
+				},
+			};
+
+			var dao = new DeclarationDataAdapter();
+			var engineData = dao.CreateEngineData(new JSONEngineDataV3(JSONInputDataFactory.ReadFile(engineFile), engineFile));
+
+			var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
+
+			var shiftPolygons = new List<ShiftPolygon>();
+			for (var i = 1; i <= gearboxData.Gears.Count; i++) {
+				shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(i, engineData.FullLoadCurve, gearboxData.Gears,
+					engineData, axlegearRatio, rdyn));
+			}
+
+			for (var i = 0; i < Math.Min(gearboxData.Gears.Count, expectedDownshift.Length); i++) {
+				foreach (var tuple in expectedDownshift[i].Zip(shiftPolygons[i].Downshift, Tuple.Create)) {
+					Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.Value(), 1e-3, "gear: {0} entry: {1}", i, tuple);
+					Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				}
+
+				foreach (var tuple in expectedUpshift[i].Zip(shiftPolygons[i].Upshift, Tuple.Create)) {
+					Assert.AreEqual(tuple.Item1.X, tuple.Item2.AngularSpeed.Value(), 1e-3, "gear: {0} entry: {1}", i, tuple);
+					Assert.AreEqual(tuple.Item1.Y, tuple.Item2.Torque.Value(), 1e-3, "gear: {0} entry: {1}", i + 1, tuple);
+				}
+			}
+
+			Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
+		}
+
+
+		//[TestMethod]
+		//public void CompueShiftPolygonDeclarationTestConfidentialEngine()
+		//{
+		//	var engineFldFile = @"E:\QUAM\Downloads\EngineFLD\Map_375c_BB1390_modTUG_R49_375c_BB1386.vfld";
+		//	var gearboxFile = @"TestData\Components\40t_Long_Haul_Truck.vgbx";
+
+		//	var rdyn = 0.4882675.SI<Meter>();
+		//	var axlegearRatio = 2.59;
+
+		//	var engineData = new CombustionEngineData() {
+		//		IdleSpeed = 509.RPMtoRad(),
+		//		FullLoadCurve = EngineFullLoadCurve.ReadFromFile(engineFldFile, true)
+		//	};
+
+		//	var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
+
+		//	var shiftPolygons = new List<ShiftPolygon>();
+		//	for (var i = 1; i <= gearboxData.Gears.Count; i++) {
+		//		shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(i, engineData.FullLoadCurve, gearboxData.Gears,
+		//			engineData, axlegearRatio, rdyn));
+		//	}
+		//}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs
index 5930ef72723e1e341f93f9a6ad85d59faf2936cd..42fe90b4a5a97a2994fd4f82897549055b802e11 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs
@@ -72,26 +72,32 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 
 			// -- shiftpolygon downshift 
 
-			Assert.AreEqual(600.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[0].AngularSpeed.Value(), 0.0001);
-			Assert.AreEqual(0.0, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[0].Torque.Value(), 0.0001);
+			Assert.AreEqual(660.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[0].AngularSpeed.Value(),
+				0.0001);
+			Assert.AreEqual(-163.9, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[0].Torque.Value(), 0.0001);
 
-			Assert.AreEqual(600.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[1].AngularSpeed.Value(), 0.0001);
-			Assert.AreEqual(266.8277, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[1].Torque.Value(), 0.1);
+			Assert.AreEqual(660.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[1].AngularSpeed.Value(),
+				0.0001);
+			Assert.AreEqual(257.7076, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[1].Torque.Value(), 0.1);
 
-			Assert.AreEqual(1310.7646.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[2].AngularSpeed.Value(),
+			Assert.AreEqual(1681.4261.RPMtoRad().Value(),
+				gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[2].AngularSpeed.Value(),
 				0.1);
-			Assert.AreEqual(899, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[2].Torque.Value(), 0.0001);
+			Assert.AreEqual(988.9, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[2].Torque.Value(), 0.0001);
 
 			// -- shiftpolygon upshift
 
-			Assert.AreEqual(1531.5293.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[0].AngularSpeed.Value(), 0.1);
-			Assert.AreEqual(0, gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[0].Torque.Value(), 0.0001);
+			Assert.AreEqual(1891.2419.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[0].AngularSpeed.Value(),
+				0.1);
+			Assert.AreEqual(-163.9, gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[0].Torque.Value(), 0.0001);
 
-			Assert.AreEqual(1531.5293.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[1].AngularSpeed.Value(), 0.1);
-			Assert.AreEqual(459.881, gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[1].Torque.Value(), 0.1);
+			Assert.AreEqual(1891.2419.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[1].AngularSpeed.Value(),
+				0.1);
+			Assert.AreEqual(245.3663, gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[1].Torque.Value(), 0.1);
 
-			Assert.AreEqual(2421.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[2].AngularSpeed.Value(), 0.1);
-			Assert.AreEqual(899, gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[2].Torque.Value(), 0.1);
+			Assert.AreEqual(5798.4116.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[2].AngularSpeed.Value(),
+				0.1);
+			Assert.AreEqual(988.9, gearbox.ModelData.Gears[1].ShiftPolygon.Upshift[2].Torque.Value(), 0.1);
 		}
 
 		[TestMethod]
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs
index c48049ab9734e28eca4ca8b015b2f3d2a821f986..477e6c8ac941d13f8a2d826130fc5e1907eb4eab 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/GearboxDataTest.cs
@@ -84,8 +84,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 			var rdyn = double.Parse(TestContext.DataRow["rDyn"].ToString(), CultureInfo.InvariantCulture);
 			var speed = double.Parse(TestContext.DataRow["v"].ToString(), CultureInfo.InvariantCulture);
 
-			var gbxData = MockSimulationDataFactory.CreateGearboxDataFromFile(TestContext.DataRow["GearboxDataFile"].ToString(),
-				EngineFile);
+			//var gbxData = MockSimulationDataFactory.CreateGearboxDataFromFile(TestContext.DataRow["GearboxDataFile"].ToString(),
+			//	EngineFile);
 			var axleData = MockSimulationDataFactory.CreateAxleGearDataFromFile(TestContext.DataRow["GearboxDataFile"].ToString());
 
 			var PvD = double.Parse(TestContext.DataRow["PowerGbxOut"].ToString(), CultureInfo.InvariantCulture).SI<Watt>();
diff --git a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs
index f2e0d827a4f7c5dadb2d1bda7e13a60d4989726b..47c428891ece523217ad92f8cf479683e30c5263 100644
--- a/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockSimulationDataFactory.cs
@@ -31,6 +31,8 @@
 
 using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData;
 using TUGraz.VectoCore.InputData.FileIO.JSON;
 using TUGraz.VectoCore.InputData.Reader.DataObjectAdaper;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
@@ -53,11 +55,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 			if (declarationMode) {
 				var dao = new DeclarationDataAdapter();
 				var engineData = dao.CreateEngineData(engineInput);
-				return dao.CreateGearboxData(gearboxInput, engineData);
+				return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>());
 			} else {
 				var dao = new EngineeringDataAdapter();
 				var engineData = dao.CreateEngineData(engineInput);
-				return dao.CreateGearboxData(gearboxInput, engineData);
+				return dao.CreateGearboxData(gearboxInput, engineData, ((IAxleGearInputData)gearboxInput).Ratio, 0.5.SI<Meter>());
 			}
 		}
 
diff --git a/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs b/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs
index d8e807af609200decbe6e9e0165430f47ab8ad1f..47bd08708ebb665b61597486eb16b07c22ef1fc7 100644
--- a/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs
+++ b/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs
@@ -29,16 +29,19 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
+using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NUnit.Framework;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Utils;
+using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
 
 namespace TUGraz.VectoCore.Tests.Utils
 {
-	[TestClass]
+	[TestFixture]
 	public class VectoMathTest
 	{
-		[TestMethod]
+		[Test]
 		public void VectoMath_Min()
 		{
 			var smaller = 0.SI();
@@ -66,5 +69,26 @@ namespace TUGraz.VectoCore.Tests.Utils
 			Assert.AreEqual(positiveWatt, VectoMath.Abs(negativeWatt));
 			Assert.AreEqual(positiveWatt, VectoMath.Abs(positiveWatt));
 		}
+
+
+		[TestCase(0, -1, 0, 1, -1, 0, 1, 0, 0, 0),
+		TestCase(0, 0, 10, 0, 0, 5, 10, 5, double.NaN, double.NaN),
+		TestCase(0, 0, 0, 10, 5, 0, 10, 5, double.NaN, double.NaN),
+		TestCase(0, 0, 1, 1, 1, 0, 0, 1, 0.5, 0.5)]
+		public void IntersectionTest(double p0x, double p0y, double p1x, double p1y, double p2x, double p2y, double p3x,
+			double p3y, double isx, double isy)
+		{
+			var line1 = new Edge(new Point(p0x, p0y), new Point(p1x, p1y));
+			var line2 = new Edge(new Point(p2x, p2y), new Point(p3x, p3y));
+
+			var intersect = VectoMath.Intersect(line1, line2);
+			if (intersect != null) {
+				Assert.AreEqual(isx, intersect.X);
+				Assert.AreEqual(isy, intersect.Y);
+			} else {
+				Assert.IsTrue(double.IsNaN(isx));
+				Assert.IsTrue(double.IsNaN(isy));
+			}
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj
index 3212cf7ce1b8db3c6e42d27403413dfbc20aeb4d..f9fa26838d2bbc5553d63818712cfe9a96d24797 100644
--- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj
+++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj
@@ -90,6 +90,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Integration\DeclarationReportTest.cs" />
+    <Compile Include="Models\Declaration\ShiftPolygonTest.cs" />
     <Compile Include="Models\SimulationComponentData\ValidationTest.cs" />
     <Compile Include="Models\Simulation\FactoryTest.cs" />
     <Compile Include="Models\Simulation\LossMapRangeValidationTest.cs" />