diff --git a/VECTO.sln.DotSettings b/VECTO.sln.DotSettings
index 79c8369e0b13181e7fdbd97067486f05854bd6ca..d837fa6d7bf34f7ba866b97aef62e747ab517d78 100644
--- a/VECTO.sln.DotSettings
+++ b/VECTO.sln.DotSettings
@@ -16,6 +16,7 @@
 	<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>
diff --git a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs
index 63ebdcee2af3a5a16ef065734fbca55f0c2dff7e..0bbb7cbc80192844bf3ab3fc955710e75f7305f5 100644
--- a/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs
+++ b/VectoCore/Models/SimulationComponent/Data/CombustionEngineData.cs
@@ -77,7 +77,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
         /// </summary>
         public RadianPerSecond IdleSpeed
         {
-            get { return _data.Body.IdleSpeed.SI().Rounds.Per.Minute.To<RadianPerSecond>(); }
+            get { return _data.Body.IdleSpeed.RPMtoRad(); }
             protected set { _data.Body.IdleSpeed = (double) value.To().Rounds.Per.Minute; }
         }
 
@@ -115,7 +115,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
         {
             get
             {
-                return _data.Body.WHTCMotorway.SI().Gramm.Per.Kilo.Watt.Hour.To().Kilo.Gramm.Per.Watt.Second.Value();
+                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; }
         }
diff --git a/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs b/VectoCore/Models/SimulationComponent/Data/DrivingCycleData.cs
index 46396270db95553cba9756b17a6441335985390e..60cd5cf6b4b99016635982ad9d5f78e23920fbe3 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 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.As<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.As<MeterPerSecond>(),
+                    RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
+                    AdditionalAuxPowerDemand =
+                        row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.As<Watt>(),
+                    EngineSpeed =
+                        row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.As<RadianPerSecond>(),
+                    Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
+                    AirSpeedRelativeToVehicle =
+                        row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle)
+                            .SI()
+                            .Kilo.Meter.Per.Hour.As<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.As<MeterPerSecond>(),
+                    RoadGradient = row.ParseDoubleOrGetDefault(Fields.RoadGradient),
+                    AdditionalAuxPowerDemand =
+                        row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.As<Watt>(),
+                    Gear = row.ParseDoubleOrGetDefault(Fields.Gear),
+                    EngineSpeed =
+                        row.ParseDoubleOrGetDefault(Fields.EngineSpeed).SI().Rounds.Per.Minute.As<RadianPerSecond>(),
+                    AirSpeedRelativeToVehicle =
+                        row.ParseDoubleOrGetDefault(Fields.AirSpeedRelativeToVehicle)
+                            .SI()
+                            .Kilo.Meter.Per.Hour.As<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.As<RadianPerSecond>(),
+                        AdditionalAuxPowerDemand =
+                            row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI().Kilo.Watt.As<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.As<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..572e7a78b2ff04c431814a7215da80dcbc409f30 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.As<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)
+        {
+            // delauney map needs is initialised with rpm, therefore the engineSpeed has to be converted.
+            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
+    }
 }
\ 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 51e88ab862b42af6687a404d24f63b0e171e19d2..a819fe67e71988b479df921a3bc2fe3a82cd5802 100644
--- a/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs
+++ b/VectoCore/Models/SimulationComponent/Data/Engine/FullLoadCurve.cs
@@ -61,7 +61,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>()
@@ -73,7 +73,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>()
@@ -134,7 +134,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
         /// </summary>
         /// <param name="angularFrequency">[rad/s]</param>
         /// <returns>[-]</returns>
-        public SI PT1(SI angularFrequency)
+        public double PT1(SI angularFrequency)
         {
             Contract.Requires(angularFrequency.HasEqualUnit(new SI().Radian.Per.Second));
             Contract.Ensures(Contract.Result<SI>().HasEqualUnit(new SI()));
@@ -142,7 +142,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
             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();
+                (double) angularFrequency);
         }
 
         /// <summary>
diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
index 9033a3df5b2202c7e1ce10fa6eac82d9d9ce3d83..9c0f7220613bfb66312ba09f2562ed83b586a48b 100644
--- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
@@ -80,7 +80,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
             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;
@@ -241,8 +241,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
             var pt1 = _data.GetFullLoadCurve(gear).PT1(angularFrequency);
 
-            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;
@@ -257,7 +257,7 @@ 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>
@@ -265,9 +265,9 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
         protected Watt InertiaPowerLoss(NewtonMeter torque, RadianPerSecond engineSpeed)
         {
             var deltaEngineSpeed = engineSpeed - _previousState.EngineSpeed;
-            var avgEngineSpeed = (_previousState.EngineSpeed + engineSpeed) / new SI(2).Second;
+            var avgEngineSpeed = (_previousState.EngineSpeed + engineSpeed) / 2.0.SI<Second>();
             var result = _data.Inertia * deltaEngineSpeed * avgEngineSpeed;
-            return result.To<Watt>();
+            return result.As<Watt>();
         }
 
         public class EngineState
diff --git a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs
index 3f666e37e14f6dc7d26ef72d9153b2a3469d76e6..1521adbf49f3faaf93dbf719be7b4242fbb7ff9d 100644
--- a/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/EngineOnlyAuxiliary.cs
@@ -58,7 +58,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/TimeBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/TimeBasedDrivingCycle.cs
index 973f35ba1f97f68e26804567578201b7e40a3d5f..cd02a3a85977d572eda1869e005ad8434fbd9712 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.As<Radian>());
         }
 
         #endregion
diff --git a/VectoCore/Utils/DoubleExtensionMethods.cs b/VectoCore/Utils/DoubleExtensionMethods.cs
index c77746f498884fa43a1f444ecda5ff7b69fdd2cb..c65aa8dd404128502dcd34c46e7bf9779e483eba 100644
--- a/VectoCore/Utils/DoubleExtensionMethods.cs
+++ b/VectoCore/Utils/DoubleExtensionMethods.cs
@@ -3,66 +3,69 @@ using System.Diagnostics.Contracts;
 
 namespace TUGraz.VectoCore.Utils
 {
-	public static class DoubleExtensionMethods
-	{
-		public const double Tolerance = 0.001;
+    public static class DoubleExtensionMethods
+    {
+        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 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 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 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 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 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);
-		}
+        [Pure]
+        public static bool IsPositive(this double d, double tolerance = Tolerance)
+        {
+            return d.IsGreaterOrEqual(0.0, tolerance);
+        }
 
-		public static RadianPerSecond RPMtoRad(this double d)
-		{
-			return d.SI().Rounds.Per.Minute.To<RadianPerSecond>();
-		}
+        /// <summary>
+        /// Converts the double-value from rounds per minute to the SI Unit RadianPerSecond
+        /// </summary>
+        /// <param name="d"></param>
+        /// <returns></returns>
+        public static RadianPerSecond RPMtoRad(this double d)
+        {
+            return d.SI().Rounds.Per.Minute.To().Radian.Per.Second.As<RadianPerSecond>();
+        }
 
-		/// <summary>
-		///     Gets the SI representation of the double (unit-less).
-		/// </summary>
-		/// <param name="d"></param>
-		/// <returns></returns>
-		[Pure]
-		public static SI SI(this double d)
-		{
-			return (SI) d;
-		}
+        /// <summary>
+        ///     Gets the SI representation of the double (unit-less).
+        /// </summary>
+        /// <param name="d"></param>
+        /// <returns></returns>
+        public static SI SI(this double d)
+        {
+            return (SI) d;
+        }
 
-		[Pure]
-		public static T SI<T>(this double d) where T : SI
-		{
-			return (T) Activator.CreateInstance(typeof (T), d);
-		}
-	}
+        public static T SI<T>(this double d) where T : SIBase<T>
+        {
+            return (T) Activator.CreateInstance(typeof (T), d);
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoCore/Utils/Formulas.cs b/VectoCore/Utils/Formulas.cs
index 721b60881bc8e8e6d7ab4485049519329c3d264c..2548cd6d5a20870db1e54a68a36d2a8a4de110f0 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
@@ -10,10 +8,9 @@ namespace TUGraz.VectoCore.Utils
 		/// <param name="torque">[Nm]</param>
 		/// <param name="angularFrequency">[rad/s]</param>
 		/// <returns>power [W]</returns>
-		[Pure]
 		public static Watt TorqueToPower(NewtonMeter torque, RadianPerSecond angularFrequency)
 		{
-			return (torque * angularFrequency).To<Watt>();
+			return torque * angularFrequency;
 		}
 
 		/// <summary>
@@ -22,10 +19,9 @@ namespace TUGraz.VectoCore.Utils
 		/// <param name="power">[W]</param>
 		/// <param name="angularFrequency">[rad/s]</param>
 		/// <returns>torque [Nm]</returns>
-		[Pure]
 		public static NewtonMeter PowerToTorque(Watt power, RadianPerSecond angularFrequency)
 		{
-			return (power / angularFrequency).To<NewtonMeter>();
+			return power / angularFrequency;
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs
index 6e4cd52ffd653ed481e65f1ce06ad2e02ca0c48b..b2f67acce29017f45bf933a4f23354e20287811e 100644
--- a/VectoCore/Utils/SI.cs
+++ b/VectoCore/Utils/SI.cs
@@ -8,580 +8,709 @@ using TUGraz.VectoCore.Exceptions;
 
 namespace TUGraz.VectoCore.Utils
 {
-    public class MeterPerSecond : SI
-    {
-        public MeterPerSecond(double val = 0) : base(val, new SI().Meter.Per.Second) {}
-    }
-
-    public class Radian : SI
-    {
-        public Radian(double val = 0) : base(val, new SI().Radian) {}
-    }
-
-    public class Second : SI
-    {
-        public Second(double val = 0) : base(val, new SI().Second) {}
-    }
-
-    public class Watt : SI
-    {
-        public Watt(double val = 0) : base(val, new SI().Watt) {}
-    }
-
-    public class RadianPerSecond : SI
-    {
-        public RadianPerSecond(double val = 0) : base(val, new SI().Radian.Per.Second) {}
-    }
-
-    public class RoundsPerMinute : SI
-    {
-        public RoundsPerMinute(double val = 0) : base(val, new SI().Rounds.Per.Minute) {}
-    }
-
-    public class NewtonMeter : SI
-    {
-        public NewtonMeter(double val = 0) : base(val, new SI().Newton.Meter) {}
-    }
-
-    public class Newton : SI
-    {
-        public Newton(double val = 0) : base(val, new SI().Newton) {}
-    }
-
-
-    [DataContract]
-    public class SI
-    {
-        [DataMember] protected readonly string[] Denominator;
-        [DataMember] protected readonly int Exponent;
-        [DataMember] protected readonly string[] Numerator;
-        [DataMember] protected readonly bool Reciproc;
-        [DataMember] protected readonly bool Reverse;
-        [DataMember] protected readonly double Val;
-
-        public SI(double val = 0.0)
-        {
-            Val = val;
-            Reciproc = false;
-            Reverse = false;
-            Numerator = new string[0];
-            Denominator = new string[0];
-            Exponent = 1;
-        }
-
-        protected SI(double val, IEnumerable<string> numerator, IEnumerable<string> denominator, bool reciproc = false,
-            bool reverse = false, int exponent = 1)
-        {
-            Contract.Requires(numerator != null);
-            Contract.Requires(denominator != null);
-
-            Val = val;
-            Reciproc = reciproc;
-            Reverse = reverse;
-            Exponent = exponent;
-
-            var tmpNumerator = numerator.ToList();
-            var tmpDenominator = denominator.ToList();
-
-            foreach (var v in tmpDenominator.ToArray().Where(v => tmpNumerator.Contains(v))) {
-                tmpNumerator.Remove(v);
-                tmpDenominator.Remove(v);
-            }
-
-            Numerator = tmpNumerator.ToArray();
-            Denominator = tmpDenominator.ToArray();
-        }
-
-        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,
-            bool? reciproc = null, bool? reverse = null, int? exponent = null)
-        {
-            Contract.Requires(si != null);
-            Contract.Requires(si.Denominator != null);
-            Contract.Requires(si.Numerator != null);
-
-            var numerator = si.Denominator.ToList();
-            var denominator = si.Numerator.ToList();
-
-            Val = si.Val;
-            Reciproc = reciproc ?? si.Reciproc;
-            Reverse = reverse ?? si.Reverse;
-            Exponent = exponent ?? si.Exponent;
-
-            if (Reverse) {
-                var tmp = fromUnit;
-                fromUnit = toUnit;
-                toUnit = tmp;
-                factor = 1 / factor;
-            }
-
-            for (var i = 0; i < Exponent; i++) {
-                if (!Reciproc) {
-                    UpdateUnit(fromUnit, toUnit, denominator);
-                    if (factor.HasValue) {
-                        Val *= factor.Value;
-                    }
-                } else {
-                    UpdateUnit(fromUnit, toUnit, numerator);
-                    if (factor.HasValue) {
-                        Val /= factor.Value;
-                    }
-                }
-            }
-
-            foreach (var v in numerator.ToArray().Where(v => denominator.Contains(v))) {
-                denominator.Remove(v);
-                numerator.Remove(v);
-            }
-
-            Numerator = denominator.ToArray();
-            Denominator = numerator.ToArray();
-        }
-
-        private void UpdateUnit(string fromUnit, string toUnit, ICollection<string> units)
-        {
-            if (Reverse && !string.IsNullOrEmpty(fromUnit)) {
-                if (units.Contains(fromUnit)) {
-                    units.Remove(fromUnit);
-                } else {
-                    throw new VectoException("Unit missing. Conversion not possible.");
-                }
-            }
-
-            if (!string.IsNullOrEmpty(toUnit)) {
-                units.Add(toUnit);
-            }
-        }
-
-        /// <summary>
-        ///     Convert an SI unit into another SI unit, defined by term following after the To().
-        /// </summary>
-        /// <returns></returns>
-        public SI To()
-        {
-            return new SI(Linear, reciproc: false, reverse: true);
-        }
-
-        public T To<T>() where T : SI
-        {
-            var t = (T) Activator.CreateInstance(typeof (T), Val);
-            Contract.Assert(HasEqualUnit(t), string.Format("SI Unit Conversion failed: From {0} to {1}", this, t));
-            return t;
-        }
-
-        public SI ToBasicUnits()
-        {
-            var numerator = new List<string>();
-            var denominator = new List<string>();
-            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)
-        {
-            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");
-                    break;
-                case "N":
-                    numerator.Add("k");
-                    numerator.Add("g");
-                    numerator.Add("m");
-                    denominator.Add("s");
-                    denominator.Add("s");
-                    break;
-                default:
-                    numerator.Add(unit);
-                    break;
-            }
-        }
-
-        /// <summary>
-        ///     Gets the basic scalar value.
-        /// </summary>
-        protected double ScalarValue()
-        {
-            return Val;
-        }
-
-        public SI Value()
-        {
-            return new SI(Val, Numerator, Denominator);
-        }
-
-        public SI Abs()
-        {
-            return new SI(Math.Abs(Val), this);
-        }
-
-        #region Unit Definitions
-
-        /// <summary>
-        ///     Defines the denominator by the terms following after the Per.
-        /// </summary>
-        [DebuggerHidden]
-        public SI Per
-        {
-            get { return new SI(Linear, reciproc: !Reciproc); }
-        }
-
-        /// <summary>
-        ///     Takes all following terms as cubic terms (=to the power of 3).
-        /// </summary>
-        [DebuggerHidden]
-        public SI Cubic
-        {
-            get { return new SI(this, exponent: 3); }
-        }
-
-        /// <summary>
-        ///     Takes all following terms as quadratic terms (=to the power of 2).
-        /// </summary>
-        [DebuggerHidden]
-        public SI Square
-        {
-            get { return new SI(this, exponent: 2); }
-        }
-
-        /// <summary>
-        ///     Takes all following terms as linear terms (=to the power of 1).
-        /// </summary>
-        [DebuggerHidden]
-        public SI Linear
-        {
-            get { return new SI(this, exponent: 1); }
-        }
-
-        /// <summary>
-        ///     [g] (to basic unit: [kg])
-        /// </summary>
-        [DebuggerHidden]
-        public SI Gramm
-        {
-            get { return new SI(new SI(this, toUnit: "k"), 0.001, "g", "g"); }
-        }
-
-        /// <summary>
-        ///     [N]
-        /// </summary>
-        [DebuggerHidden]
-        public SI Newton
-        {
-            get { return new SI(this, fromUnit: "N", toUnit: "N"); }
-        }
-
-        /// <summary>
-        ///     [W]
-        /// </summary>
-        [DebuggerHidden]
-        public SI Watt
-        {
-            get { return new SI(this, fromUnit: "W", toUnit: "W"); }
-        }
-
-        /// <summary>
-        ///     [m]
-        /// </summary>
-        [DebuggerHidden]
-        public SI Meter
-        {
-            get { return new SI(this, fromUnit: "m", toUnit: "m"); }
-        }
-
-        /// <summary>
-        ///     [s]
-        /// </summary>
-        [DebuggerHidden]
-        public SI Second
-        {
-            get { return new SI(this, fromUnit: "s", toUnit: "s"); }
-        }
-
-        /// <summary>
-        ///     [rad]
-        /// </summary>
-        [DebuggerHidden]
-        public SI Radian
-        {
-            get { return new SI(this, fromUnit: "rad", toUnit: "rad"); }
-        }
-
-        public SI GradientPercent
-        {
-            get { return new SI(this, factor: Math.Atan(Val) / Val, fromUnit: "%", toUnit: "rad"); }
-        }
-
-        /// <summary>
-        ///     Converts to/from Radiant
-        /// </summary>
-        [DebuggerHidden]
-        public SI Rounds
-        {
-            get { return new SI(this, 2 * Math.PI, toUnit: "rad"); }
-        }
-
-        /// <summary>
-        ///     Converts to/from Second
-        /// </summary>
-        [DebuggerHidden]
-        public SI Hour
-        {
-            get { return new SI(this, 3600.0, "h", "s"); }
-        }
-
-        /// <summary>
-        ///     Converts to/from Second
-        /// </summary>
-        [DebuggerHidden]
-        public SI Minute
-        {
-            get { return new SI(this, 60.0, "min", "s"); }
-        }
-
-        /// <summary>
-        ///     Converts to/from 1000 * Basic Unit
-        /// </summary>
-        [DebuggerHidden]
-        public SI Kilo
-        {
-            get { return new SI(this, 1000.0, "k"); }
-        }
-
-        /// <summary>
-        ///     Converts to/from Basic Unit / 100
-        /// </summary>
-        [DebuggerHidden]
-        public SI Centi
-        {
-            get { return new SI(this, 1.0 / 100.0, "c"); }
-        }
-
-        #endregion
-
-        #region Operators
-
-        public static SI operator +(SI si1, SI si2)
-        {
-            Contract.Requires(si1.HasEqualUnit(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));
-
-            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");
-            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");
-            return new SI(si1.Val / si2.Val, numerator, denominator);
-        }
-
-        public static SI operator +(SI si1, double d)
-        {
-            return new SI(si1.Val + d, si1);
-        }
-
-        public static SI operator -(SI si1, double d)
-        {
-            return new SI(si1.Val - d, si1);
-        }
-
-        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, 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 bool operator <(SI si1, SI si2)
-        {
-            Contract.Requires(si1.HasEqualUnit(si2));
-            return si1.Val < si2.Val;
-        }
-
-        public static bool operator >(SI si1, SI si2)
-        {
-            Contract.Requires(si1.HasEqualUnit(si2));
-            return si1.Val > si2.Val;
-        }
-
-        public static bool operator <=(SI si1, SI si2)
-        {
-            Contract.Requires(si1.HasEqualUnit(si2));
-            return si1.Val <= si2.Val;
-        }
-
-        public static bool operator >=(SI si1, SI si2)
-        {
-            Contract.Requires(si1.HasEqualUnit(si2));
-            return si1.Val >= si2.Val;
-        }
-
-        public static bool operator <(SI si1, double d)
-        {
-            return si1.Val < d;
-        }
-
-        public static bool operator >(SI si1, double d)
-        {
-            return si1.Val > d;
-        }
-
-        public static bool operator <=(SI si1, double d)
-        {
-            return si1.Val <= d;
-        }
-
-        public static bool operator >=(SI si1, double d)
-        {
-            return si1.Val >= d;
-        }
-
-        #endregion
-
-        #region Double Conversion
-
-        /// <summary>
-        ///     Casts an SI Unit to an double.
-        /// </summary>
-        /// <param name="si"></param>
-        /// <returns></returns>
-        public static explicit operator double(SI si)
-        {
-            return si.Val;
-        }
-
-        /// <summary>
-        ///     Casts a double to an SI Unit.
-        /// </summary>
-        /// <param name="d"></param>
-        /// <returns></returns>
-        public static explicit operator SI(double d)
-        {
-            return new SI(d);
-        }
-
-        #endregion
-
-        #region ToString
-
-        /// <summary>
-        ///     Returns the Unit Part of the SI Unit Expression.
-        /// </summary>
-        private string GetUnitString()
-        {
-            if (Denominator.Any()) {
-                if (Numerator.Any()) {
-                    return string.Format("{0}/{1}", string.Join("", Numerator), string.Join("", Denominator));
-                } else {
-                    return string.Format("1/{0}", string.Join("", Denominator));
-                }
-            }
-
-            if (Numerator.Any()) {
-                return string.Format("{0}", string.Join("", Numerator));
-            }
-
-            return "-";
-        }
-
-        /// <summary>
-        ///     Returns the String representation.
-        /// </summary>
-        public override string ToString()
-        {
-            return string.Format("{0} [{1}]", Val, GetUnitString());
-        }
-
-        #endregion
-
-        #region Equality members
-
-        /// <summary>
-        ///     Compares the Unit-Parts of two SI Units.
-        /// </summary>
-        [Pure]
-        public bool HasEqualUnit(SI si)
-        {
-            return ToBasicUnits()
-                .Denominator.OrderBy(x => x)
-                .SequenceEqual(si.ToBasicUnits().Denominator.OrderBy(x => x))
-                   &&
-                   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)) {
-                return false;
-            }
-            if (ReferenceEquals(this, obj)) {
-                return true;
-            }
-            var other = obj as SI;
-            return other != null && Equals(other);
-        }
-
-        public override int GetHashCode()
-        {
-            unchecked {
-                var hashCode = Val.GetHashCode();
-                hashCode = (hashCode * 397) ^ (Numerator != null ? Numerator.GetHashCode() : 0);
-                hashCode = (hashCode * 397) ^ (Denominator != null ? Denominator.GetHashCode() : 0);
-                return hashCode;
-            }
-        }
-
-        public static bool operator ==(SI left, SI right)
-        {
-            return Equals(left, right);
-        }
-
-        public static bool operator !=(SI left, SI right)
-        {
-            return !Equals(left, right);
-        }
-
-        #endregion
-    }
+	public class MeterPerSecond : SIBase<MeterPerSecond>
+	{
+		public MeterPerSecond(double val = 0) : base(val, new SI().Meter.Per.Second) {}
+	}
+
+	public class Radian : SIBase<Radian>
+	{
+		public Radian(double val = 0) : base(val, new SI().Radian) {}
+	}
+
+	public class Second : SIBase<Second>
+	{
+		public Second(double val = 0) : base(val, new SI().Second) {}
+	}
+
+	public class Watt : SIBase<Watt>
+	{
+		public Watt(double val = 0) : base(val, new SI().Watt) {}
+
+		public static RadianPerSecond operator /(Watt watt, NewtonMeter newtonMeter)
+		{
+			return ((watt as SI) / newtonMeter).As<RadianPerSecond>();
+		}
+
+		public static NewtonMeter operator /(Watt watt, RadianPerSecond radianPerSecond)
+		{
+			return ((watt as SI) / radianPerSecond).As<NewtonMeter>();
+		}
+	}
+
+	public class RadianPerSecond : SIBase<RadianPerSecond>
+	{
+		public RadianPerSecond(double val = 0) : base(val, new SI().Radian.Per.Second) {}
+
+		public static Watt operator *(RadianPerSecond radianPerSecond, NewtonMeter newtonMeter)
+		{
+			return ((radianPerSecond as SI) * newtonMeter).As<Watt>();
+		}
+	}
+
+	public class RoundsPerMinute : SIBase<RoundsPerMinute>
+	{
+		public RoundsPerMinute(double val = 0) : base(val, new SI().Rounds.Per.Minute) {}
+	}
+
+	public class NewtonMeter : SIBase<NewtonMeter>
+	{
+		public NewtonMeter(double val = 0) : base(val, new SI().Newton.Meter) {}
+
+		public static Watt operator *(NewtonMeter newtonMeter, RadianPerSecond radianPerSecond)
+		{
+			return ((newtonMeter as SI) * radianPerSecond).As<Watt>();
+		}
+
+		public static Second operator /(NewtonMeter newtonMeter, Watt watt)
+		{
+			return ((newtonMeter as SI) / watt).As<Second>();
+		}
+	}
+
+	public class Newton : SIBase<Newton>
+	{
+		public Newton(double val = 0) : base(val, new SI().Newton) {}
+	}
+
+	public abstract class SIBase<T> : SI where T : SIBase<T>
+	{
+		protected SIBase(double val = 0) : 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).As<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).As<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)).As<T>();
+		}
+
+		public static T operator -(SIBase<T> si, double d)
+		{
+			return ((si as SI) - d).As<T>();
+		}
+
+		public static T operator -(double d, SIBase<T> si)
+		{
+			return (d - (si as SI)).As<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).As<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).As<T>();
+		}
+
+		#endregion
+	}
+
+
+	[DataContract]
+	public class SI
+	{
+		[DataMember] protected readonly string[] Denominator;
+		[DataMember] protected readonly int Exponent;
+		[DataMember] protected readonly string[] Numerator;
+		[DataMember] protected readonly bool Reciproc;
+		[DataMember] protected readonly bool Reverse;
+		[DataMember] protected readonly double Val;
+
+		public SI(double val = 0.0)
+		{
+			Val = val;
+			Reciproc = false;
+			Reverse = false;
+			Numerator = new string[0];
+			Denominator = new string[0];
+			Exponent = 1;
+		}
+
+		protected SI(double val, IEnumerable<string> numerator, IEnumerable<string> denominator,
+			bool reciproc = false,
+			bool reverse = false, int exponent = 1)
+		{
+			Contract.Requires(numerator != null);
+			Contract.Requires(denominator != null);
+
+			Val = val;
+			Reciproc = reciproc;
+			Reverse = reverse;
+			Exponent = exponent;
+
+			var tmpNumerator = numerator.ToList();
+			var tmpDenominator = denominator.ToList();
+
+			foreach (var v in tmpDenominator.ToArray().Where(v => tmpNumerator.Contains(v))) {
+				tmpNumerator.Remove(v);
+				tmpDenominator.Remove(v);
+			}
+
+			Numerator = tmpNumerator.ToArray();
+			Denominator = tmpDenominator.ToArray();
+		}
+
+		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,
+			bool? reciproc = null, bool? reverse = null, int? exponent = null)
+		{
+			Contract.Requires(si != null);
+			Contract.Requires(si.Denominator != null);
+			Contract.Requires(si.Numerator != null);
+
+			var numerator = si.Denominator.ToList();
+			var denominator = si.Numerator.ToList();
+
+			Val = si.Val;
+			Reciproc = reciproc ?? si.Reciproc;
+			Reverse = reverse ?? si.Reverse;
+			Exponent = exponent ?? si.Exponent;
+
+			if (Reverse) {
+				var tmp = fromUnit;
+				fromUnit = toUnit;
+				toUnit = tmp;
+				factor = 1 / factor;
+			}
+
+			for (var i = 0; i < Exponent; i++) {
+				if (!Reciproc) {
+					UpdateUnit(fromUnit, toUnit, denominator);
+					if (factor.HasValue) {
+						Val *= factor.Value;
+					}
+				} else {
+					UpdateUnit(fromUnit, toUnit, numerator);
+					if (factor.HasValue) {
+						Val /= factor.Value;
+					}
+				}
+			}
+
+			foreach (var v in numerator.ToArray().Where(v => denominator.Contains(v))) {
+				denominator.Remove(v);
+				numerator.Remove(v);
+			}
+
+			Numerator = denominator.ToArray();
+			Denominator = numerator.ToArray();
+		}
+
+		private void UpdateUnit(string fromUnit, string toUnit, ICollection<string> units)
+		{
+			if (Reverse && !string.IsNullOrEmpty(fromUnit)) {
+				if (units.Contains(fromUnit)) {
+					units.Remove(fromUnit);
+				} else {
+					throw new VectoException("Unit missing. Conversion not possible.");
+				}
+			}
+
+			if (!string.IsNullOrEmpty(toUnit)) {
+				units.Add(toUnit);
+			}
+		}
+
+		/// <summary>
+		/// Converts the SI unit to another SI unit, defined by term(s) following after the To().
+		/// The Conversion Mode is active until an arithmetic operator is used (+,-,*,/), 
+		/// or the .Value-Method, or the .As-Method were called.
+		/// ATTENTION: Before returning an SI Unit, ensure to cancel Conversion Mode (with .Value or .As).
+		/// </summary>
+		/// <returns></returns>
+		public SI To()
+		{
+			return new SI(Linear, reciproc: false, reverse: true);
+		}
+
+		/// <summary>
+		/// Casts the SI Unit to the concrete unit type if the units are correct.
+		/// </summary>
+		/// <typeparam name="T"></typeparam>
+		/// <returns></returns>
+		public T As<T>() where T : SIBase<T>
+		{
+			var t = (T) Activator.CreateInstance(typeof (T), Val);
+			Contract.Assert(HasEqualUnit(t), string.Format("SI Unit Conversion failed: From {0} to {1}", this, t));
+			return t;
+		}
+
+		public SI ToBasicUnits()
+		{
+			var numerator = new List<string>();
+			var denominator = new List<string>();
+			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)
+		{
+			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");
+					break;
+				case "N":
+					numerator.Add("k");
+					numerator.Add("g");
+					numerator.Add("m");
+					denominator.Add("s");
+					denominator.Add("s");
+					break;
+				default:
+					numerator.Add(unit);
+					break;
+			}
+		}
+
+		/// <summary>
+		///     Gets the basic scalar value.
+		/// </summary>
+		protected double ScalarValue()
+		{
+			return Val;
+		}
+
+		public SI Value()
+		{
+			return new SI(Val, Numerator, Denominator);
+		}
+
+		public SI Abs()
+		{
+			return new SI(Math.Abs(Val), this);
+		}
+
+		#region Unit Definitions
+
+		/// <summary>
+		///     Defines the denominator by the terms following after the Per.
+		/// </summary>
+		[DebuggerHidden]
+		public SI Per
+		{
+			get { return new SI(Linear, reciproc: !Reciproc); }
+		}
+
+		/// <summary>
+		///     Takes all following terms as cubic terms (=to the power of 3).
+		/// </summary>
+		[DebuggerHidden]
+		public SI Cubic
+		{
+			get { return new SI(this, exponent: 3); }
+		}
+
+		/// <summary>
+		///     Takes all following terms as quadratic terms (=to the power of 2).
+		/// </summary>
+		[DebuggerHidden]
+		public SI Square
+		{
+			get { return new SI(this, exponent: 2); }
+		}
+
+		/// <summary>
+		///     Takes all following terms as linear terms (=to the power of 1).
+		/// </summary>
+		[DebuggerHidden]
+		public SI Linear
+		{
+			get { return new SI(this, exponent: 1); }
+		}
+
+		/// <summary>
+		///     [g] (to basic unit: [kg])
+		/// </summary>
+		[DebuggerHidden]
+		public SI Gramm
+		{
+			get { return new SI(new SI(this, toUnit: "k"), 0.001, "g", "g"); }
+		}
+
+		/// <summary>
+		///     [N]
+		/// </summary>
+		[DebuggerHidden]
+		public SI Newton
+		{
+			get { return new SI(this, fromUnit: "N", toUnit: "N"); }
+		}
+
+		/// <summary>
+		///     [W]
+		/// </summary>
+		[DebuggerHidden]
+		public SI Watt
+		{
+			get { return new SI(this, fromUnit: "W", toUnit: "W"); }
+		}
+
+		/// <summary>
+		///     [m]
+		/// </summary>
+		[DebuggerHidden]
+		public SI Meter
+		{
+			get { return new SI(this, fromUnit: "m", toUnit: "m"); }
+		}
+
+		/// <summary>
+		///     [s]
+		/// </summary>
+		[DebuggerHidden]
+		public SI Second
+		{
+			get { return new SI(this, fromUnit: "s", toUnit: "s"); }
+		}
+
+		/// <summary>
+		///     [rad]
+		/// </summary>
+		[DebuggerHidden]
+		public SI Radian
+		{
+			get { return new SI(this, fromUnit: "rad", toUnit: "rad"); }
+		}
+
+		public SI GradientPercent
+		{
+			get { return new SI(this, factor: Math.Atan(Val) / Val, fromUnit: "%", toUnit: "rad"); }
+		}
+
+		/// <summary>
+		///     Converts to/from Radiant
+		/// </summary>
+		[DebuggerHidden]
+		public SI Rounds
+		{
+			get { return new SI(this, 2 * Math.PI, toUnit: "rad"); }
+		}
+
+		/// <summary>
+		///     Converts to/from Second
+		/// </summary>
+		[DebuggerHidden]
+		public SI Hour
+		{
+			get { return new SI(this, 3600.0, "h", "s"); }
+		}
+
+		/// <summary>
+		///     Converts to/from Second
+		/// </summary>
+		[DebuggerHidden]
+		public SI Minute
+		{
+			get { return new SI(this, 60.0, "min", "s"); }
+		}
+
+		/// <summary>
+		///     Converts to/from 1000 * Basic Unit
+		/// </summary>
+		[DebuggerHidden]
+		public SI Kilo
+		{
+			get { return new SI(this, 1000.0, "k"); }
+		}
+
+		/// <summary>
+		///     Converts to/from Basic Unit / 100
+		/// </summary>
+		[DebuggerHidden]
+		public SI Centi
+		{
+			get { return new SI(this, 1.0 / 100.0, "c"); }
+		}
+
+		#endregion
+
+		#region Operators
+
+		public static SI operator +(SI si1, SI si2)
+		{
+			Contract.Requires(si1.HasEqualUnit(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));
+
+			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");
+			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");
+			return new SI(si1.Val / si2.Val, numerator, denominator);
+		}
+
+		public static SI operator +(SI si1, double d)
+		{
+			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);
+		}
+
+		public static SI operator *(double d, SI si1)
+		{
+			return new SI(d * si1.Val, si1);
+		}
+
+		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 bool operator <(SI si1, SI si2)
+		{
+			Contract.Requires(si1.HasEqualUnit(si2));
+			return si1.Val < si2.Val;
+		}
+
+		public static bool operator >(SI si1, SI si2)
+		{
+			Contract.Requires(si1.HasEqualUnit(si2));
+			return si1.Val > si2.Val;
+		}
+
+		public static bool operator <=(SI si1, SI si2)
+		{
+			Contract.Requires(si1.HasEqualUnit(si2));
+			return si1.Val <= si2.Val;
+		}
+
+		public static bool operator >=(SI si1, SI si2)
+		{
+			Contract.Requires(si1.HasEqualUnit(si2));
+			return si1.Val >= si2.Val;
+		}
+
+		public static bool operator <(SI si1, double d)
+		{
+			return si1.Val < d;
+		}
+
+		public static bool operator >(SI si1, double d)
+		{
+			return si1.Val > d;
+		}
+
+		public static bool operator <=(SI si1, double d)
+		{
+			return si1.Val <= d;
+		}
+
+		public static bool operator >=(SI si1, double d)
+		{
+			return si1.Val >= d;
+		}
+
+		#endregion
+
+		#region Double Conversion
+
+		/// <summary>
+		///     Casts an SI Unit to an double.
+		/// </summary>
+		/// <param name="si"></param>
+		/// <returns></returns>
+		public static explicit operator double(SI si)
+		{
+			return si.Val;
+		}
+
+		/// <summary>
+		///     Casts a double to an SI Unit.
+		/// </summary>
+		/// <param name="d"></param>
+		/// <returns></returns>
+		public static explicit operator SI(double d)
+		{
+			return new SI(d);
+		}
+
+		#endregion
+
+		#region ToString
+
+		/// <summary>
+		///     Returns the Unit Part of the SI Unit Expression.
+		/// </summary>
+		private string GetUnitString()
+		{
+			if (Denominator.Any()) {
+				if (Numerator.Any()) {
+					return string.Format("{0}/{1}", string.Join("", Numerator), string.Join("", Denominator));
+				} else {
+					return string.Format("1/{0}", string.Join("", Denominator));
+				}
+			}
+
+			if (Numerator.Any()) {
+				return string.Format("{0}", string.Join("", Numerator));
+			}
+
+			return "-";
+		}
+
+		/// <summary>
+		///     Returns the String representation.
+		/// </summary>
+		public override string ToString()
+		{
+			return string.Format("{0} [{1}]", Val, GetUnitString());
+		}
+
+		#endregion
+
+		#region Equality members
+
+		/// <summary>
+		///     Compares the Unit-Parts of two SI Units.
+		/// </summary>
+		[Pure]
+		public bool HasEqualUnit(SI si)
+		{
+			return ToBasicUnits()
+				.Denominator.OrderBy(x => x)
+				.SequenceEqual(si.ToBasicUnits().Denominator.OrderBy(x => x))
+					&&
+					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)) {
+				return false;
+			}
+			if (ReferenceEquals(this, obj)) {
+				return true;
+			}
+			var other = obj as SI;
+			return other != null && Equals(other);
+		}
+
+		public override int GetHashCode()
+		{
+			unchecked {
+				var hashCode = Val.GetHashCode();
+				hashCode = (hashCode * 397) ^ (Numerator != null ? Numerator.GetHashCode() : 0);
+				hashCode = (hashCode * 397) ^ (Denominator != null ? Denominator.GetHashCode() : 0);
+				return hashCode;
+			}
+		}
+
+		public static bool operator ==(SI left, SI right)
+		{
+			return Equals(left, right);
+		}
+
+		public static bool operator !=(SI left, SI right)
+		{
+			return !Equals(left, right);
+		}
+
+		#endregion
+	}
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs
index fed1acc518e77191ac550ada18debb9d8436c498..b5ce5b48aaf2a77b18e592388a51d2d0ecd35186 100644
--- a/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs
+++ b/VectoCoreTest/Models/Simulation/DrivingCycleTests.cs
@@ -66,7 +66,7 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
             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((-0.020237973).SI().GradientPercent.As<Radian>(), outPort.Gradient);
         }
 
         [TestMethod]
diff --git a/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs b/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
index 5061ea58ae918e3592f0fe39222cae9914ede78c..b8de40ea4edef01fff7c11d74b20cb5b16e5a5e1 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.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));
+                }
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Utils/SITest.cs b/VectoCoreTest/Utils/SITest.cs
index 05e6394e4fb702ef27e9da163f3c07853c9f9a45..23362db676a402f64eb71d7ccd4f5f6d65601b81 100644
--- a/VectoCoreTest/Utils/SITest.cs
+++ b/VectoCoreTest/Utils/SITest.cs
@@ -4,65 +4,65 @@ using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Tests.Utils
 {
-	[TestClass]
-	public class SITest
-	{
-		public static void AssertException<T>(Action func, string message) where T : Exception
-		{
-			try {
-				func();
-				Assert.Fail();
-			} catch (T ex) {
-				Assert.AreEqual(message, ex.Message);
-			}
-		}
+    [TestClass]
+    public class SITest
+    {
+        public static void AssertException<T>(Action func, string message) where T : Exception
+        {
+            try {
+                func();
+                Assert.Fail();
+            } catch (T ex) {
+                Assert.AreEqual(message, ex.Message);
+            }
+        }
 
-		[TestMethod]
-		public void TestSI()
-		{
-			var si = new SI();
-			Assert.AreEqual(0.0, (double) si);
-			Assert.AreEqual("0 [-]", si.ToString());
-			Assert.IsTrue(si.HasEqualUnit(new SI()));
+        [TestMethod]
+        public void TestSI()
+        {
+            var si = new SI();
+            Assert.AreEqual(0.0, (double) si);
+            Assert.AreEqual("0 [-]", si.ToString());
+            Assert.IsTrue(si.HasEqualUnit(new SI()));
 
-			var si2 = 5.0.SI().Watt;
-			Assert.AreEqual("5 [W]", si2.ToString());
+            var si2 = 5.0.SI().Watt;
+            Assert.AreEqual("5 [W]", si2.ToString());
 
-			var si3 = 2.SI().Radian.Per.Second;
-			Assert.AreEqual("2 [rad/s]", si3.ToString());
+            var si3 = 2.SI().Radian.Per.Second;
+            Assert.AreEqual("2 [rad/s]", si3.ToString());
 
-			var si4 = si2 * si3;
-			Assert.AreEqual("10 [W/s]", si4.ToString());
-			Assert.IsTrue(si4.HasEqualUnit(new SI().Watt.Per.Second));
-			Assert.AreEqual("10 [kgmm/ssss]", si4.ToBasicUnits().ToString());
+            var si4 = si2 * si3;
+            Assert.AreEqual("10 [W/s]", si4.ToString());
+            Assert.IsTrue(si4.HasEqualUnit(new SI().Watt.Per.Second));
+            Assert.AreEqual("10 [kgmm/ssss]", si4.ToBasicUnits().ToString());
 
 
-			var kg = 5.0.SI().Kilo.Gramm;
-			Assert.AreEqual(5.0, (double) kg);
-			Assert.AreEqual("5 [kg]", kg.ToString());
+            var kg = 5.0.SI().Kilo.Gramm;
+            Assert.AreEqual(5.0, (double) kg);
+            Assert.AreEqual("5 [kg]", kg.ToString());
 
-			kg = kg.To().Kilo.Gramm.Value();
-			Assert.AreEqual(5.0, (double) kg);
-			Assert.AreEqual("5 [kg]", kg.ToString());
+            kg = kg.To().Kilo.Gramm.Value();
+            Assert.AreEqual(5.0, (double) kg);
+            Assert.AreEqual("5 [kg]", kg.ToString());
 
-			kg = kg.To().Gramm.Value();
-			Assert.AreEqual(5000, (double) kg);
-			Assert.AreEqual("5000 [g]", kg.ToString());
+            kg = kg.To().Gramm.Value();
+            Assert.AreEqual(5000, (double) kg);
+            Assert.AreEqual("5000 [g]", kg.ToString());
 
-			var x = 5.SI();
-			Assert.AreEqual((2.0 / 5.0).SI(), 2 / x);
-			Assert.AreEqual((5.0 / 2.0).SI(), x / 2);
-			Assert.AreEqual((2.0 * 5.0).SI(), 2 * x);
-			Assert.AreEqual((5.0 * 2.0).SI(), x * 2);
+            var x = 5.SI();
+            Assert.AreEqual((2.0 / 5.0).SI(), 2 / x);
+            Assert.AreEqual((5.0 / 2.0).SI(), x / 2);
+            Assert.AreEqual((2.0 * 5.0).SI(), 2 * x);
+            Assert.AreEqual((5.0 * 2.0).SI(), x * 2);
 
-			Assert.AreEqual((2.0 / 5.0).SI(), 2.0 / x);
-			Assert.AreEqual((5.0 / 2.0).SI(), x / 2.0);
-			Assert.AreEqual((2 * 5).SI(), 2.0 * x);
-			Assert.AreEqual((5 * 2).SI(), x * 2.0);
+            Assert.AreEqual((2.0 / 5.0).SI(), 2.0 / x);
+            Assert.AreEqual((5.0 / 2.0).SI(), x / 2.0);
+            Assert.AreEqual((2 * 5).SI(), 2.0 * x);
+            Assert.AreEqual((5 * 2).SI(), x * 2.0);
 
 
-			var y = 2.SI();
-			Assert.AreEqual((2 * 5).SI(), y * x);
-		}
-	}
+            var y = 2.SI();
+            Assert.AreEqual((2 * 5).SI(), y * x);
+        }
+    }
 }
\ No newline at end of file