diff --git a/VectoCore/VectoCore/InputData/Reader/ShiftPolygonReader.cs b/VectoCore/VectoCore/InputData/Reader/ShiftPolygonReader.cs
index 72ded465a88707b7aa3c65f27b39386b9212c8c2..c38b34afd9a052c9193f07ec184f20c98e42616f 100644
--- a/VectoCore/VectoCore/InputData/Reader/ShiftPolygonReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ShiftPolygonReader.cs
@@ -88,37 +88,21 @@ namespace TUGraz.VectoCore.InputData.Reader
 		private static List<ShiftPolygon.ShiftPolygonEntry> CreateFromColumnNames(DataTable data, string columnName)
 		{
 			return (from DataRow row in data.Rows
-				select new ShiftPolygon.ShiftPolygonEntry {
-					Torque = row.ParseDouble(Fields.Torque).SI<NewtonMeter>(),
-					AngularSpeed = row.ParseDouble(columnName).RPMtoRad(),
-				}).ToList();
+				select new ShiftPolygon.ShiftPolygonEntry(row.SI<NewtonMeter>(Fields.Torque),
+					row.ParseDouble(columnName).RPMtoRad())).ToList();
 		}
 
 		private static List<ShiftPolygon.ShiftPolygonEntry> CreateFromColumnIndizes(DataTable data, int column)
 		{
 			return (from DataRow row in data.Rows
-				select
-					new ShiftPolygon.ShiftPolygonEntry {
-						Torque = row.ParseDouble(0).SI<NewtonMeter>(),
-						AngularSpeed = row.ParseDouble(column).RPMtoRad(),
-					}).ToList();
+					select new ShiftPolygon.ShiftPolygonEntry(row.SI<NewtonMeter>(0), row.ParseDouble(column).RPMtoRad()))
+				.ToList();
 		}
 
 		public static class Fields
 		{
-			/// <summary>
-			///		[Nm] torque
-			/// </summary>
 			public const string Torque = "engine torque";
-
-			/// <summary>
-			///		[rpm] threshold for upshift
-			/// </summary>
 			public const string AngularSpeedUp = "upshift rpm";
-
-			/// <summary>
-			///		[rpm] threshold for downshift
-			/// </summary>
 			public const string AngularSpeedDown = "downshift rpm";
 		}
 	}
diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
index 633b2fc76fe3e3a398f9719b29c982ac89ba918e..fb8d082597fc48c6facd9e7043d97200948cd510 100644
--- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
@@ -96,7 +96,6 @@ namespace TUGraz.VectoCore.Models.Declaration
 			return 1;
 		}
 
-
 		public static class Driver
 		{
 			public static class LookAhead
@@ -177,6 +176,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 
 			//public static readonly PerSecond TorqueConverterSpeedLimit = 1600.RPMtoRad();
 			public static readonly double TorqueConverterSecondGearThreshold = 1.8;
+
 			public static readonly Second PowershiftShiftTime = 0.8.SI<Second>();
 
 			/// <summary>
@@ -233,11 +233,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 				if (gearIdx > 0) {
 					downShift =
 						new[] { p2, downshiftCorr.P1, downshiftCorr.P2 }.Select(
-							point => new ShiftPolygon.ShiftPolygonEntry() {
-								AngularSpeed = point.X.SI<PerSecond>(),
-								Torque = point.Y.SI<NewtonMeter>()
-							})
-							.ToList();
+							point => new ShiftPolygon.ShiftPolygonEntry(point.Y.SI<NewtonMeter>(), point.X.SI<PerSecond>())).ToList();
 
 					downShift[0].Torque = maxDragTorque;
 				}
@@ -258,11 +254,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 				// ReSharper restore InconsistentNaming
 
 				upShift = IntersectShiftPolygon(new[] { p4, p7, p5 }, new[] { p2p, p6p, p3pExt })
-					.Select(point => new ShiftPolygon.ShiftPolygonEntry() {
-						AngularSpeed = point.X.SI<PerSecond>(),
-						Torque = point.Y.SI<NewtonMeter>()
-					})
-					.ToList();
+					.Select(point => new ShiftPolygon.ShiftPolygonEntry(point.Y.SI<NewtonMeter>(), point.X.SI<PerSecond>())).ToList();
 				upShift[0].Torque = maxDragTorque;
 				return new ShiftPolygon(downShift, upShift);
 			}
@@ -398,12 +390,11 @@ namespace TUGraz.VectoCore.Models.Declaration
 				var p2corr = new Point((maxTorque.Value() - edge.OffsetXY) / edge.SlopeXY, maxTorque.Value());
 
 				var downshift = new[] {
-					new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = DownshiftPRM, Torque = maxDragTorque },
-					new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = DownshiftPRM, Torque = maxTorque }
+					new ShiftPolygon.ShiftPolygonEntry(maxDragTorque, DownshiftPRM),
+					new ShiftPolygon.ShiftPolygonEntry(maxTorque, DownshiftPRM)
 				};
 				var upshift = new[] { p0, p1, p2corr }.Select(
-					pt =>
-						new ShiftPolygon.ShiftPolygonEntry { AngularSpeed = pt.X.SI<PerSecond>(), Torque = pt.Y.SI<NewtonMeter>() });
+					pt => new ShiftPolygon.ShiftPolygonEntry(pt.Y.SI<NewtonMeter>(), pt.X.SI<PerSecond>()));
 
 				return new ShiftPolygon(first ? new List<ShiftPolygon.ShiftPolygonEntry>() : downshift.ToList(),
 					last ? new List<ShiftPolygon.ShiftPolygonEntry>() : upshift.ToList());
@@ -415,11 +406,11 @@ namespace TUGraz.VectoCore.Models.Declaration
 				var data = VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceId), source: resourceId);
 				var characteristicTorque = (from DataRow row in data.Rows
 					select
-						new TorqueConverterEntry() {
-							SpeedRatio = row.ParseDouble(TorqueConverterDataReader.Fields.SpeedRatio),
-							Torque = row.ParseDouble(TorqueConverterDataReader.Fields.CharacteristicTorque).SI<NewtonMeter>(),
-							TorqueRatio = row.ParseDouble(TorqueConverterDataReader.Fields.TorqueRatio)
-						}).ToArray();
+					new TorqueConverterEntry() {
+						SpeedRatio = row.ParseDouble(TorqueConverterDataReader.Fields.SpeedRatio),
+						Torque = row.ParseDouble(TorqueConverterDataReader.Fields.CharacteristicTorque).SI<NewtonMeter>(),
+						TorqueRatio = row.ParseDouble(TorqueConverterDataReader.Fields.TorqueRatio)
+					}).ToArray();
 				foreach (var torqueConverterEntry in characteristicTorque) {
 					torqueConverterEntry.SpeedRatio = torqueConverterEntry.SpeedRatio * ratio;
 					torqueConverterEntry.TorqueRatio = torqueConverterEntry.TorqueRatio / ratio;
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
index 3069a63cae0014d01309ab42e67e4641f9f4dcd4..e093882dbd00e62e485f5c2da0d9af8fddc8b57e 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
@@ -1,191 +1,198 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2016 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 System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel.DataAnnotations;
-using System.Diagnostics;
-using System.Linq;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
-{
-	[CustomValidation(typeof(ShiftPolygon), "ValidateShiftPolygon")]
-	public class ShiftPolygon : SimulationComponentData
-	{
-		private readonly List<ShiftPolygonEntry> _upShiftPolygon;
-		private readonly List<ShiftPolygonEntry> _downShiftPolygon;
-
-		internal ShiftPolygon(List<ShiftPolygonEntry> downshift, List<ShiftPolygonEntry> upShift)
-		{
-			_upShiftPolygon = upShift;
-			_downShiftPolygon = downshift;
-		}
-
-
-		public ReadOnlyCollection<ShiftPolygonEntry> Upshift
-		{
-			get { return _upShiftPolygon.AsReadOnly(); }
-		}
-
-		public ReadOnlyCollection<ShiftPolygonEntry> Downshift
-		{
-			get { return _downShiftPolygon.AsReadOnly(); }
-		}
-
-		public bool IsBelowDownshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
-		{
-			var section = Downshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
-			if (section.Item2.AngularSpeed < inAngularVelocity) {
-				return false;
-			}
-			return IsLeftOf(inAngularVelocity, inTorque, section);
-		}
-
-		public bool IsBelowUpshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
-		{
-			var section = Upshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
-			if (section.Item2.AngularSpeed < inAngularVelocity) {
-				return false;
-			}
-			return IsLeftOf(inAngularVelocity, inTorque, section);
-		}
-
-		public bool IsAboveDownshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
-		{
-			var section = Downshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
-
-			if (section.Item2.AngularSpeed < inAngularVelocity) {
-				return true;
-			}
-			return IsRightOf(inAngularVelocity, inTorque, section);
-		}
-
-		public bool IsAboveUpshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
-		{
-			var section = Upshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
-
-			if (section.Item2.AngularSpeed < inAngularVelocity) {
-				return true;
-			}
-			return IsRightOf(inAngularVelocity, inTorque, section);
-		}
-
-		/// <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>
-		protected static bool IsLeftOf(PerSecond angularSpeed, NewtonMeter torque,
-			Tuple<ShiftPolygonEntry, ShiftPolygonEntry> segment)
-		{
-			var abX = segment.Item2.AngularSpeed.Value() - segment.Item1.AngularSpeed.Value();
-			var abY = segment.Item2.Torque.Value() - segment.Item1.Torque.Value();
-			var acX = angularSpeed.Value() - segment.Item1.AngularSpeed.Value();
-			var acY = torque.Value() - segment.Item1.Torque.Value();
-			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>
-		protected static bool IsRightOf(PerSecond angularSpeed, NewtonMeter torque,
-			Tuple<ShiftPolygonEntry, ShiftPolygonEntry> segment)
-		{
-			var abX = segment.Item2.AngularSpeed.Value() - segment.Item1.AngularSpeed.Value();
-			var abY = segment.Item2.Torque.Value() - segment.Item1.Torque.Value();
-			var acX = angularSpeed.Value() - segment.Item1.AngularSpeed.Value();
-			var acY = torque.Value() - segment.Item1.Torque.Value();
-			var z = abX * acY - abY * acX;
-			return z.IsSmaller(0);
-		}
-
-
-		// ReSharper disable once UnusedMember.Global -- used via validation
-		public static ValidationResult ValidateShiftPolygon(ShiftPolygon shiftPolygon, ValidationContext validationContext)
-		{
-			var validationService =
-				validationContext.GetService(typeof(VectoValidationModeServiceContainer)) as VectoValidationModeServiceContainer;
-			var gbxType = validationService != null ? validationService.GearboxType : null;
-
-			if (gbxType == null || gbxType.Value.AutomaticTransmission()) {
-				return ValidationResult.Success;
-			}
-
-			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;
-		}
-
-
-		[DebuggerDisplay("{Torque}, {AngularSpeed}")]
-		public class ShiftPolygonEntry
-		{
-			/// <summary>
-			///		[Nm] engine torque
-			/// </summary>
-			public NewtonMeter Torque { get; set; }
-
-			/// <summary>
-			///		[1/s] angular velocity threshold
-			/// </summary>
-			public PerSecond AngularSpeed { get; set; }
-		}
-
-		public NewtonMeter InterpolateDownshift(PerSecond inAngularVelocity)
-		{
-			var section = Downshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
-
-			if (section.Item1.AngularSpeed.IsEqual(section.Item2.AngularSpeed)) {
-				// vertical line
-				return double.MaxValue.SI<NewtonMeter>();
-			}
-			return VectoMath.Interpolate(section.Item1.AngularSpeed, section.Item2.AngularSpeed, section.Item1.Torque,
-				section.Item2.Torque, inAngularVelocity);
-		}
-	}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2016 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 System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel.DataAnnotations;
+using System.Diagnostics;
+using System.Linq;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
+{
+	[CustomValidation(typeof(ShiftPolygon), "ValidateShiftPolygon")]
+	public class ShiftPolygon : SimulationComponentData
+	{
+		private readonly List<ShiftPolygonEntry> _upShiftPolygon;
+		private readonly List<ShiftPolygonEntry> _downShiftPolygon;
+
+		internal ShiftPolygon(List<ShiftPolygonEntry> downshift, List<ShiftPolygonEntry> upShift)
+		{
+			_upShiftPolygon = upShift;
+			_downShiftPolygon = downshift;
+		}
+
+		public ReadOnlyCollection<ShiftPolygonEntry> Upshift
+		{
+			get { return _upShiftPolygon.AsReadOnly(); }
+		}
+
+		public ReadOnlyCollection<ShiftPolygonEntry> Downshift
+		{
+			get { return _downShiftPolygon.AsReadOnly(); }
+		}
+
+		public bool IsBelowDownshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
+		{
+			var section = Downshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
+			if (section.Item2.AngularSpeed < inAngularVelocity) {
+				return false;
+			}
+			return IsLeftOf(inAngularVelocity, inTorque, section);
+		}
+
+		public bool IsBelowUpshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
+		{
+			var section = Upshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
+			if (section.Item2.AngularSpeed < inAngularVelocity) {
+				return false;
+			}
+			return IsLeftOf(inAngularVelocity, inTorque, section);
+		}
+
+		public bool IsAboveDownshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
+		{
+			var section = Downshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
+
+			if (section.Item2.AngularSpeed < inAngularVelocity) {
+				return true;
+			}
+			return IsRightOf(inAngularVelocity, inTorque, section);
+		}
+
+		public bool IsAboveUpshiftCurve(NewtonMeter inTorque, PerSecond inAngularVelocity)
+		{
+			var section = Upshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
+
+			if (section.Item2.AngularSpeed < inAngularVelocity) {
+				return true;
+			}
+			return IsRightOf(inAngularVelocity, inTorque, section);
+		}
+
+		/// <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)
+		{
+			if (segment.Item1.AngularSpeed < angularSpeed && segment.Item2.AngularSpeed < angularSpeed)
+				return false;
+
+			var abX = segment.Item2.AngularSpeed.Value() - segment.Item1.AngularSpeed.Value();
+			var abY = segment.Item2.Torque.Value() - segment.Item1.Torque.Value();
+			var acX = angularSpeed.Value() - segment.Item1.AngularSpeed.Value();
+			var acY = torque.Value() - segment.Item1.Torque.Value();
+			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)
+		{
+			if (segment.Item1.AngularSpeed > angularSpeed && segment.Item2.AngularSpeed > angularSpeed)
+				return false;
+
+			var abX = segment.Item2.AngularSpeed.Value() - segment.Item1.AngularSpeed.Value();
+			var abY = segment.Item2.Torque.Value() - segment.Item1.Torque.Value();
+			var acX = angularSpeed.Value() - segment.Item1.AngularSpeed.Value();
+			var acY = torque.Value() - segment.Item1.Torque.Value();
+			var z = abX * acY - abY * acX;
+			return z.IsSmaller(0);
+		}
+
+		// ReSharper disable once UnusedMember.Global -- used via validation
+		public static ValidationResult ValidateShiftPolygon(ShiftPolygon shiftPolygon, ValidationContext validationContext)
+		{
+			var validationService =
+				validationContext.GetService(typeof(VectoValidationModeServiceContainer)) as VectoValidationModeServiceContainer;
+			var gbxType = validationService != null ? validationService.GearboxType : null;
+
+			if (gbxType == null || gbxType.Value.AutomaticTransmission()) {
+				return ValidationResult.Success;
+			}
+
+			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;
+		}
+
+		[DebuggerDisplay("{Torque}, {AngularSpeed}")]
+		public class ShiftPolygonEntry
+		{
+			public ShiftPolygonEntry(NewtonMeter torque, PerSecond angularSpeed)
+			{
+				Torque = torque;
+				AngularSpeed = angularSpeed;
+			}
+
+			/// <summary>
+			///		[Nm] engine torque
+			/// </summary>
+			public NewtonMeter Torque { get; set; }
+
+			/// <summary>
+			///		[1/s] angular velocity threshold
+			/// </summary>
+			public PerSecond AngularSpeed { get; set; }
+		}
+
+		public NewtonMeter InterpolateDownshift(PerSecond inAngularVelocity)
+		{
+			var section = Downshift.GetSection(entry => entry.AngularSpeed < inAngularVelocity);
+
+			if (section.Item1.AngularSpeed.IsEqual(section.Item2.AngularSpeed)) {
+				// vertical line
+				return double.MaxValue.SI<NewtonMeter>();
+			}
+			return VectoMath.Interpolate(section.Item1.AngularSpeed, section.Item2.AngularSpeed, section.Item1.Torque,
+				section.Item2.Torque, inAngularVelocity);
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Utils/DataTableExtensionMethods.cs b/VectoCore/VectoCore/Utils/DataTableExtensionMethods.cs
index 7afba99f94bfa6b3f46ae6e063cecb5c3b2ce5ef..2b83816cf8ea0d0cd52af4fec2f8675a05f73d49 100644
--- a/VectoCore/VectoCore/Utils/DataTableExtensionMethods.cs
+++ b/VectoCore/VectoCore/Utils/DataTableExtensionMethods.cs
@@ -1,102 +1,113 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2016 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 System.Collections.Generic;
-using System.Data;
-using System.Globalization;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Utils;
-
-namespace TUGraz.VectoCore.Utils
-{
-	public static class DataTableExtensionMethods
-	{
-		public static double ParseDoubleOrGetDefault(this DataRow row, string columnName,
-			double defaultValue = default(double))
-		{
-			if (row.Table.Columns.Contains(columnName)) {
-				double result;
-				if (double.TryParse(row.Field<string>(columnName), NumberStyles.Any, CultureInfo.InvariantCulture, out result)) {
-					return result;
-				}
-			}
-			return defaultValue;
-		}
-
-		public static double ParseDouble(this DataRow row, int columnIndex)
-		{
-			return row.ParseDouble(row.Table.Columns[columnIndex]);
-		}
-
-		public static double ParseDouble(this DataRow row, string columnName)
-		{
-			if (!row.Table.Columns.Contains(columnName)) {
-				throw new KeyNotFoundException(string.Format("Column {0} was not found in DataRow.", columnName));
-			}
-			return row.ParseDouble(row.Table.Columns[columnName]);
-		}
-
-		public static double ParseDouble(this DataRow row, DataColumn column)
-		{
-			try {
-				return row.Field<string>(column).ToDouble();
-			} catch (IndexOutOfRangeException e) {
-				throw new VectoException(string.Format("Field {0} was not found in DataRow.", column), e);
-			} catch (NullReferenceException e) {
-				throw new VectoException(string.Format("Field {0} must not be null.", column), e);
-			} catch (FormatException e) {
-				throw new VectoException(string.Format("Field {0} is not in a valid number format: {1}", column,
-					row.Field<string>(column)), e);
-			} catch (OverflowException e) {
-				throw new VectoException(string.Format("Field {0} has a value too high or too low: {1}", column,
-					row.Field<string>(column)), e);
-			} catch (ArgumentNullException e) {
-				throw new VectoException(string.Format("Field {0} contains null which cannot be converted to a number.", column), e);
-			} catch (Exception e) {
-				throw new VectoException(string.Format("Field {0}: {1}", column, e.Message), e);
-			}
-		}
-
-		public static bool ParseBoolean(this DataRow row, string columnName)
-		{
-			if (!row.Table.Columns.Contains(columnName)) {
-				throw new KeyNotFoundException(string.Format("Column {0} was not found in DataRow.", columnName));
-			}
-			return row.Field<string>(row.Table.Columns[columnName]).ToBoolean();
-		}
-
-		public static IEnumerable<T> Values<T>(this DataColumn column)
-		{
-			return column.Table.AsEnumerable().Select(r => r.Field<T>(column));
-		}
-	}
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2016 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 System.Collections.Generic;
+using System.Data;
+using System.Globalization;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
+
+namespace TUGraz.VectoCore.Utils
+{
+	public static class DataTableExtensionMethods
+	{
+		public static double ParseDoubleOrGetDefault(this DataRow row, string columnName,
+			double defaultValue = default(double))
+		{
+			if (row.Table.Columns.Contains(columnName)) {
+				double result;
+				if (double.TryParse(row.Field<string>(columnName), NumberStyles.Any, CultureInfo.InvariantCulture, out result)) {
+					return result;
+				}
+			}
+			return defaultValue;
+		}
+
+		public static double ParseDouble(this DataRow row, int columnIndex)
+		{
+			return row.ParseDouble(row.Table.Columns[columnIndex]);
+		}
+
+		public static T SI<T>(this DataRow row, int columnIndex) where T : SIBase<T>
+		{
+			return row.ParseDouble(row.Table.Columns[columnIndex]).SI<T>();
+		}
+
+		public static T SI<T>(this DataRow row, string columnName) where T : SIBase<T>
+		{
+			return row.ParseDouble(columnName).SI<T>();
+		}
+
+		public static double ParseDouble(this DataRow row, string columnName)
+		{
+			if (!row.Table.Columns.Contains(columnName)) {
+				throw new KeyNotFoundException(string.Format("Column {0} was not found in DataRow.", columnName));
+			}
+			return row.ParseDouble(row.Table.Columns[columnName]);
+		}
+
+		public static double ParseDouble(this DataRow row, DataColumn column)
+		{
+			try {
+				return row.Field<string>(column).ToDouble();
+			} catch (IndexOutOfRangeException e) {
+				throw new VectoException(string.Format("Field {0} was not found in DataRow.", column), e);
+			} catch (NullReferenceException e) {
+				throw new VectoException(string.Format("Field {0} must not be null.", column), e);
+			} catch (FormatException e) {
+				throw new VectoException(string.Format("Field {0} is not in a valid number format: {1}", column,
+					row.Field<string>(column)), e);
+			} catch (OverflowException e) {
+				throw new VectoException(string.Format("Field {0} has a value too high or too low: {1}", column,
+					row.Field<string>(column)), e);
+			} catch (ArgumentNullException e) {
+				throw new VectoException(string.Format("Field {0} contains null which cannot be converted to a number.", column),
+					e);
+			} catch (Exception e) {
+				throw new VectoException(string.Format("Field {0}: {1}", column, e.Message), e);
+			}
+		}
+
+		public static bool ParseBoolean(this DataRow row, string columnName)
+		{
+			if (!row.Table.Columns.Contains(columnName)) {
+				throw new KeyNotFoundException(string.Format("Column {0} was not found in DataRow.", columnName));
+			}
+			return row.Field<string>(row.Table.Columns[columnName]).ToBoolean();
+		}
+
+		public static IEnumerable<T> Values<T>(this DataColumn column)
+		{
+			return column.Table.AsEnumerable().Select(r => r.Field<T>(column));
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
index 96344a77f16f41fe558d8abd6244295affd1c6f2..1686fe09d4467ae9610160df0941d4196950dcce 100644
--- a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
@@ -292,7 +292,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 		}
 
 		[TestCase]
-		public void CompueShiftPolygonDeclarationTest()
+		public void ComputeShiftPolygonDeclarationTest()
 		{
 			var engineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
 			var gearboxFile = @"TestData\Components\40t_Long_Haul_Truck.vgbx";
@@ -372,9 +372,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			Assert.AreEqual(0, shiftPolygons.Last().Upshift.Count);
 		}
 
-
 		[TestCase]
-		public void CompueShiftPolygonATDeclarationTest()
+		public void ComputeShiftPolygonATDeclarationTest()
 		{
 			var engineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
 			var gearboxFile = @"TestData\Components\40t_Long_Haul_Truck.vgbx";
@@ -423,7 +422,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 		}
 
 		[TestCase]
-		public void CompueShiftPolygonDeclarationTestConfidentialEngine()
+		public void ComputeShiftPolygonDeclarationTestConfidentialEngine()
 		{
 			//var engineFldFile = @"E:\QUAM\Downloads\EngineFLD\Map_375c_BB1390_modTUG_R49_375c_BB1386.vfld";
 			var engineFldFile = @"E:\QUAM\tmp\scania_fullload_shiftpolygon-test.csv";
@@ -439,7 +438,6 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 
 			var gearboxData = new JSONGearboxDataV6(JSONInputDataFactory.ReadFile(gearboxFile), gearboxFile);
 
-
 			var engineData = new CombustionEngineData() {
 				IdleSpeed = 509.RPMtoRad(),
 			};
@@ -453,7 +451,6 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			}
 			engineData.FullLoadCurves = fullLoadCurves;
 
-
 			var shiftPolygons = new List<ShiftPolygon>();
 			var downshiftTransformed = new List<List<Point>>();
 			var downshiftOrig = new List<List<Point>>();
@@ -508,10 +505,12 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 				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_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,
+			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),
@@ -540,7 +539,6 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			}
 			engineData.FullLoadCurves = fullLoadCurves;
 
-
 			var shiftPolygons = new List<ShiftPolygon>();
 			var downshiftTransformed = new List<List<Point>>();
 			var upshiftOrig = new List<List<Point>>();
@@ -548,7 +546,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 				shiftPolygons.Add(
 					DeclarationData.Gearbox.ComputeShiftPolygon(gearboxData.Type, i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears,
 						engineData, axlegearRatio, rdyn.SI<Meter>())
-					);
+				);
 				List<Point> tmp1, tmp2, tmp3;
 				ComputShiftPolygonPoints(i, fullLoadCurves[(uint)(i + 1)], gearboxData.Gears,
 					engineData, axlegearRatio, rdyn.SI<Meter>(), out tmp1, out tmp2, out tmp3);
@@ -627,5 +625,53 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 
 			downshiftTransformed = new[] { p2p, p6p, p3pExt }.ToList();
 		}
+
+		/// <summary>
+		/// VECTO-517 Shiftpolygon is considered invalid
+		/// </summary>
+		[TestCase]
+		public void ShiftCurve_ShiftPolygon_Validation_Test()
+		{
+			var vgbs = new[] {
+				"-50,685,1537",
+				"550,685,1537",
+				"678,763,1537",
+				"1080,1008,2092",
+				"1200,1081,2092",
+				"1200,1081,2092",
+				"3000,1081,2092"
+			};
+
+			var shiftPolygon =
+				ShiftPolygonReader.Create(
+					VectoCSVFile.ReadStream(
+						InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm]	", vgbs)));
+
+			var results = shiftPolygon.Validate(ExecutionMode.Engineering, GearboxType.MT, false);
+			Assert.IsFalse(results.Any(), string.Join("\n", results.Select(r => r.ErrorMessage)));
+		}
+
+		[
+			TestCase(false, 650, 400),
+			TestCase(true, 400, 500),
+			TestCase(false, 900, 400),
+			TestCase(false, 1200, 400),
+			TestCase(true, 600, 900),
+			TestCase(false, 1000, 900),
+			TestCase(false, 1200, 900),
+			TestCase(true, 300, 1300),
+			TestCase(true, 900, 1300),
+			TestCase(false, 1200, 1250),
+			TestCase(false, 1200, 1600),
+		]
+		public void IsLeftOf_Test(bool result, double speed, double torque)
+		{
+			var segment = Tuple.Create(
+				new ShiftPolygon.ShiftPolygonEntry(550.SI<NewtonMeter>(), 685.RPMtoRad()),
+				new ShiftPolygon.ShiftPolygonEntry(1200.SI<NewtonMeter>(), 1080.RPMtoRad())
+			);
+
+			Assert.AreEqual(result, ShiftPolygon.IsLeftOf(speed.RPMtoRad(), torque.SI<NewtonMeter>(), segment));
+		}
 	}
 }
\ No newline at end of file