diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs
index 72e6c0eb97275baee9c8065ba9011451c4e1c17b..dd915e3fe9cf2085f9319a7029c6c2177e30b294 100644
--- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs
@@ -29,38 +29,38 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.ComponentModel;
-using System.Data;
-using System.Runtime.Serialization;
-using TUGraz.VectoCommon.Utils;
-
-// ReSharper disable InconsistentNaming
-
-namespace TUGraz.VectoCore.Models.Simulation.Data
-{
-	[DesignerCategory("")] // Full qualified attribute needed to disable design view in VisualStudio
-	[Serializable]
-	public class ModalResults : DataTable
-	{
-		public static class ExtendedPropertyNames
-		{
-			public const string Decimals = "decimals";
-			public const string OutputFactor = "outputFactor";
-			public const string ShowUnit = "showUnit";
-		}
-
-		protected ModalResults(SerializationInfo info, StreamingContext context) : base(info, context) {}
-
-		public ModalResults()
-		{
-			foreach (var value in EnumHelper.GetValues<ModalResultField>()) {
-				var col = new DataColumn(value.GetName(), value.GetAttribute().DataType) { Caption = value.GetCaption() };
-				col.ExtendedProperties[ExtendedPropertyNames.Decimals] = value.GetAttribute().Decimals;
-				col.ExtendedProperties[ExtendedPropertyNames.OutputFactor] = value.GetAttribute().OutputFactor;
-				col.ExtendedProperties[ExtendedPropertyNames.ShowUnit] = value.GetAttribute().ShowUnit;
-				Columns.Add(col);
-			}
-		}
-	}
+using System;
+using System.ComponentModel;
+using System.Data;
+using System.Runtime.Serialization;
+using TUGraz.VectoCommon.Utils;
+
+// ReSharper disable InconsistentNaming
+
+namespace TUGraz.VectoCore.Models.Simulation.Data
+{
+	[DesignerCategory("")] // Full qualified attribute needed to disable design view in VisualStudio
+	[Serializable]
+	public class ModalResults : DataTable
+	{
+		public static class ExtendedPropertyNames
+		{
+			public const string Decimals = "decimals";
+			public const string OutputFactor = "outputFactor";
+			public const string ShowUnit = "showUnit";
+		}
+
+		protected ModalResults(SerializationInfo info, StreamingContext context) : base(info, context) {}
+
+		public ModalResults()
+		{
+			foreach (var value in EnumHelper.GetValues<ModalResultField>()) {
+				var col = new DataColumn(value.GetName(), value.GetAttribute().DataType) { Caption = value.GetCaption() };
+				col.ExtendedProperties[ExtendedPropertyNames.Decimals] = value.GetAttribute().Decimals;
+				col.ExtendedProperties[ExtendedPropertyNames.OutputFactor] = value.GetAttribute().OutputFactor;
+				col.ExtendedProperties[ExtendedPropertyNames.ShowUnit] = value.GetAttribute().ShowUnit;
+				Columns.Add(col);
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/ISimulationPreprocessor.cs b/VectoCore/VectoCore/Models/Simulation/ISimulationPreprocessor.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b1470873c879cc1e0ae7550c5601c513c91f6e27
--- /dev/null
+++ b/VectoCore/VectoCore/Models/Simulation/ISimulationPreprocessor.cs
@@ -0,0 +1,8 @@
+using TUGraz.VectoCore.Models.Simulation.Impl;
+
+namespace TUGraz.VectoCore.Models.Simulation {
+	public interface ISimulationPreprocessor
+	{
+		void RunPreprocessing(VectoRun container);
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs
index 38548b02517ba68567e7faa3e4529b03d6656f60..084bf3e5372edea6f3cbef76403d8536496088b9 100644
--- a/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs
+++ b/VectoCore/VectoCore/Models/Simulation/IVehicleContainer.cs
@@ -30,6 +30,7 @@
 */
 
 using System;
+using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Models.Connector.Ports;
@@ -37,6 +38,7 @@ using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.Simulation.DataBus;
 using TUGraz.VectoCore.Models.Simulation.Impl;
 using TUGraz.VectoCore.Models.SimulationComponent;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl;
 using TUGraz.VectoCore.OutputData;
 
 namespace TUGraz.VectoCore.Models.Simulation
@@ -56,6 +58,8 @@ namespace TUGraz.VectoCore.Models.Simulation
 
 		VectoRun.Status RunStatus { get; set; }
 
+		
+
 		/// <summary>
 		/// Adds a component to the vehicle container.
 		/// </summary>
@@ -72,5 +76,10 @@ namespace TUGraz.VectoCore.Models.Simulation
 		/// </summary>
 		/// <param name="exception"></param>
 		void FinishSimulationRun(Exception exception = null);
+
+		void StartSimulationRun();
+
+		IEnumerable<ISimulationPreprocessor> GetPreprocessingRuns { get; }
+		void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor);
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs
index c66eee78a9855d7a5dd3c460e2b1e4ac65416064..7124f6ce7c71e1a3a95622ea19bcdd92513b40b0 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/VectoRun.cs
@@ -106,6 +106,14 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			}
 			var debug = new DebugData();
 
+			Log.Info("VectoJob preprocessing.");
+
+			foreach (var preprocessing in Container.GetPreprocessingRuns) {
+				preprocessing.RunPreprocessing(this);
+			}
+
+
+			Container.StartSimulationRun();
 			Log.Info("VectoJob started running.");
 
 			Container.AbsTime = AbsTime;
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
index 48467a2291bf74ab0e1835cb4c2f9ac2ddba78fb..63b828b6d74bbac1ee080f35f9bcab7a06a99da8 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
@@ -74,6 +74,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 		internal WriteSumData WriteSumData;
 
+		internal readonly IList<ISimulationPreprocessor> Preprocessors = new List<ISimulationPreprocessor>();
+
 		#region IGearCockpit
 
 		public GearboxType GearboxType
@@ -335,6 +337,21 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			DrivingCycle.FinishSimulation();
 		}
 
+		public void StartSimulationRun()
+		{
+			ModData?.Reset();
+		}
+
+		public IEnumerable<ISimulationPreprocessor> GetPreprocessingRuns
+		{
+			get { return new ReadOnlyCollection<ISimulationPreprocessor>(Preprocessors); }
+		}
+
+		public void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor)
+		{
+			Preprocessors.Add(simulationPreprocessor);
+		}
+
 		public void FinishSimulation()
 		{
 			throw new NotImplementedException();
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a06d9d6ee94e5d4eb383472529aade8ca9bcd6d7
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/AMTShiftStrategyV2.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Data;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	public class AMTShiftStrategyV2 : ShiftStrategy
+	{
+		private uint _nextGear;
+
+		public AMTShiftStrategyV2(VectoRunData data, IVehicleContainer dataBus) : base(data.GearboxData, dataBus)
+		{
+			var velocityDropData = new VelocityRollingLookup();
+			dataBus.AddPreprocessor(new VelocitySpeedGearshiftPreprocessor(velocityDropData, data.GearboxData.TractionInterruption));
+		}
+
+		#region Overrides of BaseShiftStrategy
+
+		public override bool ShiftRequired(
+			Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity, NewtonMeter inTorque,
+			PerSecond inAngularVelocity, uint gear, Second lastShiftTime)
+		{
+			throw new System.NotImplementedException();
+
+
+		}
+
+		public override uint InitGear(Second absTime, Second dt, NewtonMeter torque, PerSecond outAngularVelocity)
+		{
+			if (DataBus.VehicleSpeed.IsEqual(0)) {
+				return InitStartGear(torque, outAngularVelocity);
+			}
+
+			for (var gear = (uint)ModelData.Gears.Count; gear > 1; gear--) {
+				var inAngularVelocity = outAngularVelocity * ModelData.Gears[gear].Ratio;
+				if (DataBus.EngineSpeed < inAngularVelocity && inAngularVelocity < DataBus.EngineRatedSpeed) {
+					_nextGear = gear;
+					return gear;
+				}
+			}
+
+			return 1;
+		}
+
+		private uint InitStartGear(NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			return 1;
+		}
+
+		public override uint Engage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outAngularVelocity)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public override void Disengage(Second absTime, Second dt, NewtonMeter outTorque, PerSecond outEngineSpeed)
+		{
+			throw new System.NotImplementedException();
+		}
+
+		public override GearInfo NextGear
+		{
+			get { return new GearInfo(_nextGear, true); }
+		}
+
+		#endregion
+	}
+}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs
index f72c63bad8e106e335a86a1b976f78af19211840..ae2223f9e0620a6b1c695100da53b9f31e2c3ca8 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/Retarder.cs
@@ -91,15 +91,15 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		protected override void DoCommitSimulationStep()
 		{
-			var avgAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0;
+			var avgAngularSpeed = (PreviousState.InAngularVelocity + CurrentState.InAngularVelocity) / 2.0 * _ratio;
 			if (!avgAngularSpeed.IsBetween(_lossMap.MinSpeed, _lossMap.MaxSpeed)) {
 				Log.Warn(
 					"Retarder LossMap data was extrapolated: range for loss map is not sufficient: n:{0} (min:{1}, max:{2}), ratio:{3}",
-					CurrentState.OutAngularVelocity.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio);
+					avgAngularSpeed.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio);
 				if (DataBus.ExecutionMode == ExecutionMode.Declaration) {
 					throw new VectoException(
 						"Retarder LossMap data was extrapolated in Declaration mode: range for loss map is not sufficient: n:{0} (min:{1}, max:{2}), ratio:{3}",
-						CurrentState.OutAngularVelocity.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio);
+						avgAngularSpeed.AsRPM, _lossMap.MinSpeed.AsRPM, _lossMap.MaxSpeed.AsRPM, _ratio);
 				}
 			}
 			base.DoCommitSimulationStep();
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocityRollingLookup.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocityRollingLookup.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4d7090b17d5b63498147c50681995a8a1122dde2
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocityRollingLookup.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
+	public class VelocityRollingLookup : Interpolate2D<MeterPerSecond, Radian, MeterPerSecond,
+		VelocitySpeedGearshiftPreprocessor.Entry>
+	{
+		public VelocitySpeedGearshiftPreprocessor.Entry[] Data
+		{
+			set {
+				Valid = value != null && value.Length > 0;
+				if (Valid) {
+					SetData(value);
+				}
+			}
+		}
+
+		public bool Valid { get; set; }
+
+		#region Overrides of Interpolate2D<MeterPerSecond,Radian,MeterPerSecond,Entry>
+
+		protected override MeterPerSecond GetXValue(VelocitySpeedGearshiftPreprocessor.Entry entry)
+		{
+			return entry.StartVelocity;
+		}
+
+		protected override Radian GetYValue(VelocitySpeedGearshiftPreprocessor.Entry entry)
+		{
+			return entry.Gradient;
+		}
+
+		protected override MeterPerSecond GetZValue(VelocitySpeedGearshiftPreprocessor.Entry entry)
+		{
+			return entry.EndVelocity;
+		}
+
+		protected override IEnumerable<MeterPerSecond> GetXValuesSorted(VelocitySpeedGearshiftPreprocessor.Entry[] entries)
+		{
+			return entries.Select(x => x.StartVelocity).OrderBy(x => x);
+		}
+
+		protected override IEnumerable<Radian> GetYValuesSorted(VelocitySpeedGearshiftPreprocessor.Entry[] entries)
+		{
+			return entries.Select(x => x.Gradient).OrderBy(x => x);
+		}
+
+		#endregion
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs
new file mode 100644
index 0000000000000000000000000000000000000000..d73f14ddb7738fe33f4b13558533f2fefd537024
--- /dev/null
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/VelocitySpeedGearshiftPreprocessor.cs
@@ -0,0 +1,129 @@
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Impl;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl {
+	public class VelocitySpeedGearshiftPreprocessor : ISimulationPreprocessor
+	{
+		protected readonly Second TractionInterruption;
+		private readonly VelocityRollingLookup VehicleVelocityDropLookup;
+
+		public VelocitySpeedGearshiftPreprocessor(VelocityRollingLookup velocityDropData, Second tracktionInterruption, int minGradient = -24, int maxGradient = 24, int gradientStep = 2)
+		{
+			VehicleVelocityDropLookup = velocityDropData;
+			TractionInterruption = tracktionInterruption;
+			MinGradient = minGradient;
+			MaxGradient = maxGradient;
+			GradientStep = gradientStep;
+
+			var speeds = Enumerable.Range(1, 12).Select(x => (x * 10).KMPHtoMeterPerSecond()).ToList();
+			speeds.Insert(0, 5.KMPHtoMeterPerSecond());
+			Speeds = speeds;
+		}
+
+
+		#region Implementation of ISimulationPreprocessor
+
+		public void RunPreprocessing(VectoRun container)
+		{
+			VehicleVelocityDropLookup.Data = IterateVehicleSpeedAndGradient(container);
+		}
+
+		#endregion
+
+		public int MinGradient { get; set; }
+
+		public int MaxGradient { get; set; }
+		public int GradientStep { get; set; }
+
+		protected Entry[] IterateVehicleSpeedAndGradient(VectoRun run)
+		{
+			var container = run.GetContainer() as VehicleContainer;
+			var vehicle = container?.Vehicle as Vehicle;
+
+			if (vehicle == null) {
+				throw new VectoException("no vehicle found...");
+			}
+
+			var modData = container.ModalData as ModalDataContainer;
+
+			var tmp = new List<Entry>();
+			foreach (var speed in Speeds) {
+				for (var grad = MinGradient; grad <= MaxGradient; grad+=GradientStep) {
+					var gradient = VectoMath.InclinationToAngle(grad / 100.0);
+					vehicle.Initialize(speed, gradient);
+					(container.Gearbox as Gearbox).Gear = 0;
+					var vehicleSpeed = SimulateRollingVehicle(vehicle, gradient, container);
+					modData?.Reset();
+					tmp.Add(new Entry() { StartVelocity = speed, Gradient = gradient, EndVelocity = vehicleSpeed });
+				}
+			}
+
+			return tmp.ToArray();
+		}
+
+		public IList<MeterPerSecond> Speeds { get; }
+
+		protected MeterPerSecond SimulateRollingVehicle(
+			Vehicle vehicle, Radian gradient, IVehicleContainer container)
+		{
+			var simulationInterval = Constants.SimulationSettings.TargetTimeInterval;
+			
+			var acceleration = 0.SI<MeterPerSquareSecond>();
+			var absTime = 0.SI<Second>();
+			while (absTime < TractionInterruption) {
+				var initialResponse = vehicle.Request(absTime, simulationInterval, acceleration, gradient);
+				var delta = initialResponse.GearboxPowerRequest;
+				try {
+					var time = absTime;
+					acceleration = SearchAlgorithm.Search(
+						acceleration, delta, Constants.SimulationSettings.OperatingPointInitialSearchIntervalAccelerating,
+						getYValue: response => {
+							var r = (ResponseDryRun)response;
+							return r.GearboxPowerRequest;
+						},
+						evaluateFunction: acc => {
+							var response = vehicle.Request(time, simulationInterval, acc, gradient, true);
+							response.Acceleration = acc;
+							return response;
+						},
+						criterion: response => {
+							var r = (ResponseDryRun)response;
+							return r.GearboxPowerRequest.Value();
+						},
+						abortCriterion: (response, cnt) => {
+							var r = (ResponseDryRun)response;
+							return r != null && (vehicle.VehicleSpeed + r.Acceleration * simulationInterval) < 0.KMPHtoMeterPerSecond();
+						}
+					);
+					var step = vehicle.Request(absTime, simulationInterval, acceleration, gradient);
+					if (!(step is ResponseSuccess)) {
+						throw new VectoSimulationException("failed to find acceleration for rolling");
+					}
+
+					absTime += simulationInterval;
+				} catch (VectoSearchAbortedException) {
+					return 0.KMPHtoMeterPerSecond();
+				}
+
+				container.CommitSimulationStep(absTime, simulationInterval);
+			}
+
+			return vehicle.VehicleSpeed;
+		}
+
+		public class Entry
+		{
+			public MeterPerSecond StartVelocity;
+			public Radian Gradient;
+			public MeterPerSecond EndVelocity;
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
index f3c087df64d22f40d70a59fd3dd6b046a72cf324..b1ea488551199e30ce072675687a110ba74c3835 100644
--- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
@@ -102,6 +102,8 @@ namespace TUGraz.VectoCore.OutputData
 		/// called after the simulation is finished and the sum-entries have been written
 		/// </summary>
 		void FinishSimulation();
+
+		void Reset();
 	}
 
 	public static class ModalDataContainerExtensions
diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs
index d089ff8e198a48929c4eeacf0ada344476845dfe..52e8001005b810438ec826091f85499cf3389f2f 100644
--- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs
@@ -112,6 +112,11 @@ namespace TUGraz.VectoCore.OutputData
 			WriteAdvancedAux = false;
 		}
 
+		public void Reset()
+		{
+			Data.Rows.Clear();
+			CurrentRow = Data.NewRow();
+		}
 
 		public bool HasTorqueConverter { get; set; }
 
diff --git a/VectoCore/VectoCore/Utils/Interpolate2D.cs b/VectoCore/VectoCore/Utils/Interpolate2D.cs
new file mode 100644
index 0000000000000000000000000000000000000000..5f12027e4a705e573193772984ed2bc320b1a37e
--- /dev/null
+++ b/VectoCore/VectoCore/Utils/Interpolate2D.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using TUGraz.VectoCommon.Utils;
+
+namespace TUGraz.VectoCore.Utils
+{
+	public abstract class Interpolate2D<TKeyX, TKeyY, TValZ, TEntry>
+		where TKeyX : SI
+		where TKeyY : SI
+		where TValZ : SIBase<TValZ>
+	{
+		private DataTable _data;
+
+		private KeyValuePair<TKeyX, int>[] entriesX;
+		private KeyValuePair<TKeyY, int>[] entriesY;
+
+		protected void SetData(TEntry[] entries)
+		{
+			_data = new DataTable();
+			var xEntries = new List<KeyValuePair<TKeyX, int>>();
+			var idx = 0;
+			foreach (var xValue in GetXValuesSorted(entries).Distinct()) {
+				_data.Columns.Add(xValue.ToOutputFormat(), typeof(TKeyX));
+				xEntries.Add(new KeyValuePair<TKeyX, int>(xValue, idx++));
+			}
+
+			entriesX = xEntries.OrderBy(x => x.Key).ToArray();
+
+			idx = 0;
+			var yEntries = new List<KeyValuePair<TKeyY, int>>();
+			foreach (var yValue in GetYValuesSorted(entries).Distinct()) {
+				var row = _data.NewRow();
+				_data.Rows.Add(row);
+				yEntries.Add(new KeyValuePair<TKeyY, int>(yValue, idx++));
+			}
+
+			entriesY = yEntries.OrderBy(x => x.Key).ToArray();
+
+			foreach (var entry in entries) {
+				var col = entriesX.First(x => x.Key.IsEqual(GetXValue(entry)));
+				var row = entriesY.First(x => x.Key.IsEqual(GetYValue(entry)));
+				_data.Rows[row.Value][col.Value] = GetZValue(entry);
+			}
+		}
+
+		protected abstract TKeyX GetXValue(TEntry entry);
+
+		protected abstract TKeyY GetYValue(TEntry entry);
+
+		protected abstract TValZ GetZValue(TEntry entry);
+		
+		protected abstract IEnumerable<TKeyX> GetXValuesSorted(TEntry[] entries);
+
+		protected abstract IEnumerable<TKeyY> GetYValuesSorted(TEntry[] entries);
+
+
+		public TValZ Interpolate(TKeyX valX, TKeyY valY)
+		{
+			var speedIdx = -1;
+			for (var i = 0; i < entriesX.Length; i++) {
+				if (entriesX[i].Key.CompareTo(valX) >= 0) {
+					speedIdx = i;
+					break;
+				}
+			}
+
+			var gradientIdx = -1;
+			for (var i = 0; i < entriesY.Length; i++) {
+				if (entriesY[i].Key.CompareTo(valY) >= 0) {
+					gradientIdx = i;
+					break;
+				}
+			}
+
+			var v1 = _data.Rows[entriesY[gradientIdx - 1].Value][entriesX[speedIdx - 1].Value] as TValZ;
+			var v2 = _data.Rows[entriesY[gradientIdx - 1].Value][entriesX[speedIdx].Value] as TValZ;
+			var v3 = _data.Rows[entriesY[gradientIdx].Value][entriesX[speedIdx - 1].Value] as TValZ;
+			var v4 = _data.Rows[entriesY[gradientIdx].Value][entriesX[speedIdx].Value] as TValZ;
+			var speed1 = VectoMath.Interpolate(entriesX[speedIdx - 1].Key, entriesX[speedIdx].Key, v1, v2, valX);
+			var speed2 = VectoMath.Interpolate(entriesX[speedIdx - 1].Key, entriesX[speedIdx].Key, v3, v4, valX);
+
+			return VectoMath.Interpolate(
+				entriesY[gradientIdx - 1].Key, entriesY[gradientIdx].Key, speed1, speed2, valY);
+		}
+	}
+}
diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj
index 9d297de84f79077a83d9ce41eb3588fcb21d674b..fa0105351100d5e92cc8020092c99fa84e6171ad 100644
--- a/VectoCore/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore/VectoCore.csproj
@@ -179,6 +179,7 @@
     <Compile Include="Models\SimulationComponent\ILossMap.cs" />
     <Compile Include="Models\SimulationComponent\Data\PTOLossMap.cs" />
     <Compile Include="Models\SimulationComponent\Impl\AbstractGearbox.cs" />
+    <Compile Include="Models\SimulationComponent\Impl\AMTShiftStrategyV2.cs" />
     <Compile Include="Models\SimulationComponent\Impl\ATGearbox.cs" />
     <Compile Include="Models\SimulationComponent\Impl\ATShiftStrategy.cs" />
     <Compile Include="Models\SimulationComponent\Impl\BaseShiftStrategy.cs" />
@@ -186,6 +187,8 @@
     <Compile Include="Models\SimulationComponent\Impl\DrivingCycleEnumerator.cs" />
     <Compile Include="Models\SimulationComponent\Impl\EngineFanAuxiliary.cs" />
     <Compile Include="Models\SimulationComponent\Impl\TorqueConverterWrapper.cs" />
+    <Compile Include="Models\SimulationComponent\Impl\VelocityRollingLookup.cs" />
+    <Compile Include="Models\SimulationComponent\Impl\VelocitySpeedGearshiftPreprocessor.cs" />
     <Compile Include="Models\SimulationComponent\Impl\VTPCombustionEngine.cs" />
     <Compile Include="Models\SimulationComponent\Impl\MeasuredSpeedDrivingCycle.cs" />
     <Compile Include="Models\SimulationComponent\Impl\PTOCycleController.cs" />
@@ -196,6 +199,7 @@
     <Compile Include="Models\Simulation\Data\ModalResultField.cs" />
     <Compile Include="InputData\Reader\Impl\EngineeringVTPModeVectoRunDataFactory.cs" />
     <Compile Include="Models\SimulationComponent\Impl\VTPCycle.cs" />
+    <Compile Include="Models\Simulation\ISimulationPreprocessor.cs" />
     <Compile Include="OutputData\XML\XMLVTPReport.cs" />
     <Compile Include="OutputData\VTPReport.cs" />
     <Compile Include="OutputData\ModFilter\ActualModalDataFilter.cs" />
@@ -207,6 +211,7 @@
     <Compile Include="OutputData\XML\XMLDeclarationWriter.cs" />
     <Compile Include="OutputData\XML\XMLEngineeringWriter.cs" />
     <Compile Include="OutputData\XML\XMLManufacturerReport.cs" />
+    <Compile Include="Utils\Interpolate2D.cs" />
     <Compile Include="Utils\ProviderExtensions.cs" />
     <Compile Include="Models\Declaration\AirDrag.cs" />
     <Compile Include="Models\Declaration\Fan.cs" />
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs
index b946802f98896242b493f575aa144c442f64c5fd..59c7cdf426e5a309ce43cfdfd38be27522fcae21 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/LossMapRangeValidationTest.cs
@@ -34,33 +34,33 @@ using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.IO;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.InputData.FileIO.JSON;
-using TUGraz.VectoCore.InputData.Reader;
-using TUGraz.VectoCore.InputData.Reader.ComponentData;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.Impl;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
-using TUGraz.VectoCore.OutputData.FileIO;
-using TUGraz.VectoCore.Tests.Utils;
-
-namespace TUGraz.VectoCore.Tests.Models.Simulation
-{
-	[TestFixture]
-	public class LossMapRangeValidationTest
-	{
-		public const string ShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs";
-		public const string AccelerationFile = @"TestData\Components\Truck.vacc";
-		public const string EngineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
-		public const string AxleGearLossMap = @"TestData\Components\Axle 40t Truck.vtlm";
-		public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm";
-		public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm";
-		public const string GearboxLimited = @"TestData\Components\limited.vtlm";
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData.FileIO.JSON;
+using TUGraz.VectoCore.InputData.Reader;
+using TUGraz.VectoCore.InputData.Reader.ComponentData;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.Impl;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.OutputData.FileIO;
+using TUGraz.VectoCore.Tests.Utils;
+
+namespace TUGraz.VectoCore.Tests.Models.Simulation
+{
+	[TestFixture]
+	public class LossMapRangeValidationTest
+	{
+		public const string ShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs";
+		public const string AccelerationFile = @"TestData\Components\Truck.vacc";
+		public const string EngineFile = @"TestData\Components\40t_Long_Haul_Truck.veng";
+		public const string AxleGearLossMap = @"TestData\Components\Axle 40t Truck.vtlm";
+		public const string GearboxIndirectLoss = @"TestData\Components\Indirect Gear.vtlm";
+		public const string GearboxDirectLoss = @"TestData\Components\Direct Gear.vtlm";
+		public const string GearboxLimited = @"TestData\Components\limited.vtlm";
 		public const string GearboxShiftPolygonFile = @"TestData\Components\ShiftPolygons.vgbs";
 		//public const string GearboxFullLoadCurveFile = @"TestData\Components\Gearbox.vfld";
 
@@ -71,241 +71,241 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 			Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
 		}
 
-		/// <summary>
-		/// VECTO-173
-		/// </summary>
-		[TestCase]
-		public void LossMapValid()
-		{
-			var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss);
-			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
-			var axleGearData = CreateAxleGearData(AxleGearLossMap);
-			var vehicleData = new VehicleData {
-				DynamicTyreRadius = 0.85.SI<Meter>(),
-				Loading = 0.SI<Kilogram>(),
-				CurbWeight = 2000.SI<Kilogram>(),
-				AxleData =
-					new List<Axle> {
-						new Axle {
-							TwinTyres = false,
-							AxleWeightShare = 1,
-							TyreTestLoad = 50000.SI<Newton>(),
-							Inertia = 10.SI<KilogramSquareMeter>()
-						}
-					}
-			};
-
-			var runData = new VectoRunData {
-				GearboxData = gearboxData,
-				EngineData = engineData,
-				AxleGearData = axleGearData,
-				VehicleData = vehicleData,
-				Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() }
-			};
-
-			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
-			Assert.IsTrue(ValidationResult.Success == result);
-			Assert.IsFalse(runData.IsValid());
-		}
-
-		/// <summary>
-		/// VECTO-173
-		/// </summary>
-		[TestCase]
-		public void LossMapInvalidAxle()
-		{
-			var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss);
-			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
-			var axleGearData = CreateAxleGearData(GearboxLimited);
-
-			var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData };
-			Assert.IsFalse(runData.IsValid());
-		}
-
-		/// <summary>
-		/// VECTO-173
-		/// </summary>
-		[TestCase]
-		public void LossMapLimited()
-		{
-			var gearboxData = CreateGearboxData(GearboxLimited, GearboxLimited);
-			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
-			var axleGearData = CreateAxleGearData(AxleGearLossMap);
-			var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData };
-			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
-			Assert.IsFalse(ValidationResult.Success == result);
-		}
-
-		/// <summary>
-		/// VECTO-173
-		/// </summary>
-		[TestCase]
-		public void LossMapAxleLossMapMissing()
-		{
-			var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss);
-			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
-			var vehicleData = new VehicleData {
-				DynamicTyreRadius = 0.85.SI<Meter>(),
-				Loading = 0.SI<Kilogram>(),
-				CurbWeight = 2000.SI<Kilogram>(),
-				AxleData =
-					new List<Axle> {
-						new Axle {
-							TwinTyres = false,
-							AxleWeightShare = 1,
-							TyreTestLoad = 50000.SI<Newton>(),
-							Inertia = 10.SI<KilogramSquareMeter>()
-						}
-					}
-			};
-			var runData = new VectoRunData {
-				GearboxData = gearboxData,
-				EngineData = engineData,
-				VehicleData = vehicleData,
-				Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() }
-			};
-			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
-			Assert.IsTrue(ValidationResult.Success == result);
-			Assert.IsFalse(runData.IsValid());
-		}
-
-		/// <summary>
-		/// VECTO-173
-		/// </summary>
-		[TestCase]
-		public void LossMapGearLossMapMissing()
-		{
-			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 0);
-			var axleGearData = CreateAxleGearData(AxleGearLossMap);
-
-			var runData = new VectoRunData {
-				EngineData = engineData,
-				AxleGearData = axleGearData,
-				Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() }
-			};
-			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
-			Assert.IsTrue(ValidationResult.Success == result);
-			Assert.IsFalse(runData.IsValid());
-		}
-
-		private static GearboxData CreateGearboxData(string directlossMap, string indirectLossMap)
-		{
-			var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 };
-			return new GearboxData {
-				Gears = ratios.Select((ratio, i) =>
-					Tuple.Create((uint)i,
-						new GearData {
-//								MaxTorque = 2300.SI<NewtonMeter>(),
-							LossMap = TransmissionLossMapReader.ReadFromFile(!ratio.IsEqual(1.0) ? directlossMap : indirectLossMap, ratio,
-								string.Format("Gear {0}", i)),
-							Ratio = ratio,
-							ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile)
-						}))
-					.ToDictionary(k => k.Item1 + 1, v => v.Item2)
-			};
-		}
-
-		private static AxleGearData CreateAxleGearData(string lossMap)
-		{
-			const double ratio = 2.59;
-			return new AxleGearData {
-				AxleGear = new GearData {
-					Ratio = ratio,
-					LossMap = TransmissionLossMapReader.ReadFromFile(lossMap, ratio, "AxleGear")
-				}
-			};
-		}
-
-		/// <summary>
-		/// VECTO-230
-		/// </summary>
-		[TestCase]
-		public void TestLossMapValuesWithEfficiency()
-		{
-			var lossMap = TransmissionLossMapReader.Create(0.95, 1.0, "Dummy");
-
-			AssertHelper.AreRelativeEqual(0.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(0.RPMtoRad(), 0.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(1000.RPMtoRad(), 950.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(40.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(1000.RPMtoRad(), 760.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(1000.RPMtoRad(), 475.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(1000.RPMtoRad(), 95.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(500.RPMtoRad(), 950.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(500.RPMtoRad(), 475.SI<NewtonMeter>()).Value);
-
-			AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(),
-				lossMap.GetTorqueLoss(100.RPMtoRad(), 95.SI<NewtonMeter>()).Value);
-		}
-
-		/// <summary>
-		/// VECTO-230
-		/// </summary>
-		[TestCase]
-		public void CreateJobWithLossMapEfficiency_Engineering()
-		{
-			var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto");
-			var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, null);
-			var jobContainer = new JobContainer(null);
-			jobContainer.AddRuns(runsFactory);
-		}
-
-		/// <summary>
-		/// VECTO-230
-		/// </summary>
-		[TestCase]
-		public void RunJobWithLossMapEfficiency_Engineering()
-		{
-			const string jobFileName = @"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto";
-			var fileWriter = new FileOutputWriter(jobFileName);
-
-			var dataProvider = JSONInputDataFactory.ReadJsonJob(jobFileName);
-			var factory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, fileWriter);
-			var jobContainer = new JobContainer(new MockSumWriter());
-			jobContainer.AddRuns(factory);
-			jobContainer.Execute();
-			jobContainer.WaitFinished();
-
-			foreach (var r in jobContainer.Runs) {
-				Assert.IsTrue(r.Run.FinishedWithoutErrors, string.Format("{0}", r.ExecException));
-			}
-		}
-
-		/// <summary>
-		/// VECTO-230
-		/// </summary>
-		[TestCase]
-		public void CreateJobWith_Axle_LossMapEfficiency_Declaration()
-		{
-			var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with AxleEfficiency.vecto");
-			var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null);
-			var jobContainer = new JobContainer(null);
-
-			AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory));
-		}
-
-		/// <summary>
-		/// VECTO-230
-		/// </summary>
-		[TestCase]
-		public void CreateJobWith_Gear_LossMapEfficiency_Declaration()
-		{
-			var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with GearEfficiency.vecto");
-			var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null);
-			var jobContainer = new JobContainer(null);
-
-			AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory));
-		}
-	}
+		/// <summary>
+		/// VECTO-173
+		/// </summary>
+		[TestCase]
+		public void LossMapValid()
+		{
+			var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss);
+			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
+			var axleGearData = CreateAxleGearData(AxleGearLossMap);
+			var vehicleData = new VehicleData {
+				DynamicTyreRadius = 0.85.SI<Meter>(),
+				Loading = 0.SI<Kilogram>(),
+				CurbWeight = 2000.SI<Kilogram>(),
+				AxleData =
+					new List<Axle> {
+						new Axle {
+							TwinTyres = false,
+							AxleWeightShare = 1,
+							TyreTestLoad = 50000.SI<Newton>(),
+							Inertia = 10.SI<KilogramSquareMeter>()
+						}
+					}
+			};
+
+			var runData = new VectoRunData {
+				GearboxData = gearboxData,
+				EngineData = engineData,
+				AxleGearData = axleGearData,
+				VehicleData = vehicleData,
+				Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() }
+			};
+
+			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
+			Assert.IsTrue(ValidationResult.Success == result);
+			Assert.IsFalse(runData.IsValid());
+		}
+
+		/// <summary>
+		/// VECTO-173
+		/// </summary>
+		[TestCase]
+		public void LossMapInvalidAxle()
+		{
+			var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss);
+			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
+			var axleGearData = CreateAxleGearData(GearboxLimited);
+
+			var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData };
+			Assert.IsFalse(runData.IsValid());
+		}
+
+		/// <summary>
+		/// VECTO-173
+		/// </summary>
+		[TestCase]
+		public void LossMapLimited()
+		{
+			var gearboxData = CreateGearboxData(GearboxLimited, GearboxLimited);
+			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
+			var axleGearData = CreateAxleGearData(AxleGearLossMap);
+			var runData = new VectoRunData { GearboxData = gearboxData, EngineData = engineData, AxleGearData = axleGearData };
+			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
+			Assert.IsFalse(ValidationResult.Success == result);
+		}
+
+		/// <summary>
+		/// VECTO-173
+		/// </summary>
+		[TestCase]
+		public void LossMapAxleLossMapMissing()
+		{
+			var gearboxData = CreateGearboxData(GearboxDirectLoss, GearboxIndirectLoss);
+			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, gearboxData.Gears.Count);
+			var vehicleData = new VehicleData {
+				DynamicTyreRadius = 0.85.SI<Meter>(),
+				Loading = 0.SI<Kilogram>(),
+				CurbWeight = 2000.SI<Kilogram>(),
+				AxleData =
+					new List<Axle> {
+						new Axle {
+							TwinTyres = false,
+							AxleWeightShare = 1,
+							TyreTestLoad = 50000.SI<Newton>(),
+							Inertia = 10.SI<KilogramSquareMeter>()
+						}
+					}
+			};
+			var runData = new VectoRunData {
+				GearboxData = gearboxData,
+				EngineData = engineData,
+				VehicleData = vehicleData,
+				Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() }
+			};
+			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
+			Assert.IsTrue(ValidationResult.Success == result);
+			Assert.IsFalse(runData.IsValid());
+		}
+
+		/// <summary>
+		/// VECTO-173
+		/// </summary>
+		[TestCase]
+		public void LossMapGearLossMapMissing()
+		{
+			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(EngineFile, 0);
+			var axleGearData = CreateAxleGearData(AxleGearLossMap);
+
+			var runData = new VectoRunData {
+				EngineData = engineData,
+				AxleGearData = axleGearData,
+				Cycle = new DrivingCycleData { Entries = new List<DrivingCycleData.DrivingCycleEntry>() }
+			};
+			var result = VectoRunData.ValidateRunData(runData, new ValidationContext(runData));
+			Assert.IsTrue(ValidationResult.Success == result);
+			Assert.IsFalse(runData.IsValid());
+		}
+
+		private static GearboxData CreateGearboxData(string directlossMap, string indirectLossMap)
+		{
+			var ratios = new[] { 14.93, 11.64, 9.02, 7.04, 5.64, 4.4, 3.39, 2.65, 2.05, 1.6, 1.28, 1.0 };
+			return new GearboxData {
+				Gears = ratios.Select((ratio, i) =>
+					Tuple.Create((uint)i,
+						new GearData {
+//								MaxTorque = 2300.SI<NewtonMeter>(),
+							LossMap = TransmissionLossMapReader.ReadFromFile(!ratio.IsEqual(1.0) ? directlossMap : indirectLossMap, ratio,
+								string.Format("Gear {0}", i)),
+							Ratio = ratio,
+							ShiftPolygon = ShiftPolygonReader.ReadFromFile(ShiftPolygonFile)
+						}))
+					.ToDictionary(k => k.Item1 + 1, v => v.Item2)
+			};
+		}
+
+		private static AxleGearData CreateAxleGearData(string lossMap)
+		{
+			const double ratio = 2.59;
+			return new AxleGearData {
+				AxleGear = new GearData {
+					Ratio = ratio,
+					LossMap = TransmissionLossMapReader.ReadFromFile(lossMap, ratio, "AxleGear")
+				}
+			};
+		}
+
+		/// <summary>
+		/// VECTO-230
+		/// </summary>
+		[TestCase]
+		public void TestLossMapValuesWithEfficiency()
+		{
+			var lossMap = TransmissionLossMapReader.Create(0.95, 1.0, "Dummy");
+
+			AssertHelper.AreRelativeEqual(0.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(0.RPMtoRad(), 0.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(1000.RPMtoRad(), 950.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(40.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(1000.RPMtoRad(), 760.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(1000.RPMtoRad(), 475.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(1000.RPMtoRad(), 95.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(50.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(500.RPMtoRad(), 950.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(25.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(500.RPMtoRad(), 475.SI<NewtonMeter>()).Value);
+
+			AssertHelper.AreRelativeEqual(5.SI<NewtonMeter>(),
+				lossMap.GetTorqueLoss(100.RPMtoRad(), 95.SI<NewtonMeter>()).Value);
+		}
+
+		/// <summary>
+		/// VECTO-230
+		/// </summary>
+		[TestCase]
+		public void CreateJobWithLossMapEfficiency_Engineering()
+		{
+			var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto");
+			var runsFactory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, null);
+			var jobContainer = new JobContainer(null);
+			jobContainer.AddRuns(runsFactory);
+		}
+
+		/// <summary>
+		/// VECTO-230
+		/// </summary>
+		[TestCase]
+		public void RunJobWithLossMapEfficiency_Engineering()
+		{
+			const string jobFileName = @"TestData\Jobs\12t Delivery Truck Engineering Efficiency.vecto";
+			var fileWriter = new FileOutputWriter(jobFileName);
+
+			var dataProvider = JSONInputDataFactory.ReadJsonJob(jobFileName);
+			var factory = new SimulatorFactory(ExecutionMode.Engineering, dataProvider, fileWriter);
+			var jobContainer = new JobContainer(new MockSumWriter());
+			jobContainer.AddRuns(factory);
+			jobContainer.Execute();
+			jobContainer.WaitFinished();
+
+			foreach (var r in jobContainer.Runs) {
+				Assert.IsTrue(r.Run.FinishedWithoutErrors, string.Format("{0}", r.ExecException));
+			}
+		}
+
+		/// <summary>
+		/// VECTO-230
+		/// </summary>
+		[TestCase]
+		public void CreateJobWith_Axle_LossMapEfficiency_Declaration()
+		{
+			var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with AxleEfficiency.vecto");
+			var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null);
+			var jobContainer = new JobContainer(null);
+
+			AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory));
+		}
+
+		/// <summary>
+		/// VECTO-230
+		/// </summary>
+		[TestCase]
+		public void CreateJobWith_Gear_LossMapEfficiency_Declaration()
+		{
+			var dataProvider = JSONInputDataFactory.ReadJsonJob(@"TestData\Jobs\40t_Long_Haul_Truck with GearEfficiency.vecto");
+			var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, null);
+			var jobContainer = new JobContainer(null);
+
+			AssertHelper.Exception<InvalidFileFormatException>(() => jobContainer.AddRuns(runsFactory));
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs b/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..ce61f93576fc17e3f65ca61ce1b7c163c3d5901b
--- /dev/null
+++ b/VectoCore/VectoCoreTest/Models/Simulation/SimulationPreprocessingTest.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using NUnit.Framework;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.FileIO.JSON;
+using TUGraz.VectoCore.InputData.FileIO.XML.Declaration;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Impl;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.OutputData.FileIO;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Tests.Models.Simulation
+{
+	[TestFixture]
+	public class SimulationPreprocessingTest
+	{
+
+		public const string Class9Decl =
+			@"TestData\Generic Vehicles\Declaration Mode\Class9_RigidTruck_6x2\Class9_RigidTruck_DECL.vecto";
+
+		[OneTimeSetUp]
+		public void RunBeforeAnyTests()
+		{
+			Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
+		}
+
+		[TestCase(Class9Decl, 20, 2, 19.04812),
+		 TestCase(Class9Decl, 20, 3, 18.71013),
+		 TestCase(Class9Decl, 20, 2.5, 18.87913),
+		 TestCase(Class9Decl, 25, 0, 24.71184),
+		 TestCase(Class9Decl, 25, 1, 24.3735),
+		 TestCase(Class9Decl, 25, 0.5, 24.5427),
+		 TestCase(Class9Decl, 87, -4, 87.6266),
+		 TestCase(Class9Decl, 87, -5, 87.9629),
+		 TestCase(Class9Decl, 87, -4.65, 87.84524)
+			]
+		public void TestSimulationPreprocessing(string jobFile, double vPre, double grad, double vPost)
+		{
+			var fileWriter = new FileOutputWriter(jobFile);
+			var sumWriter = new SummaryDataContainer(fileWriter);
+			var jobContainer = new JobContainer(sumWriter);
+			var dataProvider =  JSONInputDataFactory.ReadJsonJob(jobFile);
+			var runsFactory = new SimulatorFactory(ExecutionMode.Declaration, dataProvider, fileWriter) {
+				ModalResults1Hz = false,
+				WriteModalResults = true,
+				ActualModalData = false,
+				Validate = false,
+			};
+
+			jobContainer.AddRuns(runsFactory);
+
+			
+			var i = 0;
+			//jobContainer.Runs[i].Run.Run();
+			
+			var lookup = SimulationRunPreprocessing(jobContainer.Runs[i].Run);
+
+			var velocityDrop = lookup.Interpolate(vPre.KMPHtoMeterPerSecond(), VectoMath.InclinationToAngle(grad / 100.0));
+			Assert.AreEqual(vPost, velocityDrop.AsKmph, 1e-3);
+
+
+			//var rnd = new Random(99);
+			//var t = Stopwatch.StartNew();
+			//for (var j = 0; j < 100000; j++) {
+			//	var vEnd = lookup.Interpolate(
+			//		(5 + rnd.NextDouble() * 110).KMPHtoMeterPerSecond(),
+			//		VectoMath.InclinationToAngle((rnd.NextDouble() * 20 - 10) / 100.0));
+			//}
+			//t.Stop();
+			//Console.WriteLine(t.ElapsedMilliseconds);
+
+		}
+
+
+		protected virtual VelocityRollingLookup SimulationRunPreprocessing(IVectoRun run)
+		{
+			var tmp = new VelocityRollingLookup();
+			var preprocessor = new VelocitySpeedGearshiftPreprocessor(tmp, 1.SI<Second>(), minGradient: -12, maxGradient: 12);
+			var t = Stopwatch.StartNew();
+
+			preprocessor.RunPreprocessing(run as VectoRun);
+			t.Stop();
+			//Console.WriteLine(t.ElapsedMilliseconds);
+
+			t = Stopwatch.StartNew();
+			t.Stop();
+			//Console.WriteLine(t.ElapsedMilliseconds);
+
+			return tmp;
+		}
+
+	}
+}
diff --git a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs
index 1629bf64d7612829b97f7b37e310b185abb66dd2..0043cdba5b4ad366759f08275d3c30e6fae74abc 100644
--- a/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockModalDataContainer.cs
@@ -96,6 +96,8 @@ namespace TUGraz.VectoCore.Tests.Utils
 		}
 
 		public void Finish(VectoRun.Status runStatus, Exception exception = null) {}
+		public void Reset()
+		{ }
 
 		public bool WriteModalResults { get; set; }
 
diff --git a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
index df365a62f56c98810aa04bd6a0fff5cdfa6acca1..89c3b8cb8283d86e767610dd315c2f082c6d34c0 100644
--- a/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockVehicleContainer.cs
@@ -219,6 +219,14 @@ namespace TUGraz.VectoCore.Tests.Utils
 		public void FinishSimulation() {}
 
 		public void FinishSimulationRun(Exception e) {}
+		public void StartSimulationRun()
+		{ }
+
+		public IEnumerable<ISimulationPreprocessor> GetPreprocessingRuns { get { return new ISimulationPreprocessor[] { }; } }
+		public void AddPreprocessor(ISimulationPreprocessor simulationPreprocessor)
+		{
+			throw new NotImplementedException();
+		}
 
 		public Watt SetAxlegearLoss
 		{
diff --git a/VectoCore/VectoCoreTest/VectoCoreTest.csproj b/VectoCore/VectoCoreTest/VectoCoreTest.csproj
index aa3df9078678da8149c27d7c908ac70efad5f438..a97a3edacd070695097c0eec811aa1260ebcee41 100644
--- a/VectoCore/VectoCoreTest/VectoCoreTest.csproj
+++ b/VectoCore/VectoCoreTest/VectoCoreTest.csproj
@@ -114,6 +114,7 @@
     <Compile Include="Models\Simulation\MockSumWriter.cs" />
     <Compile Include="Models\Simulation\GetSectionTest.cs" />
     <Compile Include="Models\Simulation\DeclarationSimulationFactoryTest.cs" />
+    <Compile Include="Models\Simulation\SimulationPreprocessingTest.cs" />
     <Compile Include="Reports\ActualModalSimulationDataTest.cs" />
     <Compile Include="Reports\GearshiftCountTest.cs" />
     <Compile Include="Reports\ModDataTest.cs" />