diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
index 16a12d58dd5afafb00a00331e3c9d936cd71b751..2efb9f45380f1eb28697a6bd70f8e158f7899b62 100644
--- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
@@ -249,34 +249,41 @@ namespace TUGraz.VectoCore.Models.Declaration
 			{
 				var engineSpeed85kmhLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 1], axlegearRatio, dynamicTyreRadius,
 					engine);
-				var engineSpeed85kmhSecondToLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 2], axlegearRatio,
-					dynamicTyreRadius, engine);
+				//var engineSpeed85kmhSecondToLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 2], axlegearRatio,
+				//	dynamicTyreRadius, engine);
+
+				var nVHigh = VectoMath.Min(engineSpeed85kmhLastGear, engine.FullLoadCurve.RatedSpeed);
+
+				var diffRatio = gears[gears.Count - 2].Ratio / gears[gears.Count - 1].Ratio - 1;
 
 				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 p3 = new Point(nVHigh.Value() * 0.9,
+					engine.FullLoadCurve.FullLoadStationaryTorque(nVHigh * 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());
+					new Point((nVHigh * (1 + diffRatio / 3)).Value(), 0);
+				var p5 = new Point(engine.FullLoadCurve.N95hSpeed.Value(), engine.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 fldMargin = ShiftPolygonFldMargin(fullLoadCurve.FullLoadEntries, nVHigh * 0.95);
 				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 downShift = new List<ShiftPolygon.ShiftPolygonEntry>();
+				if (gear > 0) {
+					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);
@@ -340,14 +347,14 @@ namespace TUGraz.VectoCore.Models.Declaration
 				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);
-				}
+				//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;
 			}
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
index 208bd8d08d7486cfb483e4391377b41fc7a334d1..6f5c4a992eb0880344ae41e846bd4c63a4f06a9f 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
@@ -32,6 +32,7 @@
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.ComponentModel.DataAnnotations;
 using System.Data;
 using System.Diagnostics;
 using System.Linq;
@@ -41,6 +42,7 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 {
+	[CustomValidation(typeof(ShiftPolygon), "ValidateShiftPolygon")]
 	public class ShiftPolygon : SimulationComponentData
 	{
 		private readonly List<ShiftPolygonEntry> _upShiftPolygon;
@@ -99,6 +101,46 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 			get { return _downShiftPolygon.AsReadOnly(); }
 		}
 
+		/// <summary>
+		/// Tests if current power request is on the left side of the shiftpolygon segment
+		/// </summary>
+		/// <param name="angularSpeed">The angular speed.</param>
+		/// <param name="torque">The torque.</param>
+		/// <param name="segment">Edge of the shift polygon</param>
+		/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
+		/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
+		/// if the z-component is positive (which means that X was on the right side of from--to).</remarks>
+		public static bool IsLeftOf(PerSecond angularSpeed, NewtonMeter torque,
+			Tuple<ShiftPolygonEntry, ShiftPolygonEntry> segment)
+		{
+			var abX = segment.Item2.AngularSpeed - segment.Item1.AngularSpeed;
+			var abY = segment.Item2.Torque - segment.Item1.Torque;
+			var acX = angularSpeed - segment.Item1.AngularSpeed;
+			var acY = torque - segment.Item1.Torque;
+			var z = abX * acY - abY * acX;
+			return z.IsGreater(0);
+		}
+
+		/// <summary>
+		/// Tests if current power request is on the left side of the shiftpolygon segment
+		/// </summary>
+		/// <param name="angularSpeed">The angular speed.</param>
+		/// <param name="torque">The torque.</param>
+		/// <param name="segment">Edge of the shift polygon</param>
+		/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
+		/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
+		/// if the z-component is negative (which means that X was on the left side of from--to).</remarks>
+		public static bool IsRightOf(PerSecond angularSpeed, NewtonMeter torque,
+			Tuple<ShiftPolygonEntry, ShiftPolygonEntry> segment)
+		{
+			var abX = segment.Item2.AngularSpeed - segment.Item1.AngularSpeed;
+			var abY = segment.Item2.Torque - segment.Item1.Torque;
+			var acX = angularSpeed - segment.Item1.AngularSpeed;
+			var acY = torque - segment.Item1.Torque;
+			var z = abX * acY - abY * acX;
+			return z.IsSmaller(0);
+		}
+
 		private static bool HeaderIsValid(DataColumnCollection columns)
 		{
 			return columns.Contains(Fields.Torque) && columns.Contains(Fields.AngularSpeedUp) &&
@@ -124,6 +166,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 					}).ToList();
 		}
 
+		public static ValidationResult ValidateShiftPolygon(ShiftPolygon shiftPolygon, ValidationContext validationContext)
+		{
+			return shiftPolygon.Downshift.Pairwise(Tuple.Create)
+				.Any(
+					downshiftLine =>
+						shiftPolygon.Upshift.Any(upshiftEntry => IsLeftOf(upshiftEntry.AngularSpeed, upshiftEntry.Torque, downshiftLine)))
+				? new ValidationResult("upshift line has to be right of the downshift line!")
+				: ValidationResult.Success;
+		}
+
 		private static class Fields
 		{
 			/// <summary>
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
index f2b5c560ea989f896caaf838112a945f1162b7dd..38b620258c82fee359428a5daf1c1e52fd4b1432 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ShiftStrategy.cs
@@ -83,7 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				return false;
 			}
 
-			return IsLeftOf(inEngineSpeed, inTorque, downSection.Item1, downSection.Item2);
+			return ShiftPolygon.IsLeftOf(inEngineSpeed, inTorque, downSection);
 		}
 
 		/// <summary>
@@ -105,49 +105,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				return true;
 			}
 
-			return IsRightOf(inEngineSpeed, inTorque, upSection.Item1, upSection.Item2);
-		}
-
-		/// <summary>
-		/// Tests if current power request is on the left side of the shiftpolygon segment
-		/// </summary>
-		/// <param name="angularSpeed">The angular speed.</param>
-		/// <param name="torque">The torque.</param>
-		/// <param name="from">From.</param>
-		/// <param name="to">To.</param>
-		/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
-		/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
-		/// if the z-component is positive (which means that X was on the right side of from--to).</remarks>
-		private static bool IsLeftOf(PerSecond angularSpeed, NewtonMeter torque, ShiftPolygon.ShiftPolygonEntry from,
-			ShiftPolygon.ShiftPolygonEntry to)
-		{
-			var abX = to.AngularSpeed - from.AngularSpeed;
-			var abY = to.Torque - from.Torque;
-			var acX = angularSpeed - from.AngularSpeed;
-			var acY = torque - from.Torque;
-			var z = abX * acY - abY * acX;
-			return z.IsGreater(0);
-		}
-
-		/// <summary>
-		/// Tests if current power request is on the left side of the shiftpolygon segment
-		/// </summary>
-		/// <param name="angularSpeed">The angular speed.</param>
-		/// <param name="torque">The torque.</param>
-		/// <param name="from">From.</param>
-		/// <param name="to">To.</param>
-		/// <returns><c>true</c> if current power request is on the left side of the shiftpolygon segment; otherwise, <c>false</c>.</returns>
-		/// <remarks>Computes a simplified cross product for the vectors: from--X, from--to and checks
-		/// if the z-component is negative (which means that X was on the left side of from--to).</remarks>
-		private static bool IsRightOf(PerSecond angularSpeed, NewtonMeter torque, ShiftPolygon.ShiftPolygonEntry from,
-			ShiftPolygon.ShiftPolygonEntry to)
-		{
-			var abX = to.AngularSpeed - from.AngularSpeed;
-			var abY = to.Torque - from.Torque;
-			var acX = angularSpeed - from.AngularSpeed;
-			var acY = torque - from.Torque;
-			var z = abX * acY - abY * acX;
-			return z.IsSmaller(0);
+			return ShiftPolygon.IsRightOf(inEngineSpeed, inTorque, upSection);
 		}
 	}
 
diff --git a/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs b/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs
index cc1bfcc0171f556fa0b5aafd7cee394528331820..db54ae5c58a48362a81a28db121a5b6f1b2118ec 100644
--- a/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs
+++ b/VectoCore/VectoCoreTest/FileIO/SimulationDataReaderTest.cs
@@ -97,20 +97,20 @@ namespace TUGraz.VectoCore.Tests.FileIO
 
 			Assert.AreEqual(3.7890, runData.EngineData.Inertia.Value());
 
-			var downshiftSpeeds = new[] { 660, 660, 1681.4261 };
-			var downshiftTorque = new[] { -163.9, 257.7076, 988.9 };
+			var downshiftSpeeds = new[] { 660, 660, 1750.70139 };
+			var downshiftTorque = new[] { -163.9, 208.116856, 988.9 };
 
-			Assert.AreEqual(downshiftSpeeds.Length, runData.GearboxData.Gears[1].ShiftPolygon.Downshift.Count);
+			Assert.AreEqual(downshiftSpeeds.Length, runData.GearboxData.Gears[2].ShiftPolygon.Downshift.Count);
 			for (var i = 0; i < downshiftSpeeds.Length; i++) {
 				Assert.AreEqual(downshiftSpeeds[i].RPMtoRad().Value(),
-					runData.GearboxData.Gears[1].ShiftPolygon.Downshift[i].AngularSpeed.Value(), Tolerance);
-				Assert.AreEqual(downshiftTorque[i], runData.GearboxData.Gears[1].ShiftPolygon.Downshift[i].Torque.Value(), Tolerance);
+					runData.GearboxData.Gears[2].ShiftPolygon.Downshift[i].AngularSpeed.Value(), Tolerance);
+				Assert.AreEqual(downshiftTorque[i], runData.GearboxData.Gears[2].ShiftPolygon.Downshift[i].Torque.Value(), Tolerance);
 			}
 
 			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);
+			Assert.AreEqual(upshiftSpeed.Length, runData.GearboxData.Gears[2].ShiftPolygon.Downshift.Count);
 			for (var i = 0; i < downshiftSpeeds.Length; i++) {
 				Assert.AreEqual(upshiftSpeed[i].RPMtoRad().Value(),
 					runData.GearboxData.Gears[1].ShiftPolygon.Upshift[i].AngularSpeed.Value(), Tolerance);
diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
index b2b11f045089920b6b1b7e837b2f42a7160d6cfe..8665e626c28e1a996df5b816f18811e4068c759b 100644
--- a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
@@ -2,9 +2,11 @@
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Drawing;
+using System.IO;
 using System.Linq;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using NUnit.Framework;
+using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.InputData.FileIO.JSON;
 using TUGraz.VectoCore.InputData.Reader.DataObjectAdaper;
@@ -12,6 +14,7 @@ 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.Tests.Utils;
 using TUGraz.VectoCore.Utils;
 using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
 using Point = TUGraz.VectoCore.Utils.Point;
@@ -293,21 +296,21 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 				// Gear 1
 				new[] {
 					new Point(136.9338946, -352),
-					new Point(136.9338946, 1492.7289),
-					new Point(203.9530637, 2530),
+					new Point(136.9338946, 1281.30911),
+					new Point(201.7326, 2427.6748),
 				},
 				// Gear 2
 				new[] {
 					new Point(136.9338946, -352),
-					new Point(136.9338946, 1518.81917),
-					new Point(201.3375424, 2530),
+					new Point(136.9338946, 1281.30911),
+					new Point(203.9530, 2466.9558),
 				},
 				// 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),
+					new Point(136.9338946, 1281.30911),
+					//new Point(153.606666, 1893.19273),
+					new Point(201.3375, 2420.6842),
 				},
 			};
 
@@ -317,7 +320,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
 
 			var shiftPolygons = new List<ShiftPolygon>();
-			for (var i = 1; i <= gearboxData.Gears.Count; i++) {
+			for (var i = 0; i < gearboxData.Gears.Count; i++) {
 				shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(i, engineData.FullLoadCurve, gearboxData.Gears,
 					engineData, axlegearRatio, rdyn));
 			}
@@ -338,27 +341,151 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 		}
 
 
-		//[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";
+		[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)
+			};
+			engineData.FullLoadCurve.EngineData = engineData;
+
+			var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
 
-		//	var rdyn = 0.4882675.SI<Meter>();
-		//	var axlegearRatio = 2.59;
+			var shiftPolygons = new List<ShiftPolygon>();
+			var downshiftTransformed = new List<List<Point>>();
+			var upshiftOrig = new List<List<Point>>();
+			for (var i = 0; i < gearboxData.Gears.Count; i++) {
+				shiftPolygons.Add(DeclarationData.Gearbox.ComputeShiftPolygon(i, engineData.FullLoadCurve, gearboxData.Gears,
+					engineData, axlegearRatio, rdyn));
+				List<Point> tmp1, tmp2;
+				ShiftPolygonComparison.ComputShiftPolygonPoints(i, engineData.FullLoadCurve, gearboxData.Gears,
+					engineData, axlegearRatio, rdyn, out tmp1, out tmp2);
+				upshiftOrig.Add(tmp1);
+				downshiftTransformed.Add(tmp2);
+			}
+
+			ShiftPolygonDrawer.DrawShiftPolygons(Path.GetDirectoryName(gearboxFile), engineData.FullLoadCurve, shiftPolygons,
+				"R49_375c_BB1386.png",
+				DeclarationData.Gearbox.TruckMaxAllowedSpeed / rdyn * axlegearRatio * gearboxData.Gears.Last().Ratio, upshiftOrig,
+				downshiftTransformed);
+		}
+	}
 
-		//	var engineData = new CombustionEngineData() {
-		//		IdleSpeed = 509.RPMtoRad(),
-		//		FullLoadCurve = EngineFullLoadCurve.ReadFromFile(engineFldFile, true)
-		//	};
+	[TestFixture]
+	public class ShiftPolygonComparison
+	{
+		const string BasePath = @"E:\QUAM\Workspace\Daten_INTERN\Testfahrzeuge\";
+
+		[
+			TestCase(@"class2_12t_baseline\175kW_Diesel_example.vfld", @"class2_12t_baseline\delivery_12t_example.vgbx", 0.421,
+				4.18, 600),
+			TestCase(@"class2_12t_iaxle_long\175kW_Diesel_example.vfld", @"class2_12t_iaxle_long\delivery_12t_example.vgbx",
+				0.421, 2.85, 600),
+			TestCase(@"class2_12t_iaxle_short\175kW_Diesel_example.vfld", @"class2_12t_iaxle_short\delivery_12t_example.vgbx",
+				0.421, 5.33, 600),
+			TestCase(@"class2_12t_Pmax_high\220kW_Diesel_example.vfld", @"class2_12t_Pmax_high\delivery_12t_example_220kW.vgbx",
+				0.421, 4.18, 600),
+			TestCase(@"class2_12t_Pmax_low\130kW_Diesel_example.vfld", @"class2_12t_Pmax_low\delivery_12t_example.vgbx", 0.421,
+				4.18, 600),
+			TestCase(@"class5_40t_baseline\12L-324kW.vfld", @"class5_40t_baseline\tractor_12gear_example.vgbx", 0.421, 2.64, 600),
+			TestCase(@"class5_40t_iaxle_long\12L-324kW.vfld", @"class5_40t_iaxle_long\tractor_12gear_example.vgbx", 0.421, 2.31,
+				600),
+			TestCase(@"class5_40t_iaxle_short\12L-324kW.vfld", @"class5_40t_iaxle_short\tractor_12gear_example.vgbx", 0.421, 3.71,
+				600),
+			TestCase(@"class5_40t_Pmax_high\13-9-L-375kW.vfld", @"class5_40t_Pmax_high\tractor_12gear_example.vgbx", 0.421,
+				2.64, 600),
+			TestCase(@"class5_40t_Pmax_low\9-6-L_260kW.vfld", @"class5_40t_Pmax_low\tractor_12gear_example.vgbx", 0.421, 2.64,
+				600),
+		]
+		public void ComputeShiftPolygon(string engineFldFile, string gearboxFile, double rdyn, double axlegearRatio,
+			double idlingSpeed)
+		{
+			var engineData = new CombustionEngineData() {
+				IdleSpeed = idlingSpeed.RPMtoRad(),
+				FullLoadCurve = EngineFullLoadCurve.ReadFromFile(Path.Combine(BasePath, engineFldFile), true)
+			};
+			engineData.FullLoadCurve.EngineData = engineData;
 
-		//	var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
+			var gearboxData = new JSONGearboxDataV5(JSONInputDataFactory.ReadFile(Path.Combine(BasePath, gearboxFile)),
+				Path.Combine(BasePath, 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));
-		//	}
-		//}
+			var shiftPolygons = new List<ShiftPolygon>();
+			var downshiftTransformed = new List<List<Point>>();
+			var upshiftOrig = new List<List<Point>>();
+			for (var i = 0; i < gearboxData.Gears.Count; i++) {
+				shiftPolygons.Add(
+					DeclarationData.Gearbox.ComputeShiftPolygon(i, engineData.FullLoadCurve, gearboxData.Gears,
+						engineData, axlegearRatio, rdyn.SI<Meter>())
+					);
+				List<Point> tmp1, tmp2;
+				ComputShiftPolygonPoints(i, engineData.FullLoadCurve, gearboxData.Gears,
+					engineData, axlegearRatio, rdyn.SI<Meter>(), out tmp1, out tmp2);
+				upshiftOrig.Add(tmp1);
+				downshiftTransformed.Add(tmp2);
+			}
+
+			var imageFile = Path.GetDirectoryName(gearboxFile) + "_" + Path.GetFileNameWithoutExtension(gearboxFile) + "_" +
+							Path.GetFileNameWithoutExtension(engineFldFile) +
+							".png";
+			ShiftPolygonDrawer.DrawShiftPolygons(Path.GetDirectoryName(gearboxFile), engineData.FullLoadCurve, shiftPolygons,
+				imageFile,
+				DeclarationData.Gearbox.TruckMaxAllowedSpeed / rdyn.SI<Meter>() * axlegearRatio * gearboxData.Gears.Last().Ratio,
+				upshiftOrig, downshiftTransformed);
+		}
+
+
+		public static void ComputShiftPolygonPoints(int gear, FullLoadCurve fullLoadCurve,
+			IList<ITransmissionInputData> gears, CombustionEngineData engine, double axlegearRatio, Meter dynamicTyreRadius,
+			out List<Point> upshiftOrig, out List<Point> downshiftTransformed)
+		{
+			var engineSpeed85kmhLastGear = DeclarationData.Gearbox.TruckMaxAllowedSpeed / dynamicTyreRadius * axlegearRatio *
+											gears[gears.Count - 1].Ratio;
+			//var engineSpeed85kmhSecondToLastGear = ComputeEngineSpeed85kmh(gears[gears.Count - 2], axlegearRatio,
+			//	dynamicTyreRadius, engine);
+
+			var nVHigh = VectoMath.Min(engineSpeed85kmhLastGear, engine.FullLoadCurve.RatedSpeed);
+
+			var diffRatio = gears[gears.Count - 2].Ratio / gears[gears.Count - 1].Ratio - 1;
+
+			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(nVHigh.Value() * 0.9,
+				engine.FullLoadCurve.FullLoadStationaryTorque(nVHigh * 0.9).Value());
+
+			var p4 =
+				new Point((nVHigh * (1 + diffRatio / 3)).Value(), 0);
+			var p5 = new Point(engine.FullLoadCurve.N95hSpeed.Value(), engine.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, nVHigh * 0.95);
+			//var downshiftCorr = MoveDownshiftBelowFld(Edge.Create(p6, p3), fldMargin, 1.1 * fullLoadCurve.MaxTorque);
+			upshiftOrig = new[] { p4, p7, p5 }.ToList();
+			downshiftTransformed = new List<Point>();
+
+			if (gear >= gears.Count - 1) {
+				return;
+			}
+			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);
+
+			downshiftTransformed = new[] { p2p, p6p, p3pExt }.ToList();
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs
index 42fe90b4a5a97a2994fd4f82897549055b802e11..8eaad5afbeb6962133942a6e14a92bf70b9090d7 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/FactoryTest.cs
@@ -72,18 +72,19 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 
 			// -- shiftpolygon downshift 
 
-			Assert.AreEqual(660.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[0].AngularSpeed.Value(),
+			// no downshift curve in first gear!
+			Assert.AreEqual(660.RPMtoRad().Value(), gearbox.ModelData.Gears[2].ShiftPolygon.Downshift[0].AngularSpeed.Value(),
 				0.0001);
-			Assert.AreEqual(-163.9, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[0].Torque.Value(), 0.0001);
+			Assert.AreEqual(-163.9, gearbox.ModelData.Gears[2].ShiftPolygon.Downshift[0].Torque.Value(), 0.0001);
 
-			Assert.AreEqual(660.RPMtoRad().Value(), gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[1].AngularSpeed.Value(),
+			Assert.AreEqual(660.RPMtoRad().Value(), gearbox.ModelData.Gears[2].ShiftPolygon.Downshift[1].AngularSpeed.Value(),
 				0.0001);
-			Assert.AreEqual(257.7076, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[1].Torque.Value(), 0.1);
+			Assert.AreEqual(208.116856, gearbox.ModelData.Gears[2].ShiftPolygon.Downshift[1].Torque.Value(), 0.1);
 
-			Assert.AreEqual(1681.4261.RPMtoRad().Value(),
-				gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[2].AngularSpeed.Value(),
+			Assert.AreEqual(1750.70139.RPMtoRad().Value(),
+				gearbox.ModelData.Gears[2].ShiftPolygon.Downshift[2].AngularSpeed.Value(),
 				0.1);
-			Assert.AreEqual(988.9, gearbox.ModelData.Gears[1].ShiftPolygon.Downshift[2].Torque.Value(), 0.0001);
+			Assert.AreEqual(988.9, gearbox.ModelData.Gears[2].ShiftPolygon.Downshift[2].Torque.Value(), 0.0001);
 
 			// -- shiftpolygon upshift
 
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
index e275eb04da1ca358fc914d3506dadba55c7b4b11..37bc421fb4bc5ad3d033f6b14c14871f0f1fb96b 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
@@ -129,6 +129,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 			Assert.IsTrue(engineData.IsValid());
 		}
 
+
 		[TestMethod]
 		public void Validation_CombustionEngineData_Declaration()
 		{
@@ -173,7 +174,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 		[TestMethod]
 		public void Validation_VectoRun()
 		{
-			var container = new VehicleContainer(ExecutionMode.Declaration);
+			var container = new VehicleContainer(ExecutionMode.Engineering);
 			var data = new DistanceRun(container);
 			var engineData = new CombustionEngineData {
 				FullLoadCurve = EngineFullLoadCurve.ReadFromFile(@"TestData\Components\12t Delivery Truck.vfld"),
@@ -217,15 +218,49 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 				"Validation Error: " + string.Join("\n_eng_avg", results.Select(r => r.ErrorMessage)));
 		}
 
+		/// <summary>
+		/// VECTO-249: check upshift is above downshift
+		/// </summary>
+		[TestMethod]
+		public void ShiftPolygonValidationTest()
+		{
+			var vgbs = new[] {
+				"-116,600,1508						",
+				"0,600,1508							",
+				"293,600,1508						",
+				"494,806,1508						",
+				"956,1278,2355						",
+			};
+
+			var shiftPolygon =
+				ShiftPolygon.Create(
+					VectoCSVFile.ReadStream(
+						InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm]	", vgbs)));
+
+			var results = shiftPolygon.Validate();
+			Assert.IsFalse(results.Any());
+
+			shiftPolygon =
+				ShiftPolygon.Create(
+					VectoCSVFile.ReadStream(
+						InputDataHelper.InputDataAsStream("engine torque,upshift rpm [rpm], downshift rpm [rpm]	", vgbs)));
+
+			results = shiftPolygon.Validate();
+			Assert.IsTrue(results.Any());
+		}
+
+
 		public class DeepDataObject
 		{
 			[Required, Range(41, 42)] protected int public_field = 5;
 		}
 
+
 		public abstract class ParentDataObject
 		{
 			#region 4 parent instance fields
 
+			// ReSharper disable once NotAccessedField.Local
 			[Required, Range(1, 2)] private int private_parent_field = 7;
 			[Required, Range(3, 4)] protected int protected_parent_field = 7;
 			[Required, Range(5, 6)] internal int internal_parent_field = 7;
@@ -314,6 +349,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 		{
 			#region 4 instance fields
 
+			// ReSharper disable once NotAccessedField.Local
 			[Required, Range(1, 2)] private int private_field = 7;
 			[Required, Range(3, 4)] protected int protected_field = 7;
 			[Required, Range(5, 6)] internal int internal_field = 7;
diff --git a/VectoCore/VectoCoreTest/Utils/ShiftPolygonDrawer.cs b/VectoCore/VectoCoreTest/Utils/ShiftPolygonDrawer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8b16d06df1468e1624403377522d444d1bff9065
--- /dev/null
+++ b/VectoCore/VectoCoreTest/Utils/ShiftPolygonDrawer.cs
@@ -0,0 +1,367 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Windows.Forms.DataVisualization.Charting;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using Point = TUGraz.VectoCore.Utils.Point;
+
+namespace TUGraz.VectoCore.Tests.Utils
+{
+	public class ShiftPolygonDrawer
+	{
+		private static readonly Font AxisLabelFont = new Font("Consolas", 10);
+		private static readonly Font AxisTitleFont = new Font("Verdana", 12);
+		private static readonly Font LegendFont = new Font("Verdana", 14);
+
+		private static Size _diagramSize = new Size(1000, 800);
+
+		public static void DrawShiftPolygons(string title, EngineFullLoadCurve engineFld, List<ShiftPolygon> polygons,
+			string imageFileName, PerSecond speed85kmh, List<List<Point>> upshiftOrig = null,
+			List<List<Point>> downshiftTransformed = null)
+		{
+			var numRows = Math.Ceiling(polygons.Count / 4.0);
+			var numCols = Math.Ceiling(polygons.Count / numRows);
+
+			var chart = new Chart() {
+				Size = new Size((int)(_diagramSize.Width * numCols), (int)(_diagramSize.Height * numRows))
+			};
+			var maxX = engineFld.FullLoadEntries.Last().EngineSpeed.Value() / Constants.RPMToRad * 1.1;
+
+			AddLegend(chart);
+
+			var i = 0;
+			foreach (var shiftPolygon in polygons) {
+				var chartArea = AddChartArea(chart, "Gear " + (i + 1), "Engine Speed", "Torque", 0, maxX);
+
+				PlotPower(engineFld, chartArea, chart, "engine power " + i);
+				PlotFLD(engineFld, speed85kmh, chartArea, chart, "Engine Full Load " + i);
+
+				if (upshiftOrig != null && i < upshiftOrig.Count) {
+					PlotShiftLine("UpshiftOrig " + i, chartArea, chart, Color.Gray,
+						upshiftOrig[i].Select(pt => pt.X / Constants.RPMToRad).ToList(), upshiftOrig[i].Select(pt => pt.Y).ToList(), true);
+				}
+				if (downshiftTransformed != null && i < downshiftTransformed.Count) {
+					PlotShiftLine("DownTransformed " + i, chartArea, chart, Color.BlueViolet,
+						downshiftTransformed[i].Select(pt => pt.X / Constants.RPMToRad).ToList(),
+						downshiftTransformed[i].Select(pt => pt.Y).ToList(), true);
+				}
+
+				PlotShiftPolygon(i, shiftPolygon, chartArea, chart);
+
+				PositionChartArea(chartArea, 5, i, polygons.Count, 7);
+
+
+				i++;
+			}
+
+			AddTitle(chart, title);
+			chart.Invalidate();
+			chart.SaveImage(imageFileName, ChartImageFormat.Png);
+		}
+
+		private static void PlotPower(EngineFullLoadCurve engineFld, ChartArea chartArea, Chart chart, string name)
+		{
+			var series = new Series {
+				Name = name,
+				ChartType = SeriesChartType.Line,
+				Color = Color.DarkGoldenrod,
+				BorderWidth = 2,
+				//Legend = legend.Name,
+				IsVisibleInLegend = false,
+				ChartArea = chartArea.Name,
+				//YAxisType = AxisType.Secondary
+			};
+			series.BorderDashStyle = ChartDashStyle.Dash;
+			series.BorderWidth = 1;
+
+			var x = new List<double>();
+			var y = new List<double>();
+			for (var i = engineFld.FullLoadEntries.First().EngineSpeed;
+				i < engineFld.FullLoadEntries.Last().EngineSpeed;
+				i += 5.RPMtoRad()) {
+				x.Add(i.Value() / Constants.RPMToRad);
+				y.Add(engineFld.FullLoadStationaryPower(i).Value() / 1000);
+			}
+
+			chart.Series.Add(series);
+			chart.Series[series.Name].Points.DataBindXY(x, y);
+		}
+
+		private static void AddTitle(Chart chart, string titleText)
+		{
+			var title = new Title {
+				Text = titleText,
+				IsDockedInsideChartArea = false,
+				Font = new Font("Verdana", 18, FontStyle.Bold)
+			};
+			//title.DockedToChartArea = dockToChartArea;
+			chart.Titles.Add(title);
+		}
+
+		private static void PositionChartArea(ChartArea chartArea, float titleHeight, int i, int count, float legendHeight)
+		{
+			var numRows = Math.Ceiling(count / 4.0);
+			var numCols = Math.Ceiling(count / numRows);
+			chartArea.Position.Auto = false;
+			chartArea.Position.Width = (float)((100.0f) / numCols);
+			chartArea.Position.Height = (float)((100.0f - titleHeight) / numRows);
+			chartArea.Position.X = (float)(((i) % numCols) * 100.0f / numCols);
+			chartArea.Position.Y = (float)(titleHeight + (int)((i) / numCols) * (100 - titleHeight - legendHeight) / numRows);
+		}
+
+		private static void PlotShiftPolygon(int gear, ShiftPolygon shiftPolygon, ChartArea chartArea, Chart chart)
+		{
+			var x = new List<double>();
+			var y = new List<double>();
+			foreach (var entry in shiftPolygon.Downshift) {
+				x.Add(entry.AngularSpeed.Value() / Constants.RPMToRad);
+				y.Add(entry.Torque.Value());
+			}
+			PlotShiftLine("DownShift " + gear, chartArea, chart, Color.DarkRed, x, y);
+
+
+			var xUp = new List<double>();
+			var yUp = new List<double>();
+			foreach (var entry in shiftPolygon.Upshift) {
+				xUp.Add(entry.AngularSpeed.Value() / Constants.RPMToRad);
+				yUp.Add(entry.Torque.Value());
+			}
+			PlotShiftLine("UpShift " + gear, chartArea, chart, Color.DarkRed, xUp, yUp);
+
+
+			//return series;
+		}
+
+		private static void PlotShiftLine(string name, ChartArea chartArea, Chart chart, Color color, List<double> x,
+			List<double> y, bool dashed = false)
+		{
+			var series = new Series {
+				Name = name,
+				ChartType = SeriesChartType.Line,
+				Color = color,
+				BorderWidth = 2,
+				//Legend = legend.Name,
+				IsVisibleInLegend = false,
+				ChartArea = chartArea.Name,
+			};
+			if (dashed) {
+				series.BorderDashStyle = ChartDashStyle.Dash;
+				series.BorderWidth = 1;
+			}
+
+			chart.Series.Add(series);
+			chart.Series[series.Name].Points.DataBindXY(x, y);
+		}
+
+		private static void PlotFLD(EngineFullLoadCurve engineFld, PerSecond speed85kmh, ChartArea chartArea, Chart chart,
+			string name)
+		{
+			PlotFullLoad(engineFld, chartArea, chart, name);
+
+			PlotDragLoad(engineFld, chartArea, chart, name);
+
+			PlotEngineSpeedLine(engineFld, chartArea, chart, "nPref " + name, Color.DeepSkyBlue,
+				engineFld.PreferredSpeed.Value() / Constants.RPMToRad);
+
+			PlotEngineSpeedLine(engineFld, chartArea, chart, "n95h " + name, Color.Red,
+				engineFld.N95hSpeed.Value() / Constants.RPMToRad);
+
+			PlotEngineSpeedLine(engineFld, chartArea, chart, "n85kmh " + name, Color.LimeGreen,
+				speed85kmh.Value() / Constants.RPMToRad);
+
+			PlotEngineSpeedLine(engineFld, chartArea, chart, "nPmax " + name, Color.Coral,
+				engineFld.RatedSpeed.Value() / Constants.RPMToRad);
+		}
+
+
+		private static void PlotEngineSpeedLine(EngineFullLoadCurve engineFld, ChartArea chartArea, Chart chart, string name,
+			Color color, double n)
+		{
+			var seriesNpref = new Series {
+				Name = name,
+				ChartType = SeriesChartType.Line,
+				Color = color,
+				BorderWidth = 2,
+				//Legend = legend.Name,
+				IsVisibleInLegend = false,
+				ChartArea = chartArea.Name,
+			};
+			chart.Series.Add(seriesNpref);
+			var xpref =
+				new[]
+				{ n, n }
+					.ToList();
+			var ypref = new[] { engineFld.MaxDragTorque.Value(), engineFld.MaxLoadTorque.Value() }.ToList();
+			chart.Series[seriesNpref.Name].Points.DataBindXY(xpref, ypref);
+		}
+
+		private static void PlotDragLoad(EngineFullLoadCurve engineFld, ChartArea chartArea, Chart chart, string name)
+		{
+			var seriesDrag = new Series {
+				Name = "Drag-" + name,
+				ChartType = SeriesChartType.Line,
+				Color = Color.DarkBlue,
+				BorderWidth = 2,
+				//Legend = legend.Name,
+				IsVisibleInLegend = false,
+				ChartArea = chartArea.Name,
+			};
+			chart.Series.Add(seriesDrag);
+			var xDrag = new List<double>();
+			var yDrag = new List<double>();
+			engineFld.FullLoadEntries.ForEach(entry => {
+				xDrag.Add(entry.EngineSpeed.Value() / Constants.RPMToRad);
+				yDrag.Add(entry.TorqueDrag.Value());
+			});
+			chart.Series[seriesDrag.Name].Points.DataBindXY(xDrag, yDrag);
+		}
+
+		private static void PlotFullLoad(EngineFullLoadCurve engineFld, ChartArea chartArea, Chart chart, string name)
+		{
+			var series = new Series {
+				Name = name,
+				ChartType = SeriesChartType.Line,
+				Color = Color.DarkBlue,
+				BorderWidth = 2,
+				//Legend = legend.Name,
+				IsVisibleInLegend = false,
+				ChartArea = chartArea.Name,
+			};
+			chart.Series.Add(series);
+			var x = new List<double>();
+			var y = new List<double>();
+			engineFld.FullLoadEntries.ForEach(entry => {
+				x.Add(entry.EngineSpeed.Value() / Constants.RPMToRad);
+				y.Add(entry.TorqueFullLoad.Value());
+			});
+			chart.Series[series.Name].Points.DataBindXY(x, y);
+		}
+
+		private static ChartArea AddChartArea(Chart chart, string name, string axisXTitle, string axisYTitle, double xMin,
+			double xMax, bool discreteValues = false)
+		{
+			var chartArea = new ChartArea { Name = name };
+			chartArea.AxisX.MajorGrid.LineColor = Color.DarkGray;
+			chartArea.AxisY.MajorGrid.LineColor = Color.DarkGray;
+			chartArea.AxisX.LabelStyle.Font = AxisLabelFont;
+			chartArea.AxisY.LabelStyle.Font = AxisLabelFont;
+
+			chartArea.AxisX.Interval = xMax / 20.0;
+			chartArea.AxisX.Maximum = xMax;
+			chartArea.AxisX.Minimum = xMin;
+			chartArea.AxisX.MinorGrid.Enabled = true;
+			chartArea.AxisX.MinorGrid.Interval = (xMax - xMin) / 100.0;
+			chartArea.AxisX.MinorGrid.LineColor = Color.LightGray;
+			chartArea.AxisX.Title = axisXTitle;
+			chartArea.AxisX.TitleFont = AxisTitleFont;
+			chartArea.AxisX.RoundAxisValues();
+			chartArea.AxisX.MajorTickMark.Size = 2 * 100.0f / _diagramSize.Height;
+
+			chartArea.AxisY.Title = axisYTitle;
+			chartArea.AxisY.TitleFont = AxisTitleFont;
+			chartArea.AxisY.RoundAxisValues();
+			if (discreteValues) {
+				chartArea.AxisY.MajorGrid.Interval = 1;
+				chartArea.AxisY.MinorGrid.Enabled = false;
+			} else {
+				chartArea.AxisY.MinorGrid.Enabled = true;
+			}
+			chartArea.AxisY.MinorGrid.LineColor = Color.LightGray;
+			chartArea.AxisY.MajorTickMark.Size = 5 * 100.0f / _diagramSize.Width;
+
+			chart.ChartAreas.Add(chartArea);
+			return chartArea;
+		}
+
+		private static void AddLegend(Chart chart)
+		{
+			var legend = new Legend()
+			{
+				Docking = Docking.Bottom,
+				Alignment = StringAlignment.Center,
+				IsDockedInsideChartArea = false,
+				Font = LegendFont,
+				//Title = "Legend",
+			};
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.DarkBlue,
+				Name = "Engine Full Load Curve",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.DarkRed,
+				Name = "Upshift / Downshift",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.DeepSkyBlue,
+				Name = "n_pref",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.Coral,
+				Name = "n_Pmax",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.Red,
+				Name = "n_95h",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.LimeGreen,
+				Name = "n_85km/h",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.BlueViolet,
+				Name = "Downshift next gear",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.Gray,
+				Name = "Upshift orig.",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			legend.CustomItems.Add(new LegendItem()
+			{
+				Color = Color.DarkGoldenrod,
+				Name = "P",
+				MarkerStyle = MarkerStyle.None,
+				ImageStyle = LegendImageStyle.Line,
+				BorderWidth = 3,
+			});
+			chart.Legends.Add(legend);
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj
index f9fa26838d2bbc5553d63818712cfe9a96d24797..3147d04a8853c60dbb4abf157f8b6f0dc336ce1d 100644
--- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj
+++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj
@@ -145,6 +145,7 @@
       <DependentUpon>Settings.settings</DependentUpon>
     </Compile>
     <Compile Include="Utils\MockGearbox.cs" />
+    <Compile Include="Utils\ShiftPolygonDrawer.cs" />
     <Compile Include="Utils\SITest.cs" />
     <Compile Include="Utils\DelauneyMapTest.cs" />
     <Compile Include="Utils\MockModalDataContainer.cs" />