diff --git a/VECTO.sln.DotSettings b/VECTO.sln.DotSettings
index fbc71d3de43c9322a1724330c64857302970e1f1..11271d92f6489738bb9f961d2278206600823f3c 100644
--- a/VECTO.sln.DotSettings
+++ b/VECTO.sln.DotSettings
@@ -16,9 +16,10 @@
 	<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AROUND_MULTIPLICATIVE_OP/@EntryValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SI/@EntryIndexedValue">SI</s:String>
 	<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=2BF7A1E51991F2458D2D1F0B29CF888B/@KeyIndexDefined">True</s:Boolean>
 	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=2BF7A1E51991F2458D2D1F0B29CF888B/AbsolutePath/@EntryValue">C:\Workspaces\VisualStudio\VECTO_quam\VECTO.sln.DotSettings</s:String>
 	<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File2BF7A1E51991F2458D2D1F0B29CF888B/@KeyIndexDefined">True</s:Boolean>
 	<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File2BF7A1E51991F2458D2D1F0B29CF888B/RelativePriority/@EntryValue">1</s:Double>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
\ No newline at end of file
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
diff --git a/VectoCore/Models/Connector/Ports/ITnPort.cs b/VectoCore/Models/Connector/Ports/ITnPort.cs
index f3df1dd0c8f1a4d839150851878c5068618e3450..0d6ddba5b82b143d8d717d83c0dac6d754e51f96 100644
--- a/VectoCore/Models/Connector/Ports/ITnPort.cs
+++ b/VectoCore/Models/Connector/Ports/ITnPort.cs
@@ -26,6 +26,6 @@ namespace TUGraz.VectoCore.Models.Connector.Ports
         /// <param name="dt">[s]</param>
         /// <param name="torque">[Nm]</param>
         /// <param name="angularVelocity">[rad/s]</param>
-        IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, RadianPerSecond angularVelocity);
+        IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity);
     }
 }
\ No newline at end of file
diff --git a/VectoCore/Models/Simulation/Cockpit/IEngineCockpit.cs b/VectoCore/Models/Simulation/Cockpit/IEngineCockpit.cs
index 75f2ba1f12e2aca17414c3eda758019901c68d23..27c6a586729a40915fcb13822fe9adbe4bf3d477 100644
--- a/VectoCore/Models/Simulation/Cockpit/IEngineCockpit.cs
+++ b/VectoCore/Models/Simulation/Cockpit/IEngineCockpit.cs
@@ -10,6 +10,6 @@ namespace TUGraz.VectoCore.Models.Simulation.Cockpit
 		/// <summary>
 		/// [rad/s] The current engine speed.
 		/// </summary>
-		RadianPerSecond EngineSpeed();
+        PerSecond EngineSpeed();
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
index f47865ef3c23343b9c8a4165c93dd5dac246ef01..dc2aa6bf36ce98aedd0bfd5a4dde971bb69c1ba3 100644
--- a/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
+++ b/VectoCore/Models/Simulation/Impl/VehicleContainer.cs
@@ -29,7 +29,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 
 		#region IEngineCockpit
 
-		public RadianPerSecond EngineSpeed()
+        public PerSecond EngineSpeed()
 		{
 			if (_engine == null) {
 				throw new VectoException("no engine available!");
diff --git a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs
index 9bc5d911a11f09b91e8da0ef2cca7430cc4a6f9c..9d01541e3a768124825432a29ae3d904560d5e66 100644
--- a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs
+++ b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs
@@ -68,17 +68,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 		/// </summary>
 		public SI Displacement
 		{
-			get { return _data.Body.Displacement.SI().Cubic.Centi.Meter.To().Cubic.Meter.Value(); }
-			protected set { _data.Body.Displacement = (double) value.To().Cubic.Centi.Meter; }
+            get { return _data.Body.Displacement.SI().Cubic.Centi.Meter.ConvertTo().Cubic.Meter.Value(); }
+            protected set { _data.Body.Displacement = (double) value.ConvertTo().Cubic.Centi.Meter; }
 		}
 
 		/// <summary>
 		///     [rad/s]
 		/// </summary>
-		public RadianPerSecond IdleSpeed
+        public PerSecond IdleSpeed
 		{
-			get { return _data.Body.IdleSpeed.SI().Rounds.Per.Minute.To<RadianPerSecond>(); }
-			protected set { _data.Body.IdleSpeed = (double) value.To().Rounds.Per.Minute; }
+            get { return _data.Body.IdleSpeed.RPMtoRad(); }
+            protected set { _data.Body.IdleSpeed = (double) value.ConvertTo().Rounds.Per.Minute; }
 		}
 
 		/// <summary>
@@ -87,7 +87,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 		public SI Inertia
 		{
 			get { return _data.Body.Inertia.SI().Kilo.Gramm.Square.Meter; }
-			protected set { _data.Body.Inertia = (double) value.To().Kilo.Gramm.Square.Meter; }
+            protected set { _data.Body.Inertia = (double) value.ConvertTo().Kilo.Gramm.Square.Meter; }
 		}
 
 		/// <summary>
@@ -95,8 +95,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 		/// </summary>
 		public SI WHTCUrban
 		{
-			get { return _data.Body.WHTCUrban.SI().Gramm.Per.Kilo.Watt.Hour.To().Kilo.Gramm.Per.Watt.Second.Value(); }
-			protected set { _data.Body.WHTCUrban = (double) value.To().Gramm.Per.Kilo.Watt.Hour; }
+            get { return _data.Body.WHTCUrban.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second.Value(); }
+            protected set { _data.Body.WHTCUrban = (double) value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
 		}
 
 		/// <summary>
@@ -104,8 +104,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 		/// </summary>
 		public SI WHTCRural
 		{
-			get { return _data.Body.WHTCRural.SI().Gramm.Per.Kilo.Watt.Hour.To().Kilo.Gramm.Per.Watt.Second.Value(); }
-			protected set { _data.Body.WHTCRural = (double) value.To().Gramm.Per.Kilo.Watt.Hour; }
+            get { return _data.Body.WHTCRural.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second.Value(); }
+            protected set { _data.Body.WHTCRural = (double) value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
 		}
 
 		/// <summary>
@@ -114,7 +114,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 		public SI WHTCMotorway
 		{
 			get { return _data.Body.WHTCMotorway.SI().Gramm.Per.Kilo.Watt.Hour.To().Kilo.Gramm.Per.Watt.Second.Value(); }
-			protected set { _data.Body.WHTCMotorway = (double) value.To().Gramm.Per.Kilo.Watt.Hour; }
+                return
+                    _data.Body.WHTCMotorway.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second.Value();
+            protected set { _data.Body.WHTCMotorway = (double) value.ConvertTo().Gramm.Per.Kilo.Watt.Hour; }
 		}
 
 		[DataMember]
diff --git a/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs b/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs
index 46396270db95553cba9756b17a6441335985390e..a1e4032d5a4a9070912bc18e1267e7841a2506b1 100644
--- a/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs
+++ b/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs
@@ -8,403 +8,421 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 {
-	public class DrivingCycleData : SimulationComponentData
-	{
-		public enum CycleType
-		{
-			EngineOnly,
-			TimeBased,
-			DistanceBased
-		}
-
-		public List<DrivingCycleEntry> Entries { get; set; }
-
-		public static DrivingCycleData ReadFromFileEngineOnly(string fileName)
-		{
-			return ReadFromFile(fileName, CycleType.EngineOnly);
-		}
-
-		public static DrivingCycleData ReadFromFileDistanceBased(string fileName)
-		{
-			return ReadFromFile(fileName, CycleType.DistanceBased);
-		}
-
-		public static DrivingCycleData ReadFromFileTimeBased(string fileName)
-		{
-			return ReadFromFile(fileName, CycleType.TimeBased);
-		}
-
-		public static DrivingCycleData ReadFromFile(string fileName, CycleType type)
-		{
-			var log = LogManager.GetLogger<DrivingCycleData>();
-
-			var parser = CreateDataParser(type);
-			var data = VectoCSVFile.Read(fileName);
-			var entries = parser.Parse(data).ToList();
-
-			log.Info(string.Format("Data loaded. Number of Entries: {0}", entries.Count));
-
-			var cycle = new DrivingCycleData { Entries = entries };
-			return cycle;
-		}
-
-		private static IDataParser CreateDataParser(CycleType type)
-		{
-			switch (type) {
-				case CycleType.EngineOnly:
-					return new EngineOnlyDataParser();
-				case CycleType.TimeBased:
-					return new TimeBasedDataParser();
-				case CycleType.DistanceBased:
-					return new DistanceBasedDataParser();
-				default:
-					throw new ArgumentOutOfRangeException("type");
-			}
-		}
-
-		private static class Fields
-		{
-			/// <summary>
-			///     [m]	Travelled distance used for distance-based cycles. If t is also defined this column will be ignored.
-			/// </summary>
-			public const string Distance = "s";
-
-			/// <summary>
-			///     [s]	Used for time-based cycles. If neither this nor the distance s is defined the data will be interpreted as 1Hz.
-			/// </summary>
-			public const string Time = "t";
-
-			/// <summary>
-			///     [km/h]	Required except for Engine Only Mode calculations.
-			/// </summary>
-			public const string VehicleSpeed = "v";
-
-			/// <summary>
-			///     [%]	Optional.
-			/// </summary>
-			public const string RoadGradient = "grad";
-
-			/// <summary>
-			///     [s]	Required for distance-based cycles. Not used in time based cycles. stop defines the time the vehicle spends in
-			///     stop phases.
-			/// </summary>
-			public const string StoppingTime = "stop";
-
-			/// <summary>
-			///     [kW]	"Aux_xxx" Supply Power input for each auxiliary defined in the .vecto file , where xxx matches the ID of the
-			///     corresponding Auxiliary. ID's are not case sensitive and must not contain space or special characters.
-			/// </summary>
-			// todo: implement additional aux as dictionary!
-			public const string AuxiliarySupplyPower = "Aux_";
-
-			/// <summary>
-			///     [rpm]	If n is defined VECTO uses that instead of the calculated engine speed value.
-			/// </summary>
-			public const string EngineSpeed = "n";
-
-			/// <summary>
-			///     [-]	Gear input. Overwrites the gear shift model.
-			/// </summary>
-			public const string Gear = "gear";
-
-			/// <summary>
-			///     [kW]	This power input will be directly added to the engine power in addition to possible other auxiliaries. Also
-			///     used in Engine Only Mode.
-			/// </summary>
-			public const string AdditionalAuxPowerDemand = "Padd";
-
-			/// <summary>
-			///     [km/h]	Only required if Cross Wind Correction is set to Vair and Beta Input.
-			/// </summary>
-			public const string AirSpeedRelativeToVehicle = "vair_res";
-
-			/// <summary>
-			///     [°]	Only required if Cross Wind Correction is set to Vair and Beta Input.
-			/// </summary>
-			public const string WindYawAngle = "vair_beta";
-
-			/// <summary>
-			///     [kW]	Effective engine power at clutch. Only required in Engine Only Mode. Alternatively torque Me can be defined.
-			///     Use DRAG to define motoring operation.
-			/// </summary>
-			public const string EnginePower = "Pe";
-
-			/// <summary>
-			///     [Nm]	Effective engine torque at clutch. Only required in Engine Only Mode. Alternatively power Pe can be defined.
-			///     Use DRAG to define motoring operation.
-			/// </summary>
-			public const string EngineTorque = "Me";
-		}
-
-		public class DrivingCycleEntry
-		{
-			/// <summary>
-			///     [m]	Travelled distance used for distance-based cycles. If "t"
-			///     is also defined this column will be ignored.
-			/// </summary>
-			public double Distance { get; set; }
-
-			/// <summary>
-			///     [s]	Used for time-based cycles. If neither this nor the distance
-			///     "s" is defined the data will be interpreted as 1Hz.
-			/// </summary>
-			public double Time { get; set; }
-
-			/// <summary>
-			///     [m/s]	Required except for Engine Only Mode calculations.
-			/// </summary>
-			public MeterPerSecond VehicleSpeed { get; set; }
-
-			/// <summary>
-			///     [%]	Optional.
-			/// </summary>
-			public double RoadGradient { get; set; }
-
-			/// <summary>
-			///     [s]	Required for distance-based cycles. Not used in time based
-			///     cycles. "stop" defines the time the vehicle spends in stop phases.
-			/// </summary>
-			public double StoppingTime { get; set; }
-
-			/// <summary>
-			///     [W]	Supply Power input for each auxiliary defined in the
-			///     .vecto file where xxx matches the ID of the corresponding
-			///     Auxiliary. ID's are not case sensitive and must not contain
-			///     space or special characters.
-			/// </summary>
-			public Dictionary<string, Watt> AuxiliarySupplyPower { get; set; }
-
-			/// <summary>
-			///     [rad/s]	If "n" is defined VECTO uses that instead of the
-			///     calculated engine speed value.
-			/// </summary>
-			public RadianPerSecond EngineSpeed { get; set; }
-
-			/// <summary>
-			///     [-]	Gear input. Overwrites the gear shift model.
-			/// </summary>
-			public double Gear { get; set; }
-
-			/// <summary>
-			///     [W]	This power input will be directly added to the engine
-			///     power in addition to possible other auxiliaries. Also used in
-			///     Engine Only Mode.
-			/// </summary>
-			public Watt AdditionalAuxPowerDemand { get; set; }
-
-			/// <summary>
-			///     [m/s] Only required if Cross Wind Correction is set to Vair and Beta Input.
-			/// </summary>
-			public MeterPerSecond AirSpeedRelativeToVehicle { get; set; }
-
-			/// <summary>
-			///     [°] Only required if Cross Wind Correction is set to Vair and Beta Input.
-			/// </summary>
-			public double WindYawAngle { get; set; }
-
-			/// <summary>
-			///     [Nm] Effective engine torque at clutch. Only required in
-			///     Engine Only Mode. Alternatively power "Pe" can be defined.
-			///     Use "DRAG" to define motoring operation.
-			/// </summary>
-			public NewtonMeter EngineTorque { get; set; }
-
-			public bool Drag { get; set; }
-		}
-
-		#region DataParser
-
-		private interface IDataParser
-		{
-			IEnumerable<DrivingCycleEntry> Parse(DataTable table);
-		}
-
-		/// <summary>
-		///     Reader for Auxiliary Supply Power.
-		/// </summary>
-		private static class AuxSupplyPowerReader
-		{
-			/// <summary>
-			///     [W]. Reads Auxiliary Supply Power (defined by Fields.AuxiliarySupplyPower-Prefix).
-			/// </summary>
-			public static Dictionary<string, Watt> Read(DataRow row)
-			{
-				return row.Table.Columns.Cast<DataColumn>().
-					Where(col => col.ColumnName.StartsWith(Fields.AuxiliarySupplyPower)).
-					ToDictionary(col => col.ColumnName.Substring(Fields.AuxiliarySupplyPower.Length - 1),
-						col => row.ParseDouble(col).SI().Kilo.Watt.To<Watt>());
-			}
-		}
-
-		private class DistanceBasedDataParser : IDataParser
-		{
-			public IEnumerable<DrivingCycleEntry> Parse(DataTable table)
-			{
-				ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
-
-				return table.Rows.Cast<DataRow>().Select(row => new DrivingCycleEntry {
-					Distance = row.ParseDouble(Fields.Distance),
-					VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.To<MeterPerSecond>(),
-					RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
-					AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.To<Watt>(),
-					EngineSpeed = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.To<RadianPerSecond>(),
-					Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
-					AirSpeedRelativeToVehicle =
-						row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle).SI().Kilo.Meter.Per.Hour.To<MeterPerSecond>(),
-					WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
-					AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
-				});
-			}
-
-			private static void ValidateHeader(string[] header)
-			{
-				var allowedCols = new[] {
-					Fields.Distance,
-					Fields.VehicleSpeed,
-					Fields.RoadGradient,
-					Fields.StoppingTime,
-					Fields.EngineSpeed,
-					Fields.Gear,
-					Fields.AdditionalAuxPowerDemand,
-					Fields.AirSpeedRelativeToVehicle,
-					Fields.WindYawAngle
-				};
-
-				foreach (var col in header.Where(col => !(allowedCols.Contains(col) || col.StartsWith(Fields.AuxiliarySupplyPower)))
-					) {
-					throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
-				}
-
-				if (!header.Contains(Fields.VehicleSpeed)) {
-					throw new VectoException(string.Format("Column '{0}' is missing.", Fields.VehicleSpeed));
-				}
-
-				if (!header.Contains(Fields.Distance)) {
-					throw new VectoException(string.Format("Column '{0}' is missing.", Fields.Distance));
-				}
-
-				if (header.Contains(Fields.AirSpeedRelativeToVehicle) ^ header.Contains(Fields.WindYawAngle)) {
-					throw new VectoException(string.Format("Both Columns '{0}' and '{1}' must be defined, or none of them.",
-						Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle));
-				}
-			}
-		}
-
-		private class TimeBasedDataParser : IDataParser
-		{
-			public IEnumerable<DrivingCycleEntry> Parse(DataTable table)
-			{
-				ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
-
-				var entries = table.Rows.Cast<DataRow>().Select((row, index) => new DrivingCycleEntry {
-					Time = row.ParseDoubleOrGetDefault(Fields.Time, index),
-					VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.To<MeterPerSecond>(),
-					RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
-					AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.To<Watt>(),
-					Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
-					EngineSpeed = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.To<RadianPerSecond>(),
-					AirSpeedRelativeToVehicle =
-						row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle).SI().Kilo.Meter.Per.Hour.To<MeterPerSecond>(),
-					WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
-					AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
-				}).ToArray();
-
-				return entries;
-			}
-
-			private static void ValidateHeader(string[] header)
-			{
-				var allowedCols = new[] {
-					Fields.Time,
-					Fields.VehicleSpeed,
-					Fields.RoadGradient,
-					Fields.EngineSpeed,
-					Fields.Gear,
-					Fields.AdditionalAuxPowerDemand,
-					Fields.AirSpeedRelativeToVehicle,
-					Fields.WindYawAngle
-				};
-
-				foreach (var col in header.Where(col => !(allowedCols.Contains(col) || col.StartsWith(Fields.AuxiliarySupplyPower)))
-					) {
-					throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
-				}
-
-				if (!header.Contains(Fields.VehicleSpeed)) {
-					throw new VectoException(string.Format("Column '{0}' is missing.", Fields.VehicleSpeed));
-				}
-
-				if (header.Contains(Fields.AirSpeedRelativeToVehicle) ^ header.Contains(Fields.WindYawAngle)) {
-					throw new VectoException(string.Format("Both Columns '{0}' and '{1}' must be defined, or none of them.",
-						Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle));
-				}
-			}
-		}
-
-		private class EngineOnlyDataParser : IDataParser
-		{
-			public IEnumerable<DrivingCycleEntry> Parse(DataTable table)
-			{
-				ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
-				var absTime = new TimeSpan(0, 0, 0);
-
-				foreach (DataRow row in table.Rows) {
-					var entry = new DrivingCycleEntry {
-						EngineSpeed = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.To<RadianPerSecond>(),
-						AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.To<Watt>(),
-						AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
-					};
-					if (row.Table.Columns.Contains(Fields.EngineTorque)) {
-						if (row.Field<string>(Fields.EngineTorque).Equals("<DRAG>")) {
-							entry.Drag = true;
-						} else {
-							entry.EngineTorque = row.ParseDouble(Fields.EngineTorque).SI<NewtonMeter>();
-						}
-					} else {
-						if (row.Field<string>(Fields.EnginePower).Equals("<DRAG>")) {
-							entry.Drag = true;
-						} else {
-							entry.EngineTorque = Formulas.PowerToTorque(row.ParseDouble(Fields.EnginePower).SI().Kilo.Watt.To<Watt>(),
-								entry.EngineSpeed);
-						}
-					}
-					entry.Time = absTime.TotalSeconds;
-					absTime += new TimeSpan(0, 0, 1);
-
-					yield return entry;
-				}
-			}
-
-			private static void ValidateHeader(string[] header)
-			{
-				var allowedCols = new[] {
-					Fields.EngineTorque,
-					Fields.EnginePower,
-					Fields.EngineSpeed,
-					Fields.AdditionalAuxPowerDemand
-				};
-
-				foreach (var col in header.Where(col => !allowedCols.Contains(col))) {
-					throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
-				}
-
-				if (!header.Contains(Fields.EngineSpeed)) {
-					throw new VectoException(string.Format("Column '{0}' is missing.", Fields.EngineSpeed));
-				}
-
-				if (!(header.Contains(Fields.EngineTorque) || header.Contains(Fields.EnginePower))) {
-					throw new VectoException(string.Format("Columns missing: Either column '{0}' or column '{1}' must be defined.",
-						Fields.EngineTorque, Fields.EnginePower));
-				}
-
-				if (header.Contains(Fields.EngineTorque) && header.Contains(Fields.EnginePower)) {
-					LogManager.GetLogger<DrivingCycleData>()
-						.WarnFormat("Found column '{0}' and column '{1}': only column '{0}' will be used.",
-							Fields.EngineTorque, Fields.EnginePower);
-				}
-			}
-		}
-
-		#endregion
-	}
+    public class DrivingCycleData : SimulationComponentData
+    {
+        public enum CycleType
+        {
+            EngineOnly,
+            TimeBased,
+            DistanceBased
+        }
+
+        public List<DrivingCycleEntry> Entries { get; set; }
+
+        public static DrivingCycleData ReadFromFileEngineOnly(string fileName)
+        {
+            return ReadFromFile(fileName, CycleType.EngineOnly);
+        }
+
+        public static DrivingCycleData ReadFromFileDistanceBased(string fileName)
+        {
+            return ReadFromFile(fileName, CycleType.DistanceBased);
+        }
+
+        public static DrivingCycleData ReadFromFileTimeBased(string fileName)
+        {
+            return ReadFromFile(fileName, CycleType.TimeBased);
+        }
+
+        public static DrivingCycleData ReadFromFile(string fileName, CycleType type)
+        {
+            var log = LogManager.GetLogger<DrivingCycleData>();
+
+            var parser = CreateDataParser(type);
+            var data = VectoCSVFile.Read(fileName);
+            var entries = parser.Parse(data).ToList();
+
+            log.Info(string.Format("Data loaded. Number of Entries: {0}", entries.Count));
+
+            var cycle = new DrivingCycleData { Entries = entries };
+            return cycle;
+        }
+
+        private static IDataParser CreateDataParser(CycleType type)
+        {
+            switch (type) {
+                case CycleType.EngineOnly:
+                    return new EngineOnlyDataParser();
+                case CycleType.TimeBased:
+                    return new TimeBasedDataParser();
+                case CycleType.DistanceBased:
+                    return new DistanceBasedDataParser();
+                default:
+                    throw new ArgumentOutOfRangeException("type");
+            }
+        }
+
+        private static class Fields
+        {
+            /// <summary>
+            ///     [m]	Travelled distance used for distance-based cycles. If t is also defined this column will be ignored.
+            /// </summary>
+            public const string Distance = "s";
+
+            /// <summary>
+            ///     [s]	Used for time-based cycles. If neither this nor the distance s is defined the data will be interpreted as 1Hz.
+            /// </summary>
+            public const string Time = "t";
+
+            /// <summary>
+            ///     [km/h]	Required except for Engine Only Mode calculations.
+            /// </summary>
+            public const string VehicleSpeed = "v";
+
+            /// <summary>
+            ///     [%]	Optional.
+            /// </summary>
+            public const string RoadGradient = "grad";
+
+            /// <summary>
+            ///     [s]	Required for distance-based cycles. Not used in time based cycles. stop defines the time the vehicle spends in
+            ///     stop phases.
+            /// </summary>
+            public const string StoppingTime = "stop";
+
+            /// <summary>
+            ///     [kW]	"Aux_xxx" Supply Power input for each auxiliary defined in the .vecto file , where xxx matches the ID of the
+            ///     corresponding Auxiliary. ID's are not case sensitive and must not contain space or special characters.
+            /// </summary>
+            // todo: implement additional aux as dictionary!
+            public const string AuxiliarySupplyPower = "Aux_";
+
+            /// <summary>
+            ///     [rpm]	If n is defined VECTO uses that instead of the calculated engine speed value.
+            /// </summary>
+            public const string EngineSpeed = "n";
+
+            /// <summary>
+            ///     [-]	Gear input. Overwrites the gear shift model.
+            /// </summary>
+            public const string Gear = "gear";
+
+            /// <summary>
+            ///     [kW]	This power input will be directly added to the engine power in addition to possible other auxiliaries. Also
+            ///     used in Engine Only Mode.
+            /// </summary>
+            public const string AdditionalAuxPowerDemand = "Padd";
+
+            /// <summary>
+            ///     [km/h]	Only required if Cross Wind Correction is set to Vair and Beta Input.
+            /// </summary>
+            public const string AirSpeedRelativeToVehicle = "vair_res";
+
+            /// <summary>
+            ///     [°]	Only required if Cross Wind Correction is set to Vair and Beta Input.
+            /// </summary>
+            public const string WindYawAngle = "vair_beta";
+
+            /// <summary>
+            ///     [kW]	Effective engine power at clutch. Only required in Engine Only Mode. Alternatively torque Me can be defined.
+            ///     Use DRAG to define motoring operation.
+            /// </summary>
+            public const string EnginePower = "Pe";
+
+            /// <summary>
+            ///     [Nm]	Effective engine torque at clutch. Only required in Engine Only Mode. Alternatively power Pe can be defined.
+            ///     Use DRAG to define motoring operation.
+            /// </summary>
+            public const string EngineTorque = "Me";
+        }
+
+        public class DrivingCycleEntry
+        {
+            /// <summary>
+            ///     [m]	Travelled distance used for distance-based cycles. If "t"
+            ///     is also defined this column will be ignored.
+            /// </summary>
+            public double Distance { get; set; }
+
+            /// <summary>
+            ///     [s]	Used for time-based cycles. If neither this nor the distance
+            ///     "s" is defined the data will be interpreted as 1Hz.
+            /// </summary>
+            public double Time { get; set; }
+
+            /// <summary>
+            ///     [m/s]	Required except for Engine Only Mode calculations.
+            /// </summary>
+            public MeterPerSecond VehicleSpeed { get; set; }
+
+            /// <summary>
+            ///     [%]	Optional.
+            /// </summary>
+            public double RoadGradient { get; set; }
+
+            /// <summary>
+            ///     [s]	Required for distance-based cycles. Not used in time based
+            ///     cycles. "stop" defines the time the vehicle spends in stop phases.
+            /// </summary>
+            public double StoppingTime { get; set; }
+
+            /// <summary>
+            ///     [W]	Supply Power input for each auxiliary defined in the
+            ///     .vecto file where xxx matches the ID of the corresponding
+            ///     Auxiliary. ID's are not case sensitive and must not contain
+            ///     space or special characters.
+            /// </summary>
+            public Dictionary<string, Watt> AuxiliarySupplyPower { get; set; }
+
+            /// <summary>
+            ///     [rad/s]	If "n" is defined VECTO uses that instead of the
+            ///     calculated engine speed value.
+            /// </summary>
+            public PerSecond EngineSpeed { get; set; }
+
+            /// <summary>
+            ///     [-]	Gear input. Overwrites the gear shift model.
+            /// </summary>
+            public double Gear { get; set; }
+
+            /// <summary>
+            ///     [W]	This power input will be directly added to the engine
+            ///     power in addition to possible other auxiliaries. Also used in
+            ///     Engine Only Mode.
+            /// </summary>
+            public Watt AdditionalAuxPowerDemand { get; set; }
+
+            /// <summary>
+            ///     [m/s] Only required if Cross Wind Correction is set to Vair and Beta Input.
+            /// </summary>
+            public MeterPerSecond AirSpeedRelativeToVehicle { get; set; }
+
+            /// <summary>
+            ///     [°] Only required if Cross Wind Correction is set to Vair and Beta Input.
+            /// </summary>
+            public double WindYawAngle { get; set; }
+
+            /// <summary>
+            ///     [Nm] Effective engine torque at clutch. Only required in
+            ///     Engine Only Mode. Alternatively power "Pe" can be defined.
+            ///     Use "DRAG" to define motoring operation.
+            /// </summary>
+            public NewtonMeter EngineTorque { get; set; }
+
+            public bool Drag { get; set; }
+        }
+
+        #region DataParser
+
+        private interface IDataParser
+        {
+            IEnumerable<DrivingCycleEntry> Parse(DataTable table);
+        }
+
+        /// <summary>
+        ///     Reader for Auxiliary Supply Power.
+        /// </summary>
+        private static class AuxSupplyPowerReader
+        {
+            /// <summary>
+            ///     [W]. Reads Auxiliary Supply Power (defined by Fields.AuxiliarySupplyPower-Prefix).
+            /// </summary>
+            public static Dictionary<string, Watt> Read(DataRow row)
+            {
+                return row.Table.Columns.Cast<DataColumn>().
+                    Where(col => col.ColumnName.StartsWith(Fields.AuxiliarySupplyPower)).
+                    ToDictionary(col => col.ColumnName.Substring(Fields.AuxiliarySupplyPower.Length - 1),
+                        col => row.ParseDouble(col).SI().Kilo.Watt.Cast<Watt>());
+            }
+        }
+
+        private class DistanceBasedDataParser : IDataParser
+        {
+            public IEnumerable<DrivingCycleEntry> Parse(DataTable table)
+            {
+                ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
+
+                return table.Rows.Cast<DataRow>().Select(row => new DrivingCycleEntry {
+                    Distance = row.ParseDouble(Fields.Distance),
+                    VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
+                    RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
+                    AdditionalAuxPowerDemand =
+                        row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
+                    EngineSpeed =
+                        row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
+                    Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
+                    AirSpeedRelativeToVehicle =
+                        row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle)
+                            .SI()
+                            .Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
+                    WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
+                    AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
+                });
+            }
+
+            private static void ValidateHeader(string[] header)
+            {
+                var allowedCols = new[] {
+                    Fields.Distance,
+                    Fields.VehicleSpeed,
+                    Fields.RoadGradient,
+                    Fields.StoppingTime,
+                    Fields.EngineSpeed,
+                    Fields.Gear,
+                    Fields.AdditionalAuxPowerDemand,
+                    Fields.AirSpeedRelativeToVehicle,
+                    Fields.WindYawAngle
+                };
+
+                foreach (
+                    var col in
+                        header.Where(col => !(allowedCols.Contains(col) || col.StartsWith(Fields.AuxiliarySupplyPower)))
+                    ) {
+                    throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
+                }
+
+                if (!header.Contains(Fields.VehicleSpeed)) {
+                    throw new VectoException(string.Format("Column '{0}' is missing.", Fields.VehicleSpeed));
+                }
+
+                if (!header.Contains(Fields.Distance)) {
+                    throw new VectoException(string.Format("Column '{0}' is missing.", Fields.Distance));
+                }
+
+                if (header.Contains(Fields.AirSpeedRelativeToVehicle) ^ header.Contains(Fields.WindYawAngle)) {
+                    throw new VectoException(
+                        string.Format("Both Columns '{0}' and '{1}' must be defined, or none of them.",
+                            Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle));
+                }
+            }
+        }
+
+        private class TimeBasedDataParser : IDataParser
+        {
+            public IEnumerable<DrivingCycleEntry> Parse(DataTable table)
+            {
+                ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
+
+                var entries = table.Rows.Cast<DataRow>().Select((row, index) => new DrivingCycleEntry {
+                    Time = row.ParseDoubleOrGetDefault(Fields.Time, index),
+                    VehicleSpeed = row.ParseDouble(Fields.VehicleSpeed).SI().Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
+                    RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
+                    AdditionalAuxPowerDemand =
+                        row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
+                    Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
+                    EngineSpeed =
+                        row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
+                    AirSpeedRelativeToVehicle =
+                        row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle)
+                            .SI()
+                            .Kilo.Meter.Per.Hour.Cast<MeterPerSecond>(),
+                    WindYawAngle = row.ParseDoubleOrGetDefault(Fields.WindYawAngle),
+                    AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
+                }).ToArray();
+
+                return entries;
+            }
+
+            private static void ValidateHeader(string[] header)
+            {
+                var allowedCols = new[] {
+                    Fields.Time,
+                    Fields.VehicleSpeed,
+                    Fields.RoadGradient,
+                    Fields.EngineSpeed,
+                    Fields.Gear,
+                    Fields.AdditionalAuxPowerDemand,
+                    Fields.AirSpeedRelativeToVehicle,
+                    Fields.WindYawAngle
+                };
+
+                foreach (
+                    var col in
+                        header.Where(col => !(allowedCols.Contains(col) || col.StartsWith(Fields.AuxiliarySupplyPower)))
+                    ) {
+                    throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
+                }
+
+                if (!header.Contains(Fields.VehicleSpeed)) {
+                    throw new VectoException(string.Format("Column '{0}' is missing.", Fields.VehicleSpeed));
+                }
+
+                if (header.Contains(Fields.AirSpeedRelativeToVehicle) ^ header.Contains(Fields.WindYawAngle)) {
+                    throw new VectoException(
+                        string.Format("Both Columns '{0}' and '{1}' must be defined, or none of them.",
+                            Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle));
+                }
+            }
+        }
+
+        private class EngineOnlyDataParser : IDataParser
+        {
+            public IEnumerable<DrivingCycleEntry> Parse(DataTable table)
+            {
+                ValidateHeader(table.Columns.Cast<DataColumn>().Select(col => col.ColumnName).ToArray());
+                var absTime = new TimeSpan(0, 0, 0);
+
+                foreach (DataRow row in table.Rows) {
+                    var entry = new DrivingCycleEntry {
+                        EngineSpeed =
+                            row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
+                        AdditionalAuxPowerDemand =
+                            row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.Cast<Watt>(),
+                        AuxiliarySupplyPower = AuxSupplyPowerReader.Read(row)
+                    };
+                    if (row.Table.Columns.Contains(Fields.EngineTorque)) {
+                        if (row.Field<string>(Fields.EngineTorque).Equals("<DRAG>")) {
+                            entry.Drag = true;
+                        } else {
+                            entry.EngineTorque = row.ParseDouble(Fields.EngineTorque).SI<NewtonMeter>();
+                        }
+                    } else {
+                        if (row.Field<string>(Fields.EnginePower).Equals("<DRAG>")) {
+                            entry.Drag = true;
+                        } else {
+                            entry.EngineTorque =
+                                Formulas.PowerToTorque(row.ParseDouble(Fields.EnginePower).SI().Kilo.Watt.Cast<Watt>(),
+                                    entry.EngineSpeed);
+                        }
+                    }
+                    entry.Time = absTime.TotalSeconds;
+                    absTime += new TimeSpan(0, 0, 1);
+
+                    yield return entry;
+                }
+            }
+
+            private static void ValidateHeader(string[] header)
+            {
+                var allowedCols = new[] {
+                    Fields.EngineTorque,
+                    Fields.EnginePower,
+                    Fields.EngineSpeed,
+                    Fields.AdditionalAuxPowerDemand
+                };
+
+                foreach (var col in header.Where(col => !allowedCols.Contains(col))) {
+                    throw new VectoException(string.Format("Column '{0}' is not allowed.", col));
+                }
+
+                if (!header.Contains(Fields.EngineSpeed)) {
+                    throw new VectoException(string.Format("Column '{0}' is missing.", Fields.EngineSpeed));
+                }
+
+                if (!(header.Contains(Fields.EngineTorque) || header.Contains(Fields.EnginePower))) {
+                    throw new VectoException(
+                        string.Format("Columns missing: Either column '{0}' or column '{1}' must be defined.",
+                            Fields.EngineTorque, Fields.EnginePower));
+                }
+
+                if (header.Contains(Fields.EngineTorque) && header.Contains(Fields.EnginePower)) {
+                    LogManager.GetLogger<DrivingCycleData>()
+                        .WarnFormat("Found column '{0}' and column '{1}': only column '{0}' will be used.",
+                            Fields.EngineTorque, Fields.EnginePower);
+                }
+            }
+        }
+
+        #endregion
+    }
 }
\ No newline at end of file
diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
index 52163fc134e782bdd8c7d103eb4c07f9238a1019..f1ef8218c1b7f94cb5820c1446974730e96d65ab 100644
--- a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
+++ b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
@@ -9,168 +9,167 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 {
-	[JsonObject(MemberSerialization.Fields)]
-	public class FuelConsumptionMap : SimulationComponentData
-	{
-		private readonly IList<FuelConsumptionEntry> _entries = new List<FuelConsumptionEntry>();
-		private readonly DelauneyMap _fuelMap = new DelauneyMap();
-		private FuelConsumptionMap() {}
-
-		[ContractInvariantMethod]
-		private void Invariant()
-		{
-			Contract.Invariant(_entries != null);
-			Contract.Invariant(_fuelMap != null);
-		}
-
-		public static FuelConsumptionMap ReadFromFile(string fileName)
-		{
-			var fuelConsumptionMap = new FuelConsumptionMap();
-			var data = VectoCSVFile.Read(fileName);
-
-			try {
-				foreach (DataRow row in data.Rows) {
-					try {
-						var entry = new FuelConsumptionEntry {
-							EngineSpeed = row.ParseDouble(Fields.EngineSpeed).SI().Rounds.Per.Minute.To<RadianPerSecond>(),
-							Torque = row.ParseDouble(Fields.Torque).SI<NewtonMeter>(),
-							FuelConsumption = row.ParseDouble(Fields.FuelConsumption).SI().Gramm.Per.Hour.To().Kilo.Gramm.Per.Second
-						};
-
-						// todo Contract.Assert
-						if (entry.FuelConsumption < 0) {
-							throw new ArgumentOutOfRangeException("FuelConsumption", "FuelConsumption < 0 not allowed.");
-						}
-
-						fuelConsumptionMap._entries.Add(entry);
-
-						// Delauney map works only as expected, when the engineSpeed is in rpm.
-						fuelConsumptionMap._fuelMap.AddPoint((double) entry.Torque, row.ParseDouble(Fields.EngineSpeed),
-							(double) entry.FuelConsumption);
-					} catch (Exception e) {
-						throw new VectoException(string.Format("Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e);
-					}
-				}
-			} catch (Exception e) {
-				throw new VectoException(string.Format("File {0}: {1}", fileName, e.Message), e);
-			}
-
-			fuelConsumptionMap._fuelMap.Triangulate();
-			return fuelConsumptionMap;
-		}
-
-		/// <summary>
-		///     [kg/s] Calculates the fuel consumption based on the given fuel map,
-		///     the engineSpeed [rad/s] and the torque [Nm].
-		/// </summary>
-		/// <param name="engineSpeed">[rad/sec]</param>
-		/// <param name="torque">[Nm]</param>
-		/// <returns>[kg/s]</returns>
-		public SI GetFuelConsumption(NewtonMeter torque, RadianPerSecond engineSpeed)
-		{
-			return _fuelMap.Interpolate((double) torque, (double) engineSpeed.To().Rounds.Per.Minute).SI().Kilo.Gramm.Per.Second;
-		}
-
-		private static class Fields
-		{
-			/// <summary>
-			///     [rpm]
-			/// </summary>
-			public const string EngineSpeed = "engine speed";
-
-			/// <summary>
-			///     [Nm]
-			/// </summary>
-			public const string Torque = "torque";
-
-			/// <summary>
-			///     [g/h]
-			/// </summary>
-			public const string FuelConsumption = "fuel consumption";
-		};
-
-		private class FuelConsumptionEntry
-		{
-			/// <summary>
-			///     engine speed [rad/s]
-			/// </summary>
-			public RadianPerSecond EngineSpeed { get; set; }
-
-			/// <summary>
-			///     Torque [Nm]
-			/// </summary>
-			public NewtonMeter Torque { get; set; }
-
-			/// <summary>
-			///     Fuel consumption [kg/s]
-			/// </summary>
-			public SI FuelConsumption { get; set; }
-
-			#region Equality members
-
-			private bool Equals(FuelConsumptionEntry other)
-			{
-				Contract.Requires(other != null);
-				return EngineSpeed.Equals(other.EngineSpeed) && Torque.Equals(other.Torque) &&
-						FuelConsumption.Equals(other.FuelConsumption);
-			}
-
-			public override bool Equals(object obj)
-			{
-				if (ReferenceEquals(null, obj)) {
-					return false;
-				}
-				if (ReferenceEquals(this, obj)) {
-					return true;
-				}
-				if (obj.GetType() != GetType()) {
-					return false;
-				}
-				return Equals((FuelConsumptionEntry) obj);
-			}
-
-			public override int GetHashCode()
-			{
-				unchecked {
-					var hashCode = EngineSpeed.GetHashCode();
-					hashCode = (hashCode * 397) ^ Torque.GetHashCode();
-					hashCode = (hashCode * 397) ^ FuelConsumption.GetHashCode();
-					return hashCode;
-				}
-			}
-
-			#endregion
-		}
-
-		#region Equality members
-
-		protected bool Equals(FuelConsumptionMap other)
-		{
-			return _entries.SequenceEqual(other._entries) && Equals(_fuelMap, other._fuelMap);
-		}
-
-		public override bool Equals(object obj)
-		{
-			if (ReferenceEquals(null, obj)) {
-				return false;
-			}
-			if (ReferenceEquals(this, obj)) {
-				return true;
-			}
-			if (obj.GetType() != GetType()) {
-				return false;
-			}
-			return Equals((FuelConsumptionMap) obj);
-		}
-
-		public override int GetHashCode()
-		{
-			unchecked {
-				return ((_entries != null ? _entries.GetHashCode() : 0) * 397) ^
-						(_fuelMap != null ? _fuelMap.GetHashCode() : 0);
-			}
-		}
-
-		#endregion
-	}
+    [JsonObject(MemberSerialization.Fields)]
+    public class FuelConsumptionMap : SimulationComponentData
+    {
+        private readonly IList<FuelConsumptionEntry> _entries = new List<FuelConsumptionEntry>();
+        private readonly DelauneyMap _fuelMap = new DelauneyMap();
+        private FuelConsumptionMap() {}
+
+        public static FuelConsumptionMap ReadFromFile(string fileName)
+        {
+            var fuelConsumptionMap = new FuelConsumptionMap();
+            var data = VectoCSVFile.Read(fileName);
+
+            try {
+                foreach (DataRow row in data.Rows) {
+                    try {
+                        var entry = new FuelConsumptionEntry {
+                            EngineSpeed =
+                                row.ParseDouble(Fields.EngineSpeed).SI().Rounds.Per.Minute.Cast<PerSecond>(),
+                            Torque = row.ParseDouble(Fields.Torque).SI<NewtonMeter>(),
+                            FuelConsumption =
+                                row.ParseDouble(Fields.FuelConsumption).SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second
+                        };
+
+                        // todo Contract.Assert
+                        if (entry.FuelConsumption < 0) {
+                            throw new ArgumentOutOfRangeException("FuelConsumption", "FuelConsumption < 0 not allowed.");
+                        }
+
+                        fuelConsumptionMap._entries.Add(entry);
+
+                        // Delauney map works only as expected, when the engineSpeed is in rpm.
+                        fuelConsumptionMap._fuelMap.AddPoint((double) entry.Torque, row.ParseDouble(Fields.EngineSpeed),
+                            (double) entry.FuelConsumption);
+                    } catch (Exception e) {
+                        throw new VectoException(string.Format("Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e);
+                    }
+                }
+            } catch (Exception e) {
+                throw new VectoException(string.Format("File {0}: {1}", fileName, e.Message), e);
+            }
+
+            fuelConsumptionMap._fuelMap.Triangulate();
+            return fuelConsumptionMap;
+        }
+
+        /// <summary>
+        ///     [kg/s] Calculates the fuel consumption based on the given fuel map,
+        ///     the engineSpeed [rad/s] and the torque [Nm].
+        /// </summary>
+        /// <param name="engineSpeed">[rad/sec]</param>
+        /// <param name="torque">[Nm]</param>
+        /// <returns>[kg/s]</returns>
+        public SI GetFuelConsumption(NewtonMeter torque, PerSecond engineSpeed)
+        {
+            // delauney map needs is initialised with rpm, therefore the engineSpeed has to be converted.
+            return
+                _fuelMap.Interpolate((double) torque, (double) engineSpeed.ConvertTo().Rounds.Per.Minute)
+                    .SI()
+                    .Kilo.Gramm.Per.Second;
+        }
+
+        private static class Fields
+        {
+            /// <summary>
+            ///     [rpm]
+            /// </summary>
+            public const string EngineSpeed = "engine speed";
+
+            /// <summary>
+            ///     [Nm]
+            /// </summary>
+            public const string Torque = "torque";
+
+            /// <summary>
+            ///     [g/h]
+            /// </summary>
+            public const string FuelConsumption = "fuel consumption";
+        };
+
+        private class FuelConsumptionEntry
+        {
+            /// <summary>
+            ///     engine speed [rad/s]
+            /// </summary>
+            public PerSecond EngineSpeed { get; set; }
+
+            /// <summary>
+            ///     Torque [Nm]
+            /// </summary>
+            public NewtonMeter Torque { get; set; }
+
+            /// <summary>
+            ///     Fuel consumption [kg/s]
+            /// </summary>
+            public SI FuelConsumption { get; set; }
+
+            #region Equality members
+
+            private bool Equals(FuelConsumptionEntry other)
+            {
+                Contract.Requires(other != null);
+                return EngineSpeed.Equals(other.EngineSpeed) && Torque.Equals(other.Torque) &&
+                       FuelConsumption.Equals(other.FuelConsumption);
+            }
+
+            public override bool Equals(object obj)
+            {
+                if (ReferenceEquals(null, obj)) {
+                    return false;
+                }
+                if (ReferenceEquals(this, obj)) {
+                    return true;
+                }
+                if (obj.GetType() != GetType()) {
+                    return false;
+                }
+                return Equals((FuelConsumptionEntry) obj);
+            }
+
+            public override int GetHashCode()
+            {
+                unchecked {
+                    var hashCode = EngineSpeed.GetHashCode();
+                    hashCode = (hashCode * 397) ^ Torque.GetHashCode();
+                    hashCode = (hashCode * 397) ^ FuelConsumption.GetHashCode();
+                    return hashCode;
+                }
+            }
+
+            #endregion
+        }
+
+        #region Equality members
+
+        protected bool Equals(FuelConsumptionMap other)
+        {
+            return _entries.SequenceEqual(other._entries) && Equals(_fuelMap, other._fuelMap);
+        }
+
+        public override bool Equals(object obj)
+        {
+            if (ReferenceEquals(null, obj)) {
+                return false;
+            }
+            if (ReferenceEquals(this, obj)) {
+                return true;
+            }
+            if (obj.GetType() != GetType()) {
+                return false;
+            }
+            return Equals((FuelConsumptionMap) obj);
+        }
+
+        public override int GetHashCode()
+        {
+            unchecked {
+                return ((_entries != null ? _entries.GetHashCode() : 0) * 397) ^
+                       (_fuelMap != null ? _fuelMap.GetHashCode() : 0);
+            }
+        }
+
+        #endregion
+    }
 }
\ No newline at end of file
diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs
index 78ef6b076104e00f6b432693ea170eb1d27e235a..f27ff9bb425571e519bda435e38f7e250bef9977 100644
--- a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs
+++ b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs
@@ -11,6 +11,9 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 {
+	/// <summary>
+	/// Represents the Full load curve.
+	/// </summary>
 	public class FullLoadCurve : SimulationComponentData
 	{
 		[JsonProperty] private List<FullLoadCurveEntry> _entries;
@@ -26,7 +29,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 
 			//todo Contract.Requires<VectoException>(data.Rows.Count < 2, "FullLoadCurve must consist of at least two lines with numeric values (below file header)");
 			if (data.Rows.Count < 2) {
-				throw new VectoException("FullLoadCurve must consist of at least two lines with numeric values (below file header)");
+				throw new VectoException(
+					"FullLoadCurve must consist of at least two lines with numeric values (below file header)");
 			}
 
 			List<FullLoadCurveEntry> entries;
@@ -59,7 +63,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			Contract.Requires(data != null);
 			return (from DataRow row in data.Rows
 				select new FullLoadCurveEntry {
-					EngineSpeed = row.ParseDouble(Fields.EngineSpeed).SI().Rounds.Per.Minute.To<RadianPerSecond>(),
+					EngineSpeed = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(),
 					TorqueFullLoad = row.ParseDouble(Fields.TorqueFullLoad).SI<NewtonMeter>(),
 					TorqueDrag = row.ParseDouble(Fields.TorqueDrag).SI<NewtonMeter>(),
 					PT1 = row.ParseDouble(Fields.PT1).SI<Second>()
@@ -71,7 +75,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			Contract.Requires(data != null);
 			return (from DataRow row in data.Rows
 				select new FullLoadCurveEntry {
-					EngineSpeed = row.ParseDouble(0).SI().Rounds.Per.Minute.To<RadianPerSecond>(),
+					EngineSpeed = row.ParseDouble(0).RPMtoRad(),
 					TorqueFullLoad = row.ParseDouble(1).SI<NewtonMeter>(),
 					TorqueDrag = row.ParseDouble(2).SI<NewtonMeter>(),
 					PT1 = row.ParseDouble(3).SI<Second>()
@@ -81,87 +85,88 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 		/// <summary>
 		///     [rad/s] => [Nm]
 		/// </summary>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>[Nm]</returns>
-		public NewtonMeter FullLoadStationaryTorque(RadianPerSecond angularFrequency)
+		public NewtonMeter FullLoadStationaryTorque(PerSecond angularVelocity)
 		{
-			var idx = FindIndex(angularFrequency);
+			var idx = FindIndex(angularVelocity);
 			return VectoMath.Interpolate((double) _entries[idx - 1].EngineSpeed, (double) _entries[idx].EngineSpeed,
 				(double) _entries[idx - 1].TorqueFullLoad, (double) _entries[idx].TorqueFullLoad,
-				(double) angularFrequency).SI<NewtonMeter>();
+				(double) angularVelocity).SI<NewtonMeter>();
 		}
 
 		/// <summary>
 		///     [rad/s] => [W]
 		/// </summary>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>[W]</returns>
-		public Watt FullLoadStationaryPower(RadianPerSecond angularFrequency)
+		public Watt FullLoadStationaryPower(PerSecond angularVelocity)
 		{
-			return Formulas.TorqueToPower(FullLoadStationaryTorque(angularFrequency), angularFrequency);
+			return Formulas.TorqueToPower(FullLoadStationaryTorque(angularVelocity), angularVelocity);
 		}
 
 		/// <summary>
 		///     [rad/s] => [Nm]
 		/// </summary>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>[Nm]</returns>
-		public NewtonMeter DragLoadStationaryTorque(RadianPerSecond angularFrequency)
+		public NewtonMeter DragLoadStationaryTorque(PerSecond angularVelocity)
 		{
-			var idx = FindIndex(angularFrequency);
+			var idx = FindIndex(angularVelocity);
 			return VectoMath.Interpolate((double) _entries[idx - 1].EngineSpeed, (double) _entries[idx].EngineSpeed,
 				(double) _entries[idx - 1].TorqueDrag, (double) _entries[idx].TorqueDrag,
-				(double) angularFrequency).SI<NewtonMeter>();
+				(double) angularVelocity).SI<NewtonMeter>();
 		}
 
 		/// <summary>
 		///     [rad/s] => [W].
 		/// </summary>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>[W]</returns>
-		public Watt DragLoadStationaryPower(RadianPerSecond angularFrequency)
+		public Watt DragLoadStationaryPower(PerSecond angularVelocity)
 		{
-			Contract.Requires(angularFrequency.HasEqualUnit(new SI().Radian.Per.Second));
+			Contract.Requires(angularVelocity.HasEqualUnit(new SI().Radian.Per.Second));
 			Contract.Ensures(Contract.Result<SI>().HasEqualUnit(new SI().Watt));
 
-			return Formulas.TorqueToPower(DragLoadStationaryTorque(angularFrequency), angularFrequency);
+			return Formulas.TorqueToPower(DragLoadStationaryTorque(angularVelocity), angularVelocity);
 		}
 
 		/// <summary>
 		///     [rad/s] => [-]
 		/// </summary>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>[-]</returns>
-		public SI PT1(SI angularFrequency)
+		public double PT1(PerSecond angularVelocity)
 		{
-			Contract.Requires(angularFrequency.HasEqualUnit(new SI().Radian.Per.Second));
+			Contract.Requires(angularVelocity.HasEqualUnit(new SI().Radian.Per.Second));
 			Contract.Ensures(Contract.Result<SI>().HasEqualUnit(new SI()));
 
-			var idx = FindIndex(angularFrequency);
-			return VectoMath.Interpolate((double) _entries[idx - 1].EngineSpeed, (double) _entries[idx].EngineSpeed,
-				(double) _entries[idx - 1].PT1, (double) _entries[idx].PT1,
-				(double) angularFrequency).SI();
+			var idx = FindIndex(angularVelocity);
+			return VectoMath.Interpolate(_entries[idx - 1].EngineSpeed.Double(),
+				_entries[idx].EngineSpeed.Double(),
+				_entries[idx - 1].PT1.Double(), _entries[idx].PT1.Double(),
+				angularVelocity.Double());
 		}
 
 		/// <summary>
-		///     [rad/s] => index. Get item index for engineSpeed.
+		///     [rad/s] => index. Get item index for angularVelocity.
 		/// </summary>
-		/// <param name="engineSpeed">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>index</returns>
-		protected int FindIndex(SI engineSpeed)
+		protected int FindIndex(PerSecond angularVelocity)
 		{
-			Contract.Requires(engineSpeed.HasEqualUnit(new SI().Radian.Per.Second));
+			Contract.Requires(angularVelocity.HasEqualUnit(new SI().Radian.Per.Second));
 
 			int idx;
-			if (engineSpeed < _entries[0].EngineSpeed) {
+			if (angularVelocity < _entries[0].EngineSpeed) {
 				Log.ErrorFormat("requested rpm below minimum rpm in FLD curve - extrapolating. n: {0}, rpm_min: {1}",
-					engineSpeed.To().Rounds.Per.Minute, _entries[0].EngineSpeed.To().Rounds.Per.Minute);
+					angularVelocity.ConvertTo().Rounds.Per.Minute, _entries[0].EngineSpeed.ConvertTo().Rounds.Per.Minute);
 				idx = 1;
 			} else {
-				idx = _entries.FindIndex(x => x.EngineSpeed > engineSpeed);
+				idx = _entries.FindIndex(x => x.EngineSpeed > angularVelocity);
 			}
 			if (idx <= 0) {
-				idx = engineSpeed > _entries[0].EngineSpeed ? _entries.Count - 1 : 1;
+				idx = angularVelocity > _entries[0].EngineSpeed ? _entries.Count - 1 : 1;
 			}
 			return idx;
 		}
@@ -194,7 +199,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			/// <summary>
 			///     [rad/s] engine speed
 			/// </summary>
-			public RadianPerSecond EngineSpeed { get; set; }
+			public PerSecond EngineSpeed { get; set; }
 
 			/// <summary>
 			///     [Nm] full load torque
diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
index 027776435497b56a4b76c9aeb5d3dc633479eb46..6ee631a1149a7a2500a0ac476c39f7d49c68ffc4 100644
--- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
@@ -55,7 +55,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		#region IEngineCockpit
 
-		public RadianPerSecond EngineSpeed()
+		PerSecond IEngineCockpit.EngineSpeed()
 		{
 			return _previousState.EngineSpeed;
 		}
@@ -73,14 +73,14 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		#region ITnOutPort
 
-		IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, RadianPerSecond engineSpeed)
+		IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed)
 		{
 			_currentState.EngineSpeed = engineSpeed;
 			_currentState.AbsTime = absTime;
 
 			var requestedPower = Formulas.TorqueToPower(torque, engineSpeed);
 			_currentState.EnginePowerLoss = InertiaPowerLoss(torque, engineSpeed);
-			var requestedEnginePower = (requestedPower + _currentState.EnginePowerLoss).To<Watt>();
+			var requestedEnginePower = requestedPower + _currentState.EnginePowerLoss;
 
 			if (engineSpeed < (double) _data.IdleSpeed - EngineIdleSpeedStopThreshold) {
 				_currentState.OperationMode = EngineOperationMode.Stopped;
@@ -122,13 +122,13 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			writer[ModalResultField.Tq_drag] = (double) _currentState.FullDragTorque;
 			writer[ModalResultField.Tq_full] = (double) _currentState.DynamicFullLoadTorque;
 			writer[ModalResultField.Tq_eng] = (double) _currentState.EngineTorque;
-			writer[ModalResultField.n] = (double) _currentState.EngineSpeed.To().Rounds.Per.Minute;
+			writer[ModalResultField.n] = (double) _currentState.EngineSpeed.ConvertTo().Rounds.Per.Minute;
 
 			try {
 				writer[ModalResultField.FC] =
 					(double)
 						_data.ConsumptionMap.GetFuelConsumption(_currentState.EngineTorque, _currentState.EngineSpeed)
-							.To()
+							.ConvertTo()
 							.Gramm.Per.Hour;
 			} catch (VectoException ex) {
 				Log.WarnFormat("t: {0} - {1} n: {2} Tq: {3}", _currentState.AbsTime.TotalSeconds, ex.Message,
@@ -152,11 +152,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			if (_currentState.FullDragPower >= 0 && requestedEnginePower < 0) {
 				throw new VectoSimulationException(String.Format("t: {0}  P_engine_drag > 0! n: {1} [1/min] ",
-					_currentState.AbsTime, _currentState.EngineSpeed.To().Rounds.Per.Minute));
+					_currentState.AbsTime, _currentState.EngineSpeed.ConvertTo().Rounds.Per.Minute));
 			}
 			if (_currentState.DynamicFullLoadPower <= 0 && requestedEnginePower > 0) {
 				throw new VectoSimulationException(String.Format("t: {0}  P_engine_full < 0! n: {1} [1/min] ",
-					_currentState.AbsTime, _currentState.EngineSpeed.To().Rounds.Per.Minute));
+					_currentState.AbsTime, _currentState.EngineSpeed.ConvertTo().Rounds.Per.Minute));
 			}
 		}
 
@@ -217,12 +217,12 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		/// <summary>
-		///     computes full load power from gear [-], angularFrequency [rad/s] and dt [s].
+		///     computes full load power from gear [-], angularVelocity [rad/s] and dt [s].
 		/// </summary>
 		/// <param name="gear"></param>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <param name="dt">[s]</param>
-		protected void ComputeFullLoadPower(uint gear, RadianPerSecond angularFrequency, TimeSpan dt)
+		protected void ComputeFullLoadPower(uint gear, PerSecond angularVelocity, TimeSpan dt)
 		{
 			if (dt.Ticks == 0) {
 				throw new VectoException("ComputeFullLoadPower cannot compute at time 0.");
@@ -235,19 +235,19 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			//_currentState.StationaryFullLoadPower = _data.GetFullLoadCurve(gear).FullLoadStationaryPower(rpm);
 			_currentState.StationaryFullLoadTorque =
-				_data.GetFullLoadCurve(gear).FullLoadStationaryTorque(angularFrequency);
+				_data.GetFullLoadCurve(gear).FullLoadStationaryTorque(angularVelocity);
 			_currentState.StationaryFullLoadPower = Formulas.TorqueToPower(_currentState.StationaryFullLoadTorque,
-				angularFrequency);
+				angularVelocity);
 
-			var pt1 = _data.GetFullLoadCurve(gear).PT1(angularFrequency);
+			var pt1 = _data.GetFullLoadCurve(gear).PT1(angularVelocity);
 
-			var dynFullPowerCalculated =
-				((1 / (pt1 + 1)) * (_currentState.StationaryFullLoadPower + pt1 * _previousState.EnginePower)).To<Watt>();
+			var dynFullPowerCalculated = (1 / (pt1 + 1)) *
+										(_currentState.StationaryFullLoadPower + pt1 * _previousState.EnginePower);
 			_currentState.DynamicFullLoadPower = dynFullPowerCalculated < _currentState.StationaryFullLoadPower
 				? dynFullPowerCalculated
 				: _currentState.StationaryFullLoadPower;
 			_currentState.DynamicFullLoadTorque = Formulas.PowerToTorque(_currentState.DynamicFullLoadPower,
-				angularFrequency);
+				angularVelocity);
 		}
 
 		protected bool IsFullLoad(Watt requestedPower, Watt maxPower)
@@ -257,17 +257,17 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 		}
 
 		/// <summary>
-		///     Calculates power loss. [W]
+		/// Calculates power loss. [W]
 		/// </summary>
 		/// <param name="torque">[Nm]</param>
-		/// <param name="engineSpeed">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>[W]</returns>
-		protected Watt InertiaPowerLoss(NewtonMeter torque, RadianPerSecond engineSpeed)
+		protected Watt InertiaPowerLoss(NewtonMeter torque, PerSecond angularVelocity)
 		{
-			var deltaEngineSpeed = engineSpeed - _previousState.EngineSpeed;
-			var avgEngineSpeed = (_previousState.EngineSpeed + engineSpeed) / new SI(2).Second;
+			var deltaEngineSpeed = angularVelocity - _previousState.EngineSpeed;
+			var avgEngineSpeed = (_previousState.EngineSpeed + angularVelocity) / 2.0.SI<Second>();
 			var result = _data.Inertia * deltaEngineSpeed * avgEngineSpeed;
-			return result.To<Watt>();
+			return result.Cast<Watt>();
 		}
 
 		public class EngineState
@@ -287,7 +287,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			/// <summary>
 			///     [rad/s]
 			/// </summary>
-			public RadianPerSecond EngineSpeed { get; set; }
+			public PerSecond EngineSpeed { get; set; }
 
 			/// <summary>
 			///     [W]
diff --git a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs
index 84c3ca603506ade23b7e9e778fe99f718e9f57d2..405bb80e321d12ae8e03ae0f284d075a275bd419 100644
--- a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs
@@ -50,7 +50,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
         #region ITnOutPort
 
-        IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, RadianPerSecond engineSpeed)
+        IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed)
         {
             if (_outPort == null) {
                 Log.ErrorFormat("{0} cannot handle incoming request - no outport available", absTime);
@@ -60,7 +60,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
             }
             _powerDemand = _demand.GetPowerDemand(absTime, dt);
             var tq = Formulas.PowerToTorque(_powerDemand, engineSpeed);
-            return _outPort.Request(absTime, dt, (torque + tq).To<NewtonMeter>(), engineSpeed);
+            return _outPort.Request(absTime, dt, torque + tq, engineSpeed);
         }
 
         #endregion
diff --git a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs
index c50186a671dd51d0363ea44c7adc95c84d08cda7..50b9421f52c7595b79f39f4cf072af8a843999bd 100644
--- a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyGearbox.cs
@@ -52,7 +52,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
         #region ITnOutPort
 
-        IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, RadianPerSecond engineSpeed)
+        IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed)
         {
             if (_outPort == null) {
                 Log.ErrorFormat("{0} cannot handle incoming request - no outport available", absTime);
diff --git a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
index 4340c4d7860eaf4e4d2b928d473e5e416578d273..46abd5a94fb77d1a4688255b222e0a521fadd28f 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Gearbox.cs
@@ -41,7 +41,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 	
         #region ITnOutPort
 
-        IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, RadianPerSecond engineSpeed)
+        IResponse ITnOutPort.Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond engineSpeed)
         {
             throw new NotImplementedException();
         }
diff --git a/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs
index 973f35ba1f97f68e26804567578201b7e40a3d5f..ad01e68fe628a215ea5b18f64bc62480dc3e0c31 100644
--- a/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs
@@ -51,7 +51,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
             }
 
             return _outPort.Request(absTime, dt, Data.Entries[index].VehicleSpeed,
-                Data.Entries[index].RoadGradient.SI().GradientPercent.To<Radian>());
+                Data.Entries[index].RoadGradient.SI().GradientPercent.Cast<Radian>());
         }
 
         #endregion
diff --git a/VectoCore/Utils/DoubleExtensionMethods.cs b/VectoCore/Utils/DoubleExtensionMethods.cs
index c77746f498884fa43a1f444ecda5ff7b69fdd2cb..1daa25650ce682602be33a5de5f4a6afaad90726 100644
--- a/VectoCore/Utils/DoubleExtensionMethods.cs
+++ b/VectoCore/Utils/DoubleExtensionMethods.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Diagnostics.Contracts;
 
 namespace TUGraz.VectoCore.Utils
 {
@@ -7,62 +6,62 @@ namespace TUGraz.VectoCore.Utils
 	{
 		public const double Tolerance = 0.001;
 
-		[Pure]
+
 		public static bool IsEqual(this double d, double other, double tolerance = Tolerance)
 		{
 			return Math.Abs(d - other) > -tolerance;
 		}
 
-		[Pure]
 		public static bool IsSmaller(this double d, double other, double tolerance = Tolerance)
 		{
 			return d - other < tolerance;
 		}
 
-		[Pure]
 		public static bool IsSmallerOrEqual(this double d, double other, double tolerance = Tolerance)
 		{
 			return d - other <= tolerance;
 		}
 
-		[Pure]
 		public static bool IsGreater(this double d, double other, double tolerance = Tolerance)
 		{
 			return other.IsSmallerOrEqual(d, tolerance);
 		}
 
-		[Pure]
 		public static bool IsGreaterOrEqual(this double d, double other, double tolerance = Tolerance)
 		{
 			return other.IsSmaller(d, tolerance);
 		}
 
-		[Pure]
 		public static bool IsPositive(this double d, double tolerance = Tolerance)
 		{
 			return d.IsGreaterOrEqual(0.0, tolerance);
 		}
 
-		public static RadianPerSecond RPMtoRad(this double d)
+		/// <summary>
+		/// Converts the double-value from rounds per minute to the SI Unit PerSecond
+		/// </summary>
+		/// <param name="d"></param>
+		/// <returns></returns>
+		public static PerSecond RPMtoRad(this double d)
 		{
-			return d.SI().Rounds.Per.Minute.To<RadianPerSecond>();
+			return d.SI().Rounds.Per.Minute.ConvertTo().Radian.Per.Second.Cast<PerSecond>();
 		}
 
 		/// <summary>
-		///     Gets the SI representation of the double (unit-less).
+		///     Gets the SI representation of the number (unit-less).
 		/// </summary>
-		/// <param name="d"></param>
-		/// <returns></returns>
-		[Pure]
 		public static SI SI(this double d)
 		{
 			return (SI) d;
 		}
 
-		[Pure]
-		public static T SI<T>(this double d) where T : SI
+
+		/// <summary>
+		/// Gets the special SI class of the number.
+		/// </summary>
+		public static T SI<T>(this double d) where T : SIBase<T>, new()
 		{
-			return (T) Activator.CreateInstance(typeof (T), d);
+			return SIBase<T>.Create(d);
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Utils/Formulas.cs b/VectoCore/Utils/Formulas.cs
index a25fafcd3611edf3e77d34dcc045b77a0437be70..1dfe96caaef92dd32107f51052b42accfe10d2dc 100644
--- a/VectoCore/Utils/Formulas.cs
+++ b/VectoCore/Utils/Formulas.cs
@@ -1,5 +1,3 @@
-using System.Diagnostics.Contracts;
-
 namespace TUGraz.VectoCore.Utils
 {
 	public static class Formulas
@@ -8,24 +6,22 @@ namespace TUGraz.VectoCore.Utils
 		///     [Nm], [rad/s] => [W]. Calculates the power from torque and angular velocity.
 		/// </summary>
 		/// <param name="torque">[Nm]</param>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>power [W]</returns>
-		[Pure]
-		public static Watt TorqueToPower(NewtonMeter torque, RadianPerSecond angularFrequency)
+		public static Watt TorqueToPower(NewtonMeter torque, PerSecond angularVelocity)
 		{
-			return (torque * angularFrequency).To<Watt>();
+			return torque * angularVelocity;
 		}
 
 		/// <summary>
 		///     [W], [rad/s] => [Nm]. Calculates the torque from power and angular velocity.
 		/// </summary>
 		/// <param name="power">[W]</param>
-		/// <param name="angularFrequency">[rad/s]</param>
+		/// <param name="angularVelocity">[rad/s]</param>
 		/// <returns>torque [Nm]</returns>
-		[Pure]
-		public static NewtonMeter PowerToTorque(SI power, RadianPerSecond angularFrequency)
+		public static NewtonMeter PowerToTorque(Watt power, PerSecond angularVelocity)
 		{
-			return (power / angularFrequency).To<NewtonMeter>();
+			return power / angularVelocity;
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Utils/IntExtensionMethods.cs b/VectoCore/Utils/IntExtensionMethods.cs
index 3c1dde275d53f6a0fdb5c726bd7577cfc9d6f170..0075574fbf4b245c924c328da76a9b59cec7f012 100644
--- a/VectoCore/Utils/IntExtensionMethods.cs
+++ b/VectoCore/Utils/IntExtensionMethods.cs
@@ -5,15 +5,34 @@ namespace TUGraz.VectoCore.Utils
 {
 	public static class IntExtensionMethods
 	{
-		public static SI SI(this int i)
+		/// <summary>
+		/// Converts the value from rounds per minute to the SI Unit PerSecond
+		/// </summary>
+		/// <param name="d"></param>
+		/// <returns></returns>
+		public static PerSecond RPMtoRad(this int d)
 		{
-			return new SI(i);
+			return d.SI().Rounds.Per.Minute.ConvertTo().Radian.Per.Second.Cast<PerSecond>();
 		}
 
-		[Pure]
-		public static T SI<T>(this int d) where T : SI
+		/// <summary>
+		/// Gets the SI representation of the number (unit-less).
+		/// </summary>
+		/// <param name="d"></param>
+		/// <returns></returns>
+		public static SI SI(this int d)
 		{
-			return (T) Activator.CreateInstance(typeof (T), d);
+			return (SI) d;
+		}
+
+		/// <summary>
+		/// Gets the special SI class of the number.
+		/// </summary>
+		/// <param name="d"></param>
+		/// <returns></returns>
+		public static T SI<T>(this int d) where T : SIBase<T>, new()
+		{
+			return SIBase<T>.Create(d);
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs
index e18adcfa9140b2dbff6ab45dafb7515d9b1a8c64..82a168b371c360553dd1345147f699c56ad7568d 100644
--- a/VectoCore/Utils/SI.cs
+++ b/VectoCore/Utils/SI.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Linq;
 using System.Runtime.Serialization;
@@ -8,68 +9,250 @@ using TUGraz.VectoCore.Exceptions;
 
 namespace TUGraz.VectoCore.Utils
 {
-	public class MeterPerSecond : SI
+	public class MeterPerSecond : SIBase<MeterPerSecond>
 	{
-		public MeterPerSecond(double val = 0) : base(val, new SI().Meter.Per.Second) {}
+		public MeterPerSecond() : this(0) {}
+		protected MeterPerSecond(double val) : base(val, new SI().Meter.Per.Second) {}
 	}
 
-	public class Radian : SI
+	public class Second : SIBase<Second>
 	{
-		public Radian(double val = 0) : base(val, new SI().Radian) {}
+		public Second() : this(0) {}
+		protected Second(double val) : base(val, new SI().Second) {}
 	}
 
-	public class Second : SI
+	public class Watt : SIBase<Watt>
 	{
-		public Second(double val = 0) : base(val, new SI().Second) {}
+		public Watt() : this(0) {}
+		protected Watt(double val) : base(val, new SI().Watt) {}
+
+		public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter)
+		{
+			return ((watt as SI) / newtonMeter).Cast<PerSecond>();
+		}
+
+		public static NewtonMeter operator /(Watt watt, PerSecond perSecond)
+		{
+			return ((watt as SI) / perSecond).Cast<NewtonMeter>();
+		}
 	}
 
-	public class Watt : SI
+	public class PerSecond : SIBase<PerSecond>
 	{
-		public Watt(double val = 0) : base(val, new SI().Watt) {}
+		public PerSecond() : this(0) {}
+		protected PerSecond(double val) : base(val, new SI().Radian.Per.Second) {}
 	}
 
-	public class RadianPerSecond : SI
+	public class RoundsPerMinute : SIBase<RoundsPerMinute>
 	{
-		public RadianPerSecond(double val = 0) : base(val, new SI().Radian.Per.Second) {}
+		public RoundsPerMinute() : this(0) {}
+		protected RoundsPerMinute(double val) : base(val, new SI().Rounds.Per.Minute) {}
 	}
 
-	public class RoundsPerMinute : SI
+
+	public class Newton : SIBase<Newton>
 	{
-		public RoundsPerMinute(double val = 0) : base(val, new SI().Rounds.Per.Minute) {}
+		public Newton() : this(0) {}
+		protected Newton(double val) : base(val, new SI().Newton) {}
 	}
 
-	public class NewtonMeter : SI
+	public class Radian : SIBase<Radian>
 	{
-		public NewtonMeter(double val = 0) : base(val, new SI().Newton.Meter) {}
+		public Radian() : this(0) {}
+		protected Radian(double val) : base(val, new SI().Radian) {}
 	}
 
-	public class Newton : SI
+	public class NewtonMeter : SIBase<NewtonMeter>
 	{
-		public Newton(double val = 0) : base(val, new SI().Newton) {}
+		public NewtonMeter() : this(0) {}
+		protected NewtonMeter(double val) : base(val, new SI().Newton.Meter) {}
+
+		public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond)
+		{
+			return ((newtonMeter as SI) * perSecond).Cast<Watt>();
+		}
+
+		public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter)
+		{
+			return ((perSecond as SI) * newtonMeter).Cast<Watt>();
+		}
+
+		public static Second operator /(NewtonMeter newtonMeter, Watt watt)
+		{
+			return ((newtonMeter as SI) / watt).Cast<Second>();
+		}
 	}
 
 
+	public abstract class SIBase<T> : SI where T : SIBase<T>, new()
+	{
+		public static T Create(double val)
+		{
+			return new T { Val = val };
+		}
+
+		protected SIBase() {}
+		protected SIBase(double val) : base(val) {}
+		protected SIBase(double val, SI unit) : base(val, unit) {}
+
+		#region Operators
+
+		public static T operator +(SIBase<T> si1, SIBase<T> si2)
+		{
+			return (si1 as SI) + si2;
+		}
+
+		public static T operator +(SIBase<T> si1, SI si2)
+		{
+			return ((si1 as SI) + si2).Cast<T>();
+		}
+
+		public static T operator +(SI si1, SIBase<T> si2)
+		{
+			return si2 + si1;
+		}
+
+		public static T operator +(SIBase<T> si1, double d)
+		{
+			return ((si1 as SI) + d).Cast<T>();
+		}
+
+		public static T operator +(double d, SIBase<T> si)
+		{
+			return si + d;
+		}
+
+		public static T operator -(SIBase<T> si1, SIBase<T> si2)
+		{
+			return (si1 as SI) - si2;
+		}
+
+		public static T operator -(SIBase<T> si1, SI si2)
+		{
+			return -si2 + si1;
+		}
+
+		public static T operator -(SI si1, SIBase<T> si2)
+		{
+			return (si1 - (si2 as SI)).Cast<T>();
+		}
+
+		public static T operator -(SIBase<T> si, double d)
+		{
+			return ((si as SI) - d).Cast<T>();
+		}
+
+		public static T operator -(double d, SIBase<T> si)
+		{
+			return (d - (si as SI)).Cast<T>();
+		}
+
+		public static T operator *(double d, SIBase<T> si)
+		{
+			return si * d;
+		}
+
+		public static T operator *(SIBase<T> si, double d)
+		{
+			return ((si as SI) * d).Cast<T>();
+		}
+
+		public static T operator /(double d, SIBase<T> si)
+		{
+			return si / d;
+		}
+
+		public static T operator /(SIBase<T> si, double d)
+		{
+			return ((si as SI) / d).Cast<T>();
+		}
+
+		#endregion
+	}
+
+	/// <summary>
+	/// Class for Representing SI Units.
+	/// </summary>
 	[DataContract]
-	public class SI
+	public class SI : IComparable
 	{
-		[DataMember] protected readonly string[] Denominator;
+		[DataMember] protected readonly Unit[] Denominator;
 		[DataMember] protected readonly int Exponent;
-		[DataMember] protected readonly string[] Numerator;
+		[DataMember] protected readonly Unit[] Numerator;
 		[DataMember] protected readonly bool Reciproc;
 		[DataMember] protected readonly bool Reverse;
-		[DataMember] protected readonly double Val;
+		[DataMember] protected double Val;
+
+		[SuppressMessage("ReSharper", "InconsistentNaming")]
+		protected enum Unit
+		{
+			/// <summary>
+			/// kilo
+			/// </summary>
+			k,
+
+			/// <summary>
+			/// seconds
+			/// </summary>
+			s,
+
+			/// <summary>
+			/// meter
+			/// </summary>
+			m,
+
+			/// <summary>
+			/// gramm
+			/// </summary>
+			g,
+
+			/// <summary>
+			/// Watt
+			/// </summary>
+			W,
+
+			/// <summary>
+			/// Newton
+			/// </summary>
+			N,
+
+			/// <summary>
+			/// %
+			/// </summary>
+			Percent,
+
+			/// <summary>
+			/// minutes
+			/// </summary>
+			min,
+
+			/// <summary>
+			/// centi
+			/// </summary>
+			c,
+
+			/// <summary>
+			/// Hour
+			/// </summary>
+			h
+		}
 
+		/// <summary>
+		/// Creates a new dimensionless SI Unit.
+		/// </summary>
+		/// <param name="val"></param>
 		public SI(double val = 0.0)
 		{
 			Val = val;
 			Reciproc = false;
 			Reverse = false;
-			Numerator = new string[0];
-			Denominator = new string[0];
+			Numerator = new Unit[0];
+			Denominator = new Unit[0];
 			Exponent = 1;
 		}
 
-		protected SI(double val, IEnumerable<string> numerator, IEnumerable<string> denominator, bool reciproc = false,
+		protected SI(double val, IEnumerable<Unit> numerator, IEnumerable<Unit> denominator,
+			bool reciproc = false,
 			bool reverse = false, int exponent = 1)
 		{
 			Contract.Requires(numerator != null);
@@ -95,7 +278,7 @@ namespace TUGraz.VectoCore.Utils
 		protected SI(double val, SI unit)
 			: this(val, unit.Numerator, unit.Denominator) {}
 
-		protected SI(SI si, double? factor = null, string fromUnit = null, string toUnit = null,
+		protected SI(SI si, double? factor = null, Unit? fromUnit = null, Unit? toUnit = null,
 			bool? reciproc = null, bool? reverse = null, int? exponent = null)
 		{
 			Contract.Requires(si != null);
@@ -140,65 +323,81 @@ namespace TUGraz.VectoCore.Utils
 			Denominator = numerator.ToArray();
 		}
 
-		private void UpdateUnit(string fromUnit, string toUnit, ICollection<string> units)
+		private void UpdateUnit(Unit? fromUnit, Unit? toUnit, ICollection<Unit> units)
 		{
-			if (Reverse && !string.IsNullOrEmpty(fromUnit)) {
-				if (units.Contains(fromUnit)) {
-					units.Remove(fromUnit);
+			if (Reverse && fromUnit.HasValue) {
+				if (units.Contains(fromUnit.Value)) {
+					units.Remove(fromUnit.Value);
 				} else {
-					throw new VectoException("Unit missing. Conversion not possible.");
+					throw new VectoException(string.Format("Unit missing. Conversion not possible. [{0}] does not contain a [{1}].",
+						string.Join(", ", units), fromUnit));
 				}
 			}
 
-			if (!string.IsNullOrEmpty(toUnit)) {
-				units.Add(toUnit);
+			if (toUnit.HasValue) {
+				units.Add(toUnit.Value);
 			}
 		}
 
 		/// <summary>
-		///     Convert an SI unit into another SI unit, defined by term following after the To().
+		/// Converts the SI unit to another SI unit, defined by term(s) following after the ConvertTo().
+		/// The Conversion Mode is active until an arithmetic operator is used (+,-,*,/), 
+		/// or the .Value-Method, or the .Cast-Method were called.
+		/// ATTENTION: Before returning an SI Unit, ensure to cancel Conversion Mode (with .Value or .Cast).
 		/// </summary>
 		/// <returns></returns>
-		public SI To()
+		public SI ConvertTo()
 		{
 			return new SI(Linear, reciproc: false, reverse: true);
 		}
 
-		public T To<T>() where T : SI
+		/// <summary>
+		/// Casts the SI Unit to the concrete unit type (if the units allow such an cast).
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <returns></returns>
+		public T Cast<T>() where T : SIBase<T>, new()
 		{
-			var t = (T) Activator.CreateInstance(typeof (T), Val);
-			Contract.Assert(HasEqualUnit(t), string.Format("SI Unit Conversion failed: From {0} to {1}", this, t));
+			var t = SIBase<T>.Create(Val);
+			if (!HasEqualUnit(t)) {
+				throw new VectoException(string.Format("SI Unit Conversion failed: From {0} to {1}", this, t));
+			}
 			return t;
 		}
 
+		/// <summary>
+		/// Converts the derived SI units to the basic units and returns this as a new SI object.
+		/// </summary>
+		/// <returns></returns>
 		public SI ToBasicUnits()
 		{
-			var numerator = new List<string>();
-			var denominator = new List<string>();
+			var numerator = new List<Unit>();
+			var denominator = new List<Unit>();
 			Numerator.ToList().ForEach(unit => ConvertToBasicUnits(unit, numerator, denominator));
 			Denominator.ToList().ForEach(unit => ConvertToBasicUnits(unit, denominator, numerator));
 			return new SI(Val, numerator, denominator);
 		}
 
-		private static void ConvertToBasicUnits(string unit, ICollection<string> numerator,
-			ICollection<string> denominator)
+
+		private static void ConvertToBasicUnits(Unit unit, ICollection<Unit> numerator,
+			ICollection<Unit> denominator)
 		{
 			switch (unit) {
-				case "W":
-					numerator.Add("k");
-					numerator.Add("g");
-					numerator.Add("m");
-					numerator.Add("m");
-					denominator.Add("s");
-					denominator.Add("s");
-					denominator.Add("s");
+				case Unit.W:
+					numerator.Add(Unit.k);
+					numerator.Add(Unit.g);
+					numerator.Add(Unit.m);
+					numerator.Add(Unit.m);
+					denominator.Add(Unit.s);
+					denominator.Add(Unit.s);
+					denominator.Add(Unit.s);
 					break;
-				case "N":
-					numerator.Add("k");
-					numerator.Add("g");
-					numerator.Add("m");
-					denominator.Add("s");
-					denominator.Add("s");
+				case Unit.N:
+					numerator.Add(Unit.k);
+					numerator.Add(Unit.g);
+					numerator.Add(Unit.m);
+					denominator.Add(Unit.s);
+					denominator.Add(Unit.s);
 					break;
 				default:
 					numerator.Add(unit);
@@ -207,9 +406,9 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Gets the basic scalar value.
+		///     Gets the basic double value.
 		/// </summary>
-		protected double ScalarValue()
+		public double Double()
 		{
 			return Val;
 		}
@@ -268,7 +467,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Gramm
 		{
-			get { return new SI(new SI(this, toUnit: "k"), 0.001, "g", "g"); }
+			get { return new SI(new SI(this, toUnit: Unit.k), 0.001, Unit.g, Unit.g); }
 		}
 
 		/// <summary>
@@ -277,7 +476,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Newton
 		{
-			get { return new SI(this, fromUnit: "N", toUnit: "N"); }
+			get { return new SI(this, fromUnit: Unit.N, toUnit: Unit.N); }
 		}
 
 		/// <summary>
@@ -286,7 +485,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Watt
 		{
-			get { return new SI(this, fromUnit: "W", toUnit: "W"); }
+			get { return new SI(this, fromUnit: Unit.W, toUnit: Unit.W); }
 		}
 
 		/// <summary>
@@ -295,7 +494,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Meter
 		{
-			get { return new SI(this, fromUnit: "m", toUnit: "m"); }
+			get { return new SI(this, fromUnit: Unit.m, toUnit: Unit.m); }
 		}
 
 		/// <summary>
@@ -304,7 +503,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Second
 		{
-			get { return new SI(this, fromUnit: "s", toUnit: "s"); }
+			get { return new SI(this, fromUnit: Unit.s, toUnit: Unit.s); }
 		}
 
 		/// <summary>
@@ -313,12 +512,12 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Radian
 		{
-			get { return new SI(this, fromUnit: "rad", toUnit: "rad"); }
+			get { return new SI(this); }
 		}
 
 		public SI GradientPercent
 		{
-			get { return new SI(this, factor: Math.Atan(Val) / Val, fromUnit: "%", toUnit: "rad"); }
+			get { return new SI(this, factor: Math.Atan(Val) / Val, fromUnit: Unit.Percent); }
 		}
 
 		/// <summary>
@@ -327,7 +526,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Rounds
 		{
-			get { return new SI(this, 2 * Math.PI, toUnit: "rad"); }
+			get { return new SI(this, 2 * Math.PI); }
 		}
 
 		/// <summary>
@@ -336,7 +535,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Hour
 		{
-			get { return new SI(this, 3600.0, "h", "s"); }
+			get { return new SI(this, 3600.0, Unit.h, Unit.s); }
 		}
 
 		/// <summary>
@@ -345,7 +544,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Minute
 		{
-			get { return new SI(this, 60.0, "min", "s"); }
+			get { return new SI(this, 60.0, Unit.min, Unit.s); }
 		}
 
 		/// <summary>
@@ -354,7 +553,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Kilo
 		{
-			get { return new SI(this, 1000.0, "k"); }
+			get { return new SI(this, 1000.0, Unit.k); }
 		}
 
 		/// <summary>
@@ -363,7 +562,7 @@ namespace TUGraz.VectoCore.Utils
 		[DebuggerHidden]
 		public SI Centi
 		{
-			get { return new SI(this, 1.0 / 100.0, "c"); }
+			get { return new SI(this, 1.0 / 100.0, Unit.c); }
 		}
 
 		#endregion
@@ -372,29 +571,34 @@ namespace TUGraz.VectoCore.Utils
 
 		public static SI operator +(SI si1, SI si2)
 		{
-			Contract.Requires(si1.HasEqualUnit(si2));
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+			}
 
 			return new SI(si1.Val + si2.Val, si1.Numerator, si1.Denominator);
 		}
 
 		public static SI operator -(SI si1, SI si2)
 		{
-			Contract.Requires(si1.HasEqualUnit(si2));
-
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '-' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+			}
 			return new SI(si1.Val - si2.Val, si1.Numerator, si1.Denominator);
 		}
 
 		public static SI operator *(SI si1, SI si2)
 		{
-			var numerator = si1.Numerator.Concat(si2.Numerator).Where(d => d != "rad");
-			var denominator = si1.Denominator.Concat(si2.Denominator).Where(d => d != "rad");
+			var numerator = si1.Numerator.Concat(si2.Numerator);
+			var denominator = si1.Denominator.Concat(si2.Denominator);
 			return new SI(si1.Val * si2.Val, numerator, denominator);
 		}
 
 		public static SI operator /(SI si1, SI si2)
 		{
-			var numerator = si1.Numerator.Concat(si2.Denominator).Where(d => d != "rad");
-			var denominator = si1.Denominator.Concat(si2.Numerator).Where(d => d != "rad");
+			var numerator = si1.Numerator.Concat(si2.Denominator);
+			var denominator = si1.Denominator.Concat(si2.Numerator);
 			return new SI(si1.Val / si2.Val, numerator, denominator);
 		}
 
@@ -403,11 +607,26 @@ namespace TUGraz.VectoCore.Utils
 			return new SI(si1.Val + d, si1);
 		}
 
+		public static SI operator +(double d, SI si1)
+		{
+			return si1 + d;
+		}
+
 		public static SI operator -(SI si1, double d)
 		{
 			return new SI(si1.Val - d, si1);
 		}
 
+		public static SI operator -(double d, SI si1)
+		{
+			return new SI(d - si1.Val, si1);
+		}
+
+		public static SI operator -(SI si1)
+		{
+			return 0 - si1;
+		}
+
 		public static SI operator *(SI si1, double d)
 		{
 			return new SI(si1.Val * d, si1);
@@ -430,25 +649,37 @@ namespace TUGraz.VectoCore.Utils
 
 		public static bool operator <(SI si1, SI si2)
 		{
-			Contract.Requires(si1.HasEqualUnit(si2));
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '<' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+			}
 			return si1.Val < si2.Val;
 		}
 
 		public static bool operator >(SI si1, SI si2)
 		{
-			Contract.Requires(si1.HasEqualUnit(si2));
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '>' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+			}
 			return si1.Val > si2.Val;
 		}
 
 		public static bool operator <=(SI si1, SI si2)
 		{
-			Contract.Requires(si1.HasEqualUnit(si2));
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+			}
 			return si1.Val <= si2.Val;
 		}
 
 		public static bool operator >=(SI si1, SI si2)
 		{
-			Contract.Requires(si1.HasEqualUnit(si2));
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+			}
 			return si1.Val >= si2.Val;
 		}
 
@@ -528,6 +759,14 @@ namespace TUGraz.VectoCore.Utils
 			return string.Format("{0} [{1}]", Val, GetUnitString());
 		}
 
+		public virtual string ToString(string format)
+		{
+			if (string.IsNullOrEmpty(format)) {
+				format = "";
+			}
+			return string.Format("{0:" + format + "} [{2}]", Val, format, GetUnitString());
+		}
+
 		#endregion
 
 		#region Equality members
@@ -545,11 +784,6 @@ namespace TUGraz.VectoCore.Utils
 					ToBasicUnits().Numerator.OrderBy(x => x).SequenceEqual(si.ToBasicUnits().Numerator.OrderBy(x => x));
 		}
 
-		protected bool Equals(SI other)
-		{
-			return Val.Equals(other.Val) && HasEqualUnit(other);
-		}
-
 		public override bool Equals(object obj)
 		{
 			if (ReferenceEquals(null, obj)) {
@@ -559,12 +793,13 @@ namespace TUGraz.VectoCore.Utils
 				return true;
 			}
 			var other = obj as SI;
-			return other != null && Equals(other);
+			return other != null && Val.Equals(other.Val) && HasEqualUnit(other);
 		}
 
 		public override int GetHashCode()
 		{
 			unchecked {
+				// ReSharper disable once NonReadonlyMemberInGetHashCode
 				var hashCode = Val.GetHashCode();
 				hashCode = (hashCode * 397) ^ (Numerator != null ? Numerator.GetHashCode() : 0);
 				hashCode = (hashCode * 397) ^ (Denominator != null ? Denominator.GetHashCode() : 0);
@@ -572,6 +807,26 @@ namespace TUGraz.VectoCore.Utils
 			}
 		}
 
+		public int CompareTo(object obj)
+		{
+			var si = (obj as SI);
+			if (si == null) {
+				return 1;
+			}
+
+			if (!HasEqualUnit(si)) {
+				if (si.Numerator.Length + si.Denominator.Length <= Numerator.Length + Denominator.Length) {
+					return -1;
+				}
+				return 1;
+			}
+
+			if (this > si) {
+				return 1;
+			}
+			return this < si ? -1 : 0;
+		}
+
 		public static bool operator ==(SI left, SI right)
 		{
 			return Equals(left, right);
diff --git a/VectoCore/Utils/VectoMath.cs b/VectoCore/Utils/VectoMath.cs
index 61f2f91eb4350b906c8ecdbe49164db7898b615d..71a8fb44a3a0e8bc681175a8b94db1da1f51ac87 100644
--- a/VectoCore/Utils/VectoMath.cs
+++ b/VectoCore/Utils/VectoMath.cs
@@ -1,3 +1,7 @@
+using System;
+using Common.Logging.Factory;
+using NLog.LayoutRenderers.Wrappers;
+
 namespace TUGraz.VectoCore.Utils
 {
 	public class VectoMath
@@ -6,5 +10,26 @@ namespace TUGraz.VectoCore.Utils
 		{
 			return (xint - x1) * (y2 - y1) / (x2 - x1) + y1;
 		}
+
+		public static SI Abs(SI si)
+		{
+			return si.Abs();
+		}
+
+
+		public static T Abs<T>(T si) where T : SIBase<T>, new()
+		{
+			return si.Abs().Cast<T>();
+		}
+
+		public static T Min<T>(T c1, T c2) where T : IComparable
+		{
+			return c1.CompareTo(c2) <= 0 ? c1 : c2;
+		}
+
+		public static T Max<T>(T c1, T c2) where T : IComparable
+		{
+			return c1.CompareTo(c2) >= 0 ? c1 : c2;
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs
index fed1acc518e77191ac550ada18debb9d8436c498..35d4f7f444d6702a42e9ce00314e7fd64c073b71 100644
--- a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs
+++ b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs
@@ -10,91 +10,91 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Tests.Models.Simulation
 {
-    [TestClass]
-    public class DrivingCycleTests
-    {
-        [TestMethod]
-        public void TestEngineOnly()
-        {
-            var container = new VehicleContainer();
+	[TestClass]
+	public class DrivingCycleTests
+	{
+		[TestMethod]
+		public void TestEngineOnly()
+		{
+			var container = new VehicleContainer();
 
-            var cycleData = DrivingCycleData.ReadFromFileEngineOnly(@"TestData\Cycles\Coach Engine Only.vdri");
-            var cycle = new EngineOnlyDrivingCycle(container, cycleData);
+			var cycleData = DrivingCycleData.ReadFromFileEngineOnly(@"TestData\Cycles\Coach Engine Only.vdri");
+			var cycle = new EngineOnlyDrivingCycle(container, cycleData);
 
-            var outPort = new MockTnOutPort();
-            var inPort = cycle.InShaft();
-            var cycleOut = cycle.OutPort();
+			var outPort = new MockTnOutPort();
+			var inPort = cycle.InShaft();
+			var cycleOut = cycle.OutPort();
 
-            inPort.Connect(outPort);
+			inPort.Connect(outPort);
 
-            var absTime = new TimeSpan();
-            var dt = TimeSpan.FromSeconds(1);
+			var absTime = new TimeSpan();
+			var dt = TimeSpan.FromSeconds(1);
 
-            var response = cycleOut.Request(absTime, dt);
-            Assert.IsInstanceOfType(response, typeof (ResponseSuccess));
+			var response = cycleOut.Request(absTime, dt);
+			Assert.IsInstanceOfType(response, typeof (ResponseSuccess));
 
-            var dataWriter = new TestModalDataWriter();
-            container.CommitSimulationStep(dataWriter);
+			var dataWriter = new TestModalDataWriter();
+			container.CommitSimulationStep(dataWriter);
 
-            Assert.AreEqual(absTime, outPort.AbsTime);
-            Assert.AreEqual(dt, outPort.Dt);
-            Assert.AreEqual(600.0.RPMtoRad(), outPort.AngularFrequency);
-            Assert.AreEqual(0.SI<NewtonMeter>(), outPort.Torque);
-        }
+			Assert.AreEqual(absTime, outPort.AbsTime);
+			Assert.AreEqual(dt, outPort.Dt);
+			Assert.AreEqual(600.0.RPMtoRad(), outPort.AngularVelocity);
+			Assert.AreEqual(0.SI<NewtonMeter>(), outPort.Torque);
+		}
 
-        [TestMethod]
-        public void Test_TimeBased_FirstCycle()
-        {
-            var container = new VehicleContainer();
+		[TestMethod]
+		public void Test_TimeBased_FirstCycle()
+		{
+			var container = new VehicleContainer();
 
-            var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Coach time based.vdri");
-            var cycle = new TimeBasedDrivingCycle(container, cycleData);
+			var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Coach time based.vdri");
+			var cycle = new TimeBasedDrivingCycle(container, cycleData);
 
-            var outPort = new MockDriverDemandOutPort();
+			var outPort = new MockDriverDemandOutPort();
 
-            var inPort = cycle.InPort();
-            var cycleOut = cycle.OutPort();
+			var inPort = cycle.InPort();
+			var cycleOut = cycle.OutPort();
 
-            inPort.Connect(outPort);
+			inPort.Connect(outPort);
 
-            var absTime = new TimeSpan();
-            var dt = TimeSpan.FromSeconds(1);
+			var absTime = new TimeSpan();
+			var dt = TimeSpan.FromSeconds(1);
 
-            var response = cycleOut.Request(absTime, dt);
-            Assert.IsInstanceOfType(response, typeof (ResponseSuccess));
+			var response = cycleOut.Request(absTime, dt);
+			Assert.IsInstanceOfType(response, typeof (ResponseSuccess));
 
-            Assert.AreEqual(absTime, outPort.AbsTime);
-            Assert.AreEqual(dt, outPort.Dt);
-            Assert.AreEqual(0.0.SI<MeterPerSecond>(), outPort.Velocity);
-            Assert.AreEqual((-0.020237973).SI().GradientPercent.To<Radian>(), outPort.Gradient);
-        }
+			Assert.AreEqual(absTime, outPort.AbsTime);
+			Assert.AreEqual(dt, outPort.Dt);
+			Assert.AreEqual(0.0.SI<MeterPerSecond>(), outPort.Velocity);
+			Assert.AreEqual((-0.020237973).SI().GradientPercent.Cast<Radian>(), outPort.Gradient);
+		}
 
-        [TestMethod]
-        public void Test_TimeBased_TimeFieldMissing()
-        {
-            var container = new VehicleContainer();
+		[TestMethod]
+		public void Test_TimeBased_TimeFieldMissing()
+		{
+			var container = new VehicleContainer();
 
-            var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Cycle time field missing.vdri");
-            var cycle = new TimeBasedDrivingCycle(container, cycleData);
+			var cycleData = DrivingCycleData.ReadFromFileTimeBased(@"TestData\Cycles\Cycle time field missing.vdri");
+			var cycle = new TimeBasedDrivingCycle(container, cycleData);
 
-            var outPort = new MockDriverDemandOutPort();
+			var outPort = new MockDriverDemandOutPort();
 
-            var inPort = cycle.InPort();
-            var cycleOut = cycle.OutPort();
+			var inPort = cycle.InPort();
+			var cycleOut = cycle.OutPort();
 
-            inPort.Connect(outPort);
+			inPort.Connect(outPort);
 
-            var dataWriter = new TestModalDataWriter();
-            var absTime = new TimeSpan();
-            var dt = TimeSpan.FromSeconds(1);
+			var dataWriter = new TestModalDataWriter();
+			var absTime = new TimeSpan();
+			var dt = TimeSpan.FromSeconds(1);
 
-            while (cycleOut.Request(absTime, dt) is ResponseSuccess) {
-                Assert.AreEqual(absTime, outPort.AbsTime);
-                Assert.AreEqual(dt, outPort.Dt);
-                container.CommitSimulationStep(dataWriter);
+			while (cycleOut.Request(absTime, dt) is ResponseSuccess) {
+				Assert.AreEqual(absTime, outPort.AbsTime);
+				Assert.AreEqual(dt, outPort.Dt);
+				container.CommitSimulationStep(dataWriter);
 
-                absTime += dt;
-            }
-        }
-    }
+				absTime += dt;
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs
index 9ba69f9cdf8ea0d23c3826618a656bc0c731252b..dd0e4772335baa21345738d91082a6de59a9d8d9 100644
--- a/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs
+++ b/VectoCoreTest/Models/SimulationComponent/CombustionEngineTest.cs
@@ -65,7 +65,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 			var absTime = new TimeSpan(seconds: 0, minutes: 0, hours: 0);
 			var dt = new TimeSpan(seconds: 1, minutes: 0, hours: 0);
 
-			var torque = new NewtonMeter();
+			var torque = 0.SI<NewtonMeter>();
 			var engineSpeed = 600.0.RPMtoRad();
 			var dataWriter = new TestModalDataWriter();
 
diff --git a/VectoCoreTest/Models/SimulationComponent/MockPorts.cs b/VectoCoreTest/Models/SimulationComponent/MockPorts.cs
index 0ede14df24ca885ccbfddd3a425ac0eeba14eb1c..d0f5b37d5036f6495ec5591da8cf7b89e8a1c5a6 100644
--- a/VectoCoreTest/Models/SimulationComponent/MockPorts.cs
+++ b/VectoCoreTest/Models/SimulationComponent/MockPorts.cs
@@ -6,41 +6,41 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 {
-    public class MockTnOutPort : ITnOutPort
-    {
-        public TimeSpan AbsTime { get; set; }
-        public TimeSpan Dt { get; set; }
-        public NewtonMeter Torque { get; set; }
-		public RadianPerSecond AngularFrequency { get; set; }
+	public class MockTnOutPort : ITnOutPort
+	{
+		public TimeSpan AbsTime { get; set; }
+		public TimeSpan Dt { get; set; }
+		public NewtonMeter Torque { get; set; }
+		public PerSecond AngularVelocity { get; set; }
 
-		public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, RadianPerSecond angularFrequency)
-        {
-            AbsTime = absTime;
-            Dt = dt;
-            Torque = torque;
-            AngularFrequency = angularFrequency;
-            LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, torque: {3}, engineSpeed: {4}",
-                absTime, dt, torque, angularFrequency);
-            return new ResponseSuccess();
-        }
-    }
+		public IResponse Request(TimeSpan absTime, TimeSpan dt, NewtonMeter torque, PerSecond angularVelocity)
+		{
+			AbsTime = absTime;
+			Dt = dt;
+			Torque = torque;
+			AngularVelocity = angularVelocity;
+			LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, torque: {3}, engineSpeed: {4}",
+				absTime, dt, torque, angularVelocity);
+			return new ResponseSuccess();
+		}
+	}
 
-    public class MockDriverDemandOutPort : IDriverDemandOutPort
-    {
-        public TimeSpan AbsTime { get; set; }
-        public TimeSpan Dt { get; set; }
-        public MeterPerSecond Velocity { get; set; }
-        public Radian Gradient { get; set; }
+	public class MockDriverDemandOutPort : IDriverDemandOutPort
+	{
+		public TimeSpan AbsTime { get; set; }
+		public TimeSpan Dt { get; set; }
+		public MeterPerSecond Velocity { get; set; }
+		public Radian Gradient { get; set; }
 
-        public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient)
-        {
-            AbsTime = absTime;
-            Dt = dt;
-            Velocity = velocity;
-            Gradient = gradient;
-            LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, velocity: {3}, gradient: {4}",
-                absTime, dt, velocity, gradient);
-            return new ResponseSuccess();
-        }
-    }
+		public IResponse Request(TimeSpan absTime, TimeSpan dt, MeterPerSecond velocity, Radian gradient)
+		{
+			AbsTime = absTime;
+			Dt = dt;
+			Velocity = velocity;
+			Gradient = gradient;
+			LogManager.GetLogger(GetType()).DebugFormat("Request: absTime: {0}, dt: {1}, velocity: {3}, gradient: {4}",
+				absTime, dt, velocity, gradient);
+			return new ResponseSuccess();
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs b/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
index 5061ea58ae918e3592f0fe39222cae9914ede78c..965f39a46cf39a3dbd150c770b95f39bc0af5f2d 100644
--- a/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
+++ b/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
@@ -8,41 +8,41 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 {
-	[TestClass]
-	public class FuelConsumptionMapTest
-	{
-		private const double Tolerance = 0.0001;
+    [TestClass]
+    public class FuelConsumptionMapTest
+    {
+        private const double Tolerance = 0.0001;
 
-		[TestMethod]
-		public void TestFuelConsumption_FixedPoints()
-		{
-			var map = FuelConsumptionMap.ReadFromFile(@"TestData\Components\24t Coach.vmap");
-			var lines = File.ReadAllLines(@"TestData\Components\24t Coach.vmap").Skip(1).ToArray();
-			AssertMapValuesEqual(lines, map);
-		}
+        [TestMethod]
+        public void TestFuelConsumption_FixedPoints()
+        {
+            var map = FuelConsumptionMap.ReadFromFile(@"TestData\Components\24t Coach.vmap");
+            var lines = File.ReadAllLines(@"TestData\Components\24t Coach.vmap").Skip(1).ToArray();
+            AssertMapValuesEqual(lines, map);
+        }
 
-		[TestMethod]
-		public void TestFuelConsumption_InterpolatedPoints()
-		{
-			var map = FuelConsumptionMap.ReadFromFile(@"TestData\Components\24t Coach.vmap");
-			var lines = File.ReadAllLines(@"TestData\Components\24t CoachInterpolated.vmap").Skip(1).ToArray();
-			AssertMapValuesEqual(lines, map);
-		}
+        [TestMethod]
+        public void TestFuelConsumption_InterpolatedPoints()
+        {
+            var map = FuelConsumptionMap.ReadFromFile(@"TestData\Components\24t Coach.vmap");
+            var lines = File.ReadAllLines(@"TestData\Components\24t CoachInterpolated.vmap").Skip(1).ToArray();
+            AssertMapValuesEqual(lines, map);
+        }
 
-		private static void AssertMapValuesEqual(string[] lines, FuelConsumptionMap map)
-		{
-			for (var i = 1; i < lines.Count(); i++) {
-				var entry = lines[i].Split(',').Select(x => double.Parse(x, CultureInfo.InvariantCulture)).ToArray();
-				try {
-					Assert.AreEqual((double) entry[2].SI().Gramm.Per.Hour.To().Kilo.Gramm.Per.Second,
-						(double) map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad()),
-						Tolerance,
-						string.Format("Line: {0}, n={1}, T={2}", (i + 2), entry[0].SI().Rounds.Per.Minute, entry[1]));
-				} catch (VectoException ex) {
-					throw new VectoException(string.Format("Row {0}: Error in ConsumptionMap n={1}, T={2}: {3}",
-						i + 2, entry[0], entry[1], ex.Message));
-				}
-			}
-		}
-	}
+        private static void AssertMapValuesEqual(string[] lines, FuelConsumptionMap map)
+        {
+            for (var i = 1; i < lines.Count(); i++) {
+                var entry = lines[i].Split(',').Select(x => double.Parse(x, CultureInfo.InvariantCulture)).ToArray();
+                try {
+                    Assert.AreEqual((double) entry[2].SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second,
+                        (double) map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad()),
+                        Tolerance,
+                        string.Format("Line: {0}, n={1}, T={2}", (i + 2), entry[0].SI().Rounds.Per.Minute, entry[1]));
+                } catch (VectoException ex) {
+                    throw new VectoException(string.Format("Row {0}: Error in ConsumptionMap n={1}, T={2}: {3}",
+                        i + 2, entry[0], entry[1], ex.Message));
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs
index 07f97e2aba1fc8601fb1f8f982d636d942f4832e..6de77a4a1bcf63188d7d469e5e159dad801fc411 100644
--- a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs
+++ b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs
@@ -101,7 +101,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 		public void Test_FileRead_NoHeader()
 		{
 			var curve = FullLoadCurve.ReadFromFile(@"TestData\Components\FullLoadCurve no header.vfld");
-			var result = curve.FullLoadStationaryTorque(1.SI<RadianPerSecond>());
+			var result = curve.FullLoadStationaryTorque(1.SI<PerSecond>());
 			Assert.AreNotEqual((double) result, 0.0);
 		}
 
diff --git a/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs b/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..21d802107dedb390e230f7ed1e36d8b7e2d2525e
--- /dev/null
+++ b/VectoCoreTest/Utils/DoubleExtensionMethodTest.cs
@@ -0,0 +1,29 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Tests.Utils
+{
+	[TestClass]
+	public class DoubleExtensionMethodTest
+	{
+		[TestMethod]
+		public void DoubleExtensions_SI_Test()
+		{
+			var val = 600.0.RPMtoRad();
+			Assert.AreEqual(600 / 60 * 2 * Math.PI, val.Double());
+
+			Assert.IsTrue(0.0.SI<PerSecond>().HasEqualUnit(val));
+
+			var val2 = 1200.0.SI().Rounds.Per.Minute.ConvertTo().Radian.Per.Second.Cast<PerSecond>();
+			val = val * 2;
+			Assert.AreEqual(val, val2);
+
+			val2 = val2 / 2;
+			val = val / 2;
+			Assert.AreEqual(val, val2);
+			Assert.AreEqual(600.SI().Rounds.Per.Minute.Cast<PerSecond>(), val2);
+			Assert.AreEqual(600.SI().Rounds.Per.Minute.Cast<PerSecond>().Double(), val2.Double());
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCoreTest/Utils/SITest.cs b/VectoCoreTest/Utils/SITest.cs
index 05e6394e4fb702ef27e9da163f3c07853c9f9a45..94325d67b9e5c293821c32d2461d040534d13769 100644
--- a/VectoCoreTest/Utils/SITest.cs
+++ b/VectoCoreTest/Utils/SITest.cs
@@ -1,5 +1,7 @@
 using System;
+using System.Diagnostics.CodeAnalysis;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
+using TUGraz.VectoCore.Exceptions;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Tests.Utils
@@ -7,21 +9,98 @@ namespace TUGraz.VectoCore.Tests.Utils
 	[TestClass]
 	public class SITest
 	{
-		public static void AssertException<T>(Action func, string message) where T : Exception
+		/// <summary>
+		/// Assert an expected Exception.
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <param name="func"></param>
+		/// <param name="message"></param>
+		public static void AssertException<T>(Action func, string message = null) where T : Exception
 		{
 			try {
 				func();
-				Assert.Fail();
+				Assert.Fail("Expected Exception {0}, but no exception occured.", typeof (T));
 			} catch (T ex) {
-				Assert.AreEqual(message, ex.Message);
+				if (message != null) {
+					Assert.AreEqual(message, ex.Message);
+				}
 			}
 		}
 
+		public void SI_TypicalUsageTest()
+		{
+			//mult
+			var angularVelocity = 600.RPMtoRad();
+			var torque = 1500.SI<NewtonMeter>();
+			var power = angularVelocity * torque;
+			Assert.IsInstanceOfType(power, typeof (Watt));
+			Assert.AreEqual(600 * 1500, power.Double());
+
+			var siStandardMult = power * torque;
+			Assert.IsInstanceOfType(siStandardMult, typeof (SI));
+			Assert.AreEqual(600 * 1500 * 1500, siStandardMult.Double());
+			Assert.IsTrue(siStandardMult.HasEqualUnit(new SI().Watt.Newton.Meter));
+
+			//div
+			var torque2 = power / angularVelocity;
+			Assert.IsInstanceOfType(torque2, typeof (NewtonMeter));
+			Assert.AreEqual(1500, torque2.Double());
+
+			var siStandardDiv = power / power;
+			Assert.IsInstanceOfType(siStandardMult, typeof (SI));
+			Assert.IsTrue(siStandardDiv.HasEqualUnit(new SI()));
+			Assert.AreEqual(600 * 1500 * 1500, siStandardMult.Double());
+
+
+			//add
+			var angularVelocity2 = 400.SI<RoundsPerMinute>().Cast<PerSecond>();
+			var angVeloSum = angularVelocity + angularVelocity2;
+			Assert.IsInstanceOfType(angVeloSum, typeof (PerSecond));
+			Assert.AreEqual(400 + 600, angVeloSum.Double());
+			AssertException<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; });
+
+			//subtract
+			var angVeloDiff = angularVelocity - angularVelocity2;
+			Assert.IsInstanceOfType(angVeloDiff, typeof (PerSecond));
+			Assert.AreEqual(600 - 400, angVeloDiff.Double());
+
+			//general si unit
+			var generalSIUnit = 60000.SI().Gramm.Per.Kilo.Watt.Hour.ConvertTo().Kilo.Gramm.Per.Watt.Second;
+			Assert.IsInstanceOfType(generalSIUnit, typeof (SI));
+			Assert.AreEqual(1, generalSIUnit.Double());
+
+
+			//type conversion
+			var engineSpeed = 600;
+			var angularVelocity3 = engineSpeed.RPMtoRad();
+
+			// convert between units measures
+			var angularVelocity4 = engineSpeed.SI().Rounds.Per.Minute.ConvertTo().Radian.Per.Second;
+
+			// cast SI to specialized unit classes.
+			var angularVelocity5 = angularVelocity2.Cast<PerSecond>();
+			Assert.AreEqual(angularVelocity3, angularVelocity5);
+			Assert.AreEqual(angularVelocity3.Double(), angularVelocity4.Double());
+			Assert.IsInstanceOfType(angularVelocity3, typeof (PerSecond));
+			Assert.IsInstanceOfType(angularVelocity5, typeof (PerSecond));
+			Assert.IsInstanceOfType(angularVelocity4, typeof (SI));
+
+
+			// ConvertTo only allows conversion if the units are correct.
+			AssertException<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo().Watt; });
+			var res1 = 40.SI<Newton>().ConvertTo().Newton;
+
+			// Cast only allows the cast if the units are correct.
+			AssertException<VectoException>(() => { var x = 40.SI().Newton.Cast<Watt>(); });
+			var res2 = 40.SI().Newton.Cast<Newton>();
+		}
+
+
 		[TestMethod]
-		public void TestSI()
+		public void SI_Test()
 		{
 			var si = new SI();
-			Assert.AreEqual(0.0, (double) si);
+			Assert.AreEqual(0.0, si.Double());
 			Assert.AreEqual("0 [-]", si.ToString());
 			Assert.IsTrue(si.HasEqualUnit(new SI()));
 
@@ -29,7 +108,7 @@ namespace TUGraz.VectoCore.Tests.Utils
 			Assert.AreEqual("5 [W]", si2.ToString());
 
 			var si3 = 2.SI().Radian.Per.Second;
-			Assert.AreEqual("2 [rad/s]", si3.ToString());
+			Assert.AreEqual("2 [1/s]", si3.ToString());
 
 			var si4 = si2 * si3;
 			Assert.AreEqual("10 [W/s]", si4.ToString());
@@ -38,15 +117,15 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 
 			var kg = 5.0.SI().Kilo.Gramm;
-			Assert.AreEqual(5.0, (double) kg);
+			Assert.AreEqual(5.0, kg.Double());
 			Assert.AreEqual("5 [kg]", kg.ToString());
 
-			kg = kg.To().Kilo.Gramm.Value();
-			Assert.AreEqual(5.0, (double) kg);
+			kg = kg.ConvertTo().Kilo.Gramm.Value();
+			Assert.AreEqual(5.0, kg.Double());
 			Assert.AreEqual("5 [kg]", kg.ToString());
 
-			kg = kg.To().Gramm.Value();
-			Assert.AreEqual(5000, (double) kg);
+			kg = kg.ConvertTo().Gramm.Value();
+			Assert.AreEqual(5000, kg.Double());
 			Assert.AreEqual("5000 [g]", kg.ToString());
 
 			var x = 5.SI();
@@ -63,6 +142,40 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 			var y = 2.SI();
 			Assert.AreEqual((2 * 5).SI(), y * x);
+
+			var percent = 10.SI<Radian>().ConvertTo().GradientPercent;
+			Assert.AreEqual(67.975.ToString("F3") + " [Percent]", percent.ToString("F3"));
+			Assert.AreEqual(67.975, percent.Double(), 0.001);
+		}
+
+		[TestMethod]
+		[SuppressMessage("ReSharper", "SuggestVarOrType_SimpleTypes")]
+		public void SI_Test_Addition_Subtraction()
+		{
+			var v1 = 600.SI<NewtonMeter>();
+			var v2 = 455.SI<NewtonMeter>();
+			NewtonMeter v3 = v1 + v2;
+
+			NewtonMeter v4 = v1 - v2;
+
+			var v5 = v1 * v2;
+			Assert.IsTrue(v5.HasEqualUnit(0.SI().Square.Newton.Meter));
+			Assert.AreEqual(v1.Double() * v2.Double(), v5.Double());
+
+			var v6 = v1 / v2;
+			Assert.IsTrue(v6.HasEqualUnit(0.SI()));
+			Assert.AreEqual(v1.Double() / v2.Double(), v6.Double());
+
+			var t = 10.SI<NewtonMeter>();
+			var angVelo = 5.SI<PerSecond>();
+
+			Watt w = t * angVelo;
+			Watt w1 = angVelo * t;
+
+			NewtonMeter t1 = w / angVelo;
+
+			PerSecond angVelo1 = w / t;
+			Second sec = t / w;
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Utils/VectoMathTest.cs b/VectoCoreTest/Utils/VectoMathTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2c163c8e67055adf5aba109fb75ee29ec58e5c41
--- /dev/null
+++ b/VectoCoreTest/Utils/VectoMathTest.cs
@@ -0,0 +1,37 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Tests.Utils
+{
+	[TestClass]
+	public class VectoMathTest
+	{
+		[TestMethod]
+		public void VectoMath_Min()
+		{
+			var smaller = 0.SI();
+			var bigger = 5.SI();
+			var negative = -10.SI();
+			var positive = 10.SI();
+			Assert.AreEqual(smaller, VectoMath.Min(smaller, bigger));
+
+			Assert.AreEqual(bigger, VectoMath.Max(smaller, bigger));
+
+			Assert.AreEqual(positive, VectoMath.Abs(negative));
+			Assert.AreEqual(positive, VectoMath.Abs(positive));
+
+
+			var smallerWatt = 0.SI<Watt>();
+			var biggerWatt = 5.SI<Watt>();
+			var negativeWatt = -10.SI<Watt>();
+			var positiveWatt = 10.SI<Watt>();
+			Assert.AreEqual(smallerWatt, VectoMath.Min(smallerWatt, biggerWatt));
+
+			Assert.AreEqual(biggerWatt, VectoMath.Max(smallerWatt, biggerWatt));
+
+
+			Assert.AreEqual(positiveWatt, VectoMath.Abs(negativeWatt));
+			Assert.AreEqual(positiveWatt, VectoMath.Abs(positiveWatt));
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCoreTest/VectoCoreTest.csproj b/VectoCoreTest/VectoCoreTest.csproj
index 65929aa594cf78dc57bff7d7f1fade892684b5ca..35c2226a409022a7222b092583735f95ae37ed24 100644
--- a/VectoCoreTest/VectoCoreTest.csproj
+++ b/VectoCoreTest/VectoCoreTest.csproj
@@ -88,6 +88,8 @@
     <Compile Include="Utils\SITest.cs" />
     <Compile Include="Utils\DelauneyMapTest.cs" />
     <Compile Include="Utils\TestModalDataWriter.cs" />
+    <Compile Include="Utils\DoubleExtensionMethodTest.cs" />
+    <Compile Include="Utils\VectoMathTest.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\VectoCore\VectoCore.csproj">