diff --git a/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs b/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs
index 9b6a591478ab7b9a820df9e5c3d2a4448e2b7c4a..0f0b1ab619c4d6a7cc2e086cb044d4882a116b17 100644
--- a/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs
+++ b/VectoCore/FileIO/Reader/DataObjectAdaper/DeclarationDataAdapter.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using TUGraz.VectoCore.Configuration;
@@ -181,22 +180,25 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
 			retVal.HasTorqueConverter = false;
 
 			var axleGear = gearbox.Body.Gears.First();
-			var lossMap = TransmissionLossMap.ReadFromFile(Path.Combine(gearbox.BasePath, axleGear.LossMap), axleGear.Ratio);
-			retVal.AxleGearData = new GearData { LossMap = lossMap, Ratio = axleGear.Ratio };
+			var axleLossMap = TransmissionLossMap.ReadFromFile(Path.Combine(gearbox.BasePath, axleGear.LossMap), axleGear.Ratio);
+			retVal.AxleGearData = new GearData { LossMap = axleLossMap, Ratio = axleGear.Ratio, TorqueConverterActive = false };
 
 			retVal.Gears = gearbox.Body.Gears.Skip(1).Select((gear, i) => {
-				lossMap = TransmissionLossMap.ReadFromFile(Path.Combine(gearbox.BasePath, gear.LossMap), gear.Ratio);
-				EngineFullLoadCurve fullLoadCurve;
-				if (string.IsNullOrWhiteSpace(gear.FullLoadCurve) || gear.FullLoadCurve == "<NOFILE>") {
-					fullLoadCurve = engine.FullLoadCurve;
-				} else {
-					var gearFullLoad = FullLoadCurve.ReadFromFile(Path.Combine(gearbox.BasePath, gear.FullLoadCurve));
-					fullLoadCurve = IntersectFullLoadCurves(gearFullLoad, engine.FullLoadCurve);
-				}
+				var gearLossMap = TransmissionLossMap.ReadFromFile(Path.Combine(gearbox.BasePath, gear.LossMap), gear.Ratio);
+				var gearFullLoad = (string.IsNullOrWhiteSpace(gear.FullLoadCurve) || gear.FullLoadCurve == "<NOFILE>")
+					? engine.FullLoadCurve
+					: FullLoadCurve.ReadFromFile(Path.Combine(gearbox.BasePath, gear.FullLoadCurve));
 
+				var fullLoadCurve = IntersectFullLoadCurves(gearFullLoad, engine.FullLoadCurve);
 				var shiftPolygon = DeclarationData.Gearbox.ComputeShiftPolygon(fullLoadCurve, engine.IdleSpeed);
 				return new KeyValuePair<uint, GearData>((uint)i + 1,
-					new GearData { LossMap = lossMap, ShiftPolygon = shiftPolygon, Ratio = gear.Ratio });
+					new GearData {
+						LossMap = gearLossMap,
+						ShiftPolygon = shiftPolygon,
+						FullLoadCurve = gearFullLoad,
+						Ratio = gear.Ratio,
+						TorqueConverterActive = false
+					});
 			}).ToDictionary(kv => kv.Key, kv => kv.Value);
 			return retVal;
 		}
@@ -205,12 +207,11 @@ namespace TUGraz.VectoCore.FileIO.Reader.DataObjectAdaper
 		/// Intersects full load curves.
 		/// </summary>
 		/// <param name="curves">full load curves</param>
-		/// <returns>A combined full load curve with the minimum of all full load torques over all input curves.</returns>
+		/// <returns>A combined EngineFullLoadCurve with the minimum full load torque over all inputs curves.</returns>
 		private static EngineFullLoadCurve IntersectFullLoadCurves(params FullLoadCurve[] curves)
 		{
-			var entries = curves.SelectMany(curve => curve.FullLoadEntries)
-				.Select(entry => entry.EngineSpeed)
-				.OrderBy(x => x)
+			var entries = curves.SelectMany(curve => curve.FullLoadEntries, (curve, entry) => entry.EngineSpeed)
+				.OrderBy(engineSpeed => engineSpeed)
 				.Distinct()
 				.Select(engineSpeed => new FullLoadCurve.FullLoadCurveEntry {
 					EngineSpeed = engineSpeed,
diff --git a/VectoCore/Models/Connector/Ports/IResponse.cs b/VectoCore/Models/Connector/Ports/IResponse.cs
index 7965878e35c78a1ab469a724a1814bab4221dbd5..d6d68d495dfab355caa637982c081eb2028d843b 100644
--- a/VectoCore/Models/Connector/Ports/IResponse.cs
+++ b/VectoCore/Models/Connector/Ports/IResponse.cs
@@ -12,6 +12,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports
 		FailTimeInterval,
 		DrivingCycleDistanceExceeded,
 		DryRun,
+		GearShift
 	}
 
 
diff --git a/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs b/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
index f3cc051dc714c0360f77b9cafd87ce5662cf978e..f84847448cc28fa02763da4547c852ac1d07a63b 100644
--- a/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
+++ b/VectoCore/Models/SimulationComponent/Data/Gearbox/ShiftPolygon.cs
@@ -33,13 +33,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 
 			List<ShiftPolygonEntry> entriesDown, entriesUp;
 			if (HeaderIsValid(data.Columns)) {
-				entriesDown = CreateFromColumnNames(data, Fields.AngluarSpeedDown);
+				entriesDown = CreateFromColumnNames(data, Fields.AngularSpeedDown);
 				entriesUp = CreateFromColumnNames(data, Fields.AngularSpeedUp);
 			} else {
 				var log = LogManager.GetLogger<ShiftPolygon>();
 				log.WarnFormat(
 					"ShiftPolygon: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: '{3}'. Falling back to column index",
-					Fields.Torque, Fields.AngularSpeedUp, Fields.AngluarSpeedDown,
+					Fields.Torque, Fields.AngularSpeedUp, Fields.AngularSpeedDown,
 					string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Reverse()));
 				entriesDown = CreateFromColumnIndizes(data, 1);
 				entriesUp = CreateFromColumnIndizes(data, 2);
@@ -60,7 +60,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 		private static bool HeaderIsValid(DataColumnCollection columns)
 		{
 			return columns.Contains(Fields.Torque) && columns.Contains(Fields.AngularSpeedUp) &&
-					columns.Contains((Fields.AngluarSpeedDown));
+					columns.Contains((Fields.AngularSpeedDown));
 		}
 
 		private static List<ShiftPolygonEntry> CreateFromColumnNames(DataTable data, string columnName)
@@ -97,7 +97,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox
 			/// <summary>
 			///		[rpm] threshold for downshift
 			/// </summary>
-			public const string AngluarSpeedDown = "downshift rpm";
+			public const string AngularSpeedDown = "downshift rpm";
 		}
 
 		public class ShiftPolygonEntry
diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 53dcf97ec378a712ac6c4b70fa4449f10f4eb01f..7d5e067941f5e50d25da0ca34899b238e5d005da 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -66,11 +66,48 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		IResponse ITnOutPort.Request(Second absTime, Second dt, NewtonMeter torque, PerSecond engineSpeed, bool dryRun)
 		{
-			// todo check shiftpolygon for shifting
-
-			// convert out data to in data
-			var inEngineSpeed = engineSpeed * CurrentGear.Ratio;
-			var inTorque = CurrentGear.LossMap.GearboxInTorque(inEngineSpeed, torque);
+			bool gearChanged;
+			PerSecond inEngineSpeed;
+			NewtonMeter inTorque;
+
+			do {
+				gearChanged = false;
+				// calculate new inEngineSpeed and Torque for the current gear
+				inEngineSpeed = engineSpeed * CurrentGear.Ratio;
+				inTorque = CurrentGear.LossMap.GearboxInTorque(inEngineSpeed, torque);
+
+				//todo: 
+				// Data.TorqueReserve ... % TorqueReserver for GearSkipping and EarlyUpshift
+				// Data.ShiftTime ... minimal time between shift operations
+				// AT, MT, AMT .... different behaviour!
+
+				// check if GearBox should shift up
+				if (_gear < Data.Gears.Count) {
+					var upSection = CurrentGear.ShiftPolygon.Upshift.GetSection(entry => entry.AngularSpeed < inEngineSpeed);
+					if (inEngineSpeed > upSection.Item2.AngularSpeed ||
+						(inEngineSpeed > upSection.Item1.AngularSpeed &&
+						(inTorque < upSection.Item1.Torque || inTorque < upSection.Item2.Torque))) {
+						_gear++;
+						gearChanged = true;
+						continue;
+					}
+				}
+
+				// check if GearBox should shift down
+				if (_gear > 1) {
+					var downSection = CurrentGear.ShiftPolygon.Downshift.GetSection(entry => entry.AngularSpeed < inEngineSpeed);
+					if (inEngineSpeed < downSection.Item1.AngularSpeed ||
+						(inEngineSpeed < downSection.Item2.AngularSpeed &&
+						(inTorque > downSection.Item1.Torque || inTorque > downSection.Item2.Torque))) {
+						_gear--;
+						gearChanged = true;
+					}
+				}
+			} while (Data.SkipGears && gearChanged);
+
+			if (gearChanged) {
+				return new ResponseGearShift { SimulationInterval = Data.TractionInterruption };
+			}
 
 			// check full load curve for overload/underload (mirrored)
 			var maxTorque = CurrentGear.FullLoadCurve.FullLoadStationaryTorque(inEngineSpeed);
@@ -115,4 +152,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		#endregion
 	}
+
+	internal class ResponseGearShift : AbstractResponse
+	{
+		public override ResponseType ResponseType
+		{
+			get { return ResponseType.GearShift; }
+		}
+	}
 }
\ No newline at end of file