diff --git a/VectoCore/Models/Declaration/Segments.cs b/VectoCore/Models/Declaration/Segments.cs
index bcbcbc1571bbd31256359ea8f375df133991b164..19ae272376755ba0392d42b1a13533d82e686d84 100644
--- a/VectoCore/Models/Declaration/Segments.cs
+++ b/VectoCore/Models/Declaration/Segments.cs
@@ -100,8 +100,8 @@ namespace TUGraz.VectoCore.Models.Declaration
 		{
 			const double longHaulFactor = 0.5882;
 			const double otherFactor = 0.3941;
-			const double longHaulWeightDeduction = 2511.8;
-			const double otherWeightDeduction = 1705.9;
+			var longHaulWeightDeduction = 2511.8.SI<Kilogram>();
+			var otherWeightDeduction = 1705.9.SI<Kilogram>();
 
 			Kilogram refLoad;
 			if (refLoadField == "f") {
diff --git a/VectoCore/Models/Declaration/TorqueConverter.cs b/VectoCore/Models/Declaration/TorqueConverter.cs
index 9c053939de6b600fe6b099e5d4970c80c21ebe33..4994ef78c7d65d8d1be7c68ee251133affe5fb51 100644
--- a/VectoCore/Models/Declaration/TorqueConverter.cs
+++ b/VectoCore/Models/Declaration/TorqueConverter.cs
@@ -32,7 +32,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 			}
 
 			var torque = VectoMath.Interpolate(sec.Item1.Key, sec.Item2.Key, sec.Item1.Value.Torque, sec.Item2.Value.Torque, nu);
-			return torque * Math.Pow((angularSpeedIn / referenceSpeed).Scalar(), 2);
+			return torque * Math.Pow((angularSpeedIn / referenceSpeed).Cast<Scalar>(), 2);
 		}
 
 		public double LookupMu(double nu)
diff --git a/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs b/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs
index d68a5709a20959ef4b6f9c1609cac207b06ed35f..65964ac4abd066cf0ab1ca88c7556205678c2302 100644
--- a/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs
+++ b/VectoCore/Models/Simulation/Data/SummaryFileWriter.cs
@@ -180,8 +180,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 				row[LOADING] = vehicleLoading;
 			}
 
-			var dtValues = data.GetValues<SI>(ModalResultField.simulationInterval).ToList();
-			var accValues = data.GetValues<SI>(ModalResultField.acc);
+			var dtValues = data.GetValues<SI>(ModalResultField.simulationInterval).Cast<Second>().ToList();
+			var accValues = data.GetValues<SI>(ModalResultField.acc).Cast<MeterPerSquareSecond>();
 			var accelerations = CalculateAverageOverSeconds(dtValues, accValues).ToList();
 			if (accelerations.Any()) {
 				row[A] = accelerations.Average();
@@ -218,8 +218,8 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 		}
 
 
-		private static IEnumerable<SI> CalculateAverageOverSeconds(IEnumerable<SI> dtValues,
-			IEnumerable<SI> accValues)
+		private static IEnumerable<SI> CalculateAverageOverSeconds(IEnumerable<Second> dtValues,
+			IEnumerable<MeterPerSquareSecond> accValues)
 		{
 			var dtSum = 0.SI().Second;
 			var accSum = 0.SI().Meter.Per.Second;
@@ -228,7 +228,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 				var currentX = x;
 
 				while (dtSum + currentX.dt >= 1) {
-					var splitX = new { dt = 1 - dtSum, currentX.acc };
+					var splitX = new { dt = 1.SI<Second>() - dtSum, currentX.acc };
 					yield return accSum;
 					dtSum = 0.SI<Second>();
 					accSum = 0.SI<MeterPerSecond>();
diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/EngineFullLoadCurve.cs b/VectoCore/Models/SimulationComponent/Data/Engine/EngineFullLoadCurve.cs
index b729e81aa5a3d44e50c9659a64065b97fab2c645..5b2e82d0e1daab584e5d814aef59015cfcabe94b 100644
--- a/VectoCore/Models/SimulationComponent/Data/Engine/EngineFullLoadCurve.cs
+++ b/VectoCore/Models/SimulationComponent/Data/Engine/EngineFullLoadCurve.cs
@@ -251,7 +251,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 		{
 			var maxArea = ComputeArea(EngineData.IdleSpeed, N95hSpeed);
 
-			var area = 0.0;
+			var area = 0.SI<Watt>();
 			var idx = 0;
 			while (++idx < _fullLoadEntries.Count) {
 				var additionalArea = ComputeArea(_fullLoadEntries[idx - 1].EngineSpeed, _fullLoadEntries[idx].EngineSpeed);
@@ -265,7 +265,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			Log.WarnFormat("Could not compute preferred speed, check FullLoadCurve! N95h: {0}, maxArea: {1}", N95hSpeed, maxArea);
 		}
 
-		private PerSecond ComputeEngineSpeedForSegmentArea(FullLoadCurveEntry p1, FullLoadCurveEntry p2, double area)
+		private PerSecond ComputeEngineSpeedForSegmentArea(FullLoadCurveEntry p1, FullLoadCurveEntry p2, Watt area)
 		{
 			var k = (p2.TorqueFullLoad - p1.TorqueFullLoad) / (p2.EngineSpeed - p1.EngineSpeed);
 			var d = p2.TorqueFullLoad - k * p2.EngineSpeed;
@@ -273,7 +273,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			if (k.IsEqual(0.0)) {
 				// rectangle
 				// area = M * n
-				return (p1.EngineSpeed + (area / d.Value()));
+				return p1.EngineSpeed + area / d;
 			}
 
 			// non-constant torque, M(n) = k * n + d
@@ -340,16 +340,16 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 			return retVal;
 		}
 
-		private double ComputeArea(PerSecond lowEngineSpeed, PerSecond highEngineSpeed)
+		private SI ComputeArea(PerSecond lowEngineSpeed, PerSecond highEngineSpeed)
 		{
 			var startSegment = FindIndex(lowEngineSpeed);
 			var endSegment = FindIndex(highEngineSpeed);
 
-			var area = 0.0;
+			var area = 0.SI<Watt>();
 			if (lowEngineSpeed < _fullLoadEntries[startSegment].EngineSpeed) {
 				// add part of the first segment
-				area += ((_fullLoadEntries[startSegment].EngineSpeed - lowEngineSpeed) *
-						(FullLoadStationaryTorque(lowEngineSpeed) + _fullLoadEntries[startSegment].TorqueFullLoad) / 2.0).Value();
+				area += (_fullLoadEntries[startSegment].EngineSpeed - lowEngineSpeed) *
+						(FullLoadStationaryTorque(lowEngineSpeed) + _fullLoadEntries[startSegment].TorqueFullLoad) / 2.0;
 			}
 			for (var i = startSegment + 1; i <= endSegment; i++) {
 				var speedHigh = _fullLoadEntries[i].EngineSpeed;
@@ -359,8 +359,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 					speedHigh = highEngineSpeed;
 					torqueHigh = FullLoadStationaryTorque(highEngineSpeed);
 				}
-				area += ((speedHigh - _fullLoadEntries[i - 1].EngineSpeed) *
-						(torqueHigh + _fullLoadEntries[i - 1].TorqueFullLoad) / 2.0).Value();
+				area += (speedHigh - _fullLoadEntries[i - 1].EngineSpeed) * (torqueHigh + _fullLoadEntries[i - 1].TorqueFullLoad) /
+						2.0;
 			}
 			return area;
 		}
diff --git a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
index 5946347629890427c93a9047c2754004fa59e064..251312db42a91cce4bd4898ec8f773213b860688 100644
--- a/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
+++ b/VectoCore/Models/SimulationComponent/Data/Engine/FuelConsumptionMap.cs
@@ -40,8 +40,8 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data.Engine
 						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);
+						fuelConsumptionMap._fuelMap.AddPoint(entry.Torque.Value(), row.ParseDouble(Fields.EngineSpeed),
+							entry.FuelConsumption.Value());
 					} catch (Exception e) {
 						throw new VectoException(string.Format("Line {0}: {1}", data.Rows.IndexOf(row), e.Message), e);
 					}
diff --git a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
index c2145ebbbe156b323b397d91681e169b97892f27..0e1e0162fa58b640326357fedcc731fa3e3276fa 100644
--- a/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/CombustionEngine.cs
@@ -265,7 +265,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 		protected bool IsFullLoad(Watt requestedPower, Watt maxPower)
 		{
-			var testValue = requestedPower / maxPower - 1.0;
+			var testValue = (requestedPower / maxPower).Cast<Scalar>() - 1.0;
 			return testValue.Abs() < FullLoadMargin;
 		}
 
diff --git a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
index 592e509cf3e73e51d49209e4152a59e50958b734..48793b65d667c0ac0f0b5dd8c9cd69a406a44feb 100644
--- a/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
@@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 							CycleIntervalIterator.LeftSample.StoppingTime, CycleIntervalIterator.LeftSample.VehicleTargetSpeed);
 						throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!");
 					}
-					var dt = CycleIntervalIterator.LeftSample.StoppingTime.Value() - PreviousState.WaitTime;
+					var dt = CycleIntervalIterator.LeftSample.StoppingTime - PreviousState.WaitTime;
 					return DriveTimeInterval(absTime, dt);
 				}
 			}
diff --git a/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs b/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
index f8d379ac04dcf82b9b7e6d653d52a0f639267bca..d8e7daddec9c9182e1f9ca046dfb7113fb9a6186 100644
--- a/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
+++ b/VectoCore/Models/SimulationComponent/Impl/Vehicle.cs
@@ -156,7 +156,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 
 			var points = new List<Point> { new Point { X = 0.SI<MeterPerSecond>(), Y = 0 } };
 
-			for (var vVeh = 60; vVeh <= 100; vVeh += 5) {
+			for (var vVeh = 60.KMPHtoMeterPerSecond(); vVeh <= 100; vVeh += 5.SI<MeterPerSecond>()) {
 				var cdASum = 0.0;
 				for (var alpha = 0; alpha <= 180; alpha += 10) {
 					var vWindX = Physics.BaseWindSpeed * Math.Cos(alpha.ToRadian());
@@ -170,11 +170,11 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 					var deltaCdA = VectoMath.Interpolate(sec.Item1.Key, sec.Item2.Key, sec.Item1.Value, sec.Item2.Value, beta);
 					var cdA = cdA0Actual + deltaCdA;
 
-					var degreeShare = ((vVeh != 0 && vVeh != 180) ? 10.0 / 180.0 : 5.0 / 180.0);
+					var degreeShare = ((alpha != 0 && alpha != 180) ? 10.0 / 180.0 : 5.0 / 180.0);
 
-					cdASum += degreeShare * cdA * (vAir * vAir / (vVeh * vVeh)).Scalar();
+					cdASum += degreeShare * cdA * (vAir * vAir / (vVeh * vVeh)).Cast<Scalar>();
 				}
-				points.Add(new Point { X = vVeh.SI<MeterPerSecond>(), Y = cdASum });
+				points.Add(new Point { X = vVeh, Y = cdASum });
 			}
 
 			points[0].Y = points[1].Y;
diff --git a/VectoCore/Utils/DoubleExtensionMethods.cs b/VectoCore/Utils/DoubleExtensionMethods.cs
index cfdcdf9ebf171ea1747463cdb30774c3ad98a7ff..a1a77ecf017461e6177cd9df7e8eb3394c2c2544 100644
--- a/VectoCore/Utils/DoubleExtensionMethods.cs
+++ b/VectoCore/Utils/DoubleExtensionMethods.cs
@@ -14,6 +14,12 @@ namespace TUGraz.VectoCore.Utils
 		/// </summary>
 		public const double Tolerance = 0.001;
 
+		/// <summary>
+		/// The tolerancefactor for relative comparisons.
+		/// </summary>
+		public const double ToleranceFactor = 10e-6;
+
+
 		/// <summary>
 		/// Determines whether the specified other is equal within tolerance.
 		/// </summary>
@@ -114,22 +120,17 @@ namespace TUGraz.VectoCore.Utils
 		/// <summary>
 		/// Creates an SI object for the number (unit-less: [-]).
 		/// </summary>
-		/// <param name="self">The self.</param>
-		/// <returns></returns>
-		public static SI SI(this double self)
+		public static SI SI(this double value)
 		{
-			return (SI)self;
+			return new SI(value);
 		}
 
 		/// <summary>
 		/// Creates an templated SI object for the number.
 		/// </summary>
-		/// <typeparam name="T"></typeparam>
-		/// <param name="self">The self.</param>
-		/// <returns></returns>
-		public static T SI<T>(this double self) where T : SIBase<T>
+		public static T SI<T>(this double value) where T : SIBase<T>
 		{
-			return SIBase<T>.Create(self);
+			return SIBase<T>.Create(value);
 		}
 
 		public static IEnumerable<T> SI<T>(this IEnumerable<double> self) where T : SIBase<T>
diff --git a/VectoCore/Utils/IntExtensionMethods.cs b/VectoCore/Utils/IntExtensionMethods.cs
index 3ba5c8a1cd3c07a84c7dac91b21d729d6d5ecfeb..41a759e179e7f920fef92906128d0a658b43a747 100644
--- a/VectoCore/Utils/IntExtensionMethods.cs
+++ b/VectoCore/Utils/IntExtensionMethods.cs
@@ -23,11 +23,9 @@ namespace TUGraz.VectoCore.Utils
 		/// <summary>
 		/// Gets the SI representation of the number (unit-less).
 		/// </summary>
-		/// <param name="d"></param>
-		/// <returns></returns>
-		public static SI SI(this int d)
+		public static SI SI(this int value)
 		{
-			return (SI)d;
+			return new SI(value);
 		}
 
 		/// <summary>
diff --git a/VectoCore/Utils/SI.cs b/VectoCore/Utils/SI.cs
index d4a895ac313bd4b6a0cfbead80d22b1581dab1dd..64d9d5f897b2d14d339b9b76ad85d2cf78bc45f0 100644
--- a/VectoCore/Utils/SI.cs
+++ b/VectoCore/Utils/SI.cs
@@ -1,5 +1,4 @@
 using System;
-using System.CodeDom;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
@@ -8,17 +7,19 @@ using System.Globalization;
 using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Runtime.Serialization;
-using System.Text;
 using Newtonsoft.Json;
 using TUGraz.VectoCore.Exceptions;
 
 namespace TUGraz.VectoCore.Utils
 {
+	/// <summary>
+	/// SI Class for Scalar Values. Converts implicitely to double and is only castable if the SI value has no units.
+	/// </summary>
 	public class Scalar : SIBase<Scalar>
 	{
 		static Scalar()
 		{
-			Constructors.Add(typeof(Scalar), val => new Scalar(val));
+			Register(val => new Scalar(val));
 		}
 
 		private Scalar(double val) : base(new SI(val)) {}
@@ -28,18 +29,45 @@ namespace TUGraz.VectoCore.Utils
 			return self.Val;
 		}
 
-		public static implicit operator Scalar(double val)
+		public static Scalar operator +(Scalar si1, Scalar si2)
 		{
-			return new Scalar(val);
+			return new Scalar(si1.Val + si2.Val);
+		}
+
+		public static Scalar operator +(Scalar si1, double si2)
+		{
+			return new Scalar(si1.Val + si2);
 		}
-	}
 
+		public static Scalar operator +(double si1, Scalar si2)
+		{
+			return new Scalar(si1 + si2.Val);
+		}
+
+		public static Scalar operator -(Scalar si1, Scalar si2)
+		{
+			return new Scalar(si1.Val - si2.Val);
+		}
 
+		public static Scalar operator -(Scalar si1, double si2)
+		{
+			return new Scalar(si1.Val - si2);
+		}
+
+		public static Scalar operator -(double si1, Scalar si2)
+		{
+			return new Scalar(si1 - si2.Val);
+		}
+	}
+
+	/// <summary>
+	/// SI Class for Newton [N].
+	/// </summary>
 	public class Newton : SIBase<Newton>
 	{
 		static Newton()
 		{
-			Constructors.Add(typeof(Newton), val => new Newton(val));
+			Register(val => new Newton(val));
 		}
 
 		[JsonConstructor]
@@ -51,121 +79,152 @@ namespace TUGraz.VectoCore.Utils
 		}
 	}
 
+	/// <summary>
+	/// SI Class for Radian [] (rad).
+	/// </summary>
 	public class Radian : SIBase<Radian>
 	{
 		static Radian()
 		{
-			Constructors.Add(typeof(Radian), val => new Radian(val));
+			Register(val => new Radian(val));
 		}
 
 		[JsonConstructor]
 		private Radian(double val) : base(new SI(val).Radian) {}
 	}
 
-
+	/// <summary>
+	/// SI Class for Meter per square second [m/s�].
+	/// </summary>
 	public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond>
 	{
 		static MeterPerSquareSecond()
 		{
-			Constructors.Add(typeof(MeterPerSquareSecond), val => new MeterPerSquareSecond(val));
+			Register(val => new MeterPerSquareSecond(val));
 		}
 
 		protected MeterPerSquareSecond(double val) : base(new SI(val).Meter.Per.Square.Second) {}
 	}
 
+	/// <summary>
+	/// SI Class for Second [s].
+	/// </summary>
 	public class Second : SIBase<Second>
 	{
 		static Second()
 		{
-			Constructors.Add(typeof(Second), val => new Second(val));
+			Register(val => new Second(val));
 		}
 
 		[JsonConstructor]
 		private Second(double val) : base(new SI(val).Second) {}
 	}
 
+	/// <summary>
+	/// SI Class for Meter [m].
+	/// </summary>
 	public class Meter : SIBase<Meter>
 	{
 		static Meter()
 		{
-			Constructors.Add(typeof(Meter), val => new Meter(val));
+			Register(val => new Meter(val));
 		}
 
 		protected Meter(double val) : base(new SI(val).Meter) {}
 	}
 
-	public class Ton : SIBase<Ton>
+	/// <summary>
+	/// SI Class for Kilogram [kg].
+	/// </summary>
+	public class Kilogram : SIBase<Kilogram>
 	{
-		static Ton()
+		static Kilogram()
 		{
-			Constructors.Add(typeof(Ton), val => new Ton(val));
+			Register(val => new Kilogram(val));
 		}
 
 		[JsonConstructor]
-		protected Ton(double val) : base(new SI(val).Ton) {}
+		protected Kilogram(double val) : base(new SI(val).Kilo.Gramm) {}
 	}
 
-
-	public class Kilogram : SIBase<Kilogram>
+	/// <summary>
+	/// SI Class for Ton [t] (automatically converts to [kg])
+	/// </summary>
+	public class Ton : SIBase<Ton>
 	{
-		static Kilogram()
+		static Ton()
 		{
-			Constructors.Add(typeof(Kilogram), val => new Kilogram(val));
+			Register(val => new Ton(val));
 		}
 
 		[JsonConstructor]
-		protected Kilogram(double val) : base(new SI(val).Kilo.Gramm) {}
+		protected Ton(double val) : base(new SI(val).Ton) {}
 	}
 
+	/// <summary>
+	/// SI Class for Square meter [m�].
+	/// </summary>
 	public class SquareMeter : SIBase<SquareMeter>
 	{
 		static SquareMeter()
 		{
-			Constructors.Add(typeof(SquareMeter), val => new SquareMeter(val));
+			Register(val => new SquareMeter(val));
 		}
 
 		[JsonConstructor]
 		private SquareMeter(double val) : base(new SI(val).Square.Meter) {}
 	}
 
+	/// <summary>
+	/// SI Class for cubic meter [m�].
+	/// </summary>
 	public class CubicMeter : SIBase<CubicMeter>
 	{
 		static CubicMeter()
 		{
-			Constructors.Add(typeof(CubicMeter), val => new CubicMeter(val));
+			Register(val => new CubicMeter(val));
 		}
 
 		[JsonConstructor]
 		private CubicMeter(double val) : base(new SI(val).Cubic.Meter) {}
 	}
 
+	/// <summary>
+	/// SI Class for Kilogram Square Meter [kgm�].
+	/// </summary>
 	public class KilogramSquareMeter : SIBase<KilogramSquareMeter>
 	{
 		static KilogramSquareMeter()
 		{
-			Constructors.Add(typeof(KilogramSquareMeter), val => new KilogramSquareMeter(val));
+			Register(val => new KilogramSquareMeter(val));
 		}
 
 		[JsonConstructor]
 		protected KilogramSquareMeter(double val) : base(new SI(val).Kilo.Gramm.Square.Meter) {}
 	}
 
+	/// <summary>
+	/// SI Class for Kilogramm per watt second [kg/ws].
+	/// </summary>
 	public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond>
 	{
 		static KilogramPerWattSecond()
 		{
-			Constructors.Add(typeof(KilogramPerWattSecond), val => new KilogramPerWattSecond(val));
+			Register(val => new KilogramPerWattSecond(val));
 		}
 
 		[JsonConstructor]
 		protected KilogramPerWattSecond(double val) : base(new SI(val).Kilo.Gramm.Per.Watt.Second) {}
 	}
 
+	/// <summary>
+	/// SI Class for Watt [W].
+	/// </summary>
 	public class Watt : SIBase<Watt>
 	{
 		static Watt()
 		{
-			Constructors.Add(typeof(Watt), val => new Watt(val));
+			Register(val => new Watt(val));
 		}
 
 		[JsonConstructor]
@@ -182,22 +241,28 @@ namespace TUGraz.VectoCore.Utils
 		}
 	}
 
+	/// <summary>
+	/// SI Class for one per second [1/s].
+	/// </summary>
 	public class PerSecond : SIBase<PerSecond>
 	{
 		static PerSecond()
 		{
-			Constructors.Add(typeof(PerSecond), val => new PerSecond(val));
+			Register(val => new PerSecond(val));
 		}
 
 		[JsonConstructor]
 		private PerSecond(double val) : base(new SI(val).Per.Second) {}
 	}
 
+	/// <summary>
+	/// SI Class for Meter per second [m/s].
+	/// </summary>
 	public class MeterPerSecond : SIBase<MeterPerSecond>
 	{
 		static MeterPerSecond()
 		{
-			Constructors.Add(typeof(MeterPerSecond), val => new MeterPerSecond(val));
+			Register(val => new MeterPerSecond(val));
 		}
 
 		[JsonConstructor]
@@ -210,24 +275,28 @@ namespace TUGraz.VectoCore.Utils
 		}
 	}
 
-
+	/// <summary>
+	/// SI Class for Rounds per minute [rpm] (automatically converts internally to radian per second)
+	/// </summary>
 	public class RoundsPerMinute : SIBase<RoundsPerMinute>
 	{
 		static RoundsPerMinute()
 		{
-			Constructors.Add(typeof(RoundsPerMinute), val => new RoundsPerMinute(val));
+			Register(val => new RoundsPerMinute(val));
 		}
 
 		[JsonConstructor]
 		private RoundsPerMinute(double val) : base(new SI(val).Rounds.Per.Minute) {}
 	}
 
-
+	/// <summary>
+	/// SI Class for NewtonMeter [Nm].
+	/// </summary>
 	public class NewtonMeter : SIBase<NewtonMeter>
 	{
 		static NewtonMeter()
 		{
-			Constructors.Add(typeof(NewtonMeter), val => new NewtonMeter(val));
+			Register(val => new NewtonMeter(val));
 		}
 
 		[JsonConstructor]
@@ -254,97 +323,181 @@ namespace TUGraz.VectoCore.Utils
 		}
 	}
 
+
+	/// <summary>
+	/// Base Class for all special SI Classes. Not intended to be used directly.
+	/// Implements templated operators for type safety and convenience.
+	/// </summary>
+	/// <typeparam name="T"></typeparam>
 	public abstract class SIBase<T> : SI where T : SIBase<T>
 	{
-		protected static Dictionary<Type, Func<double, T>> Constructors =
-			new Dictionary<Type, Func<double, T>>();
+		/// <summary>
+		/// Static dictionary with constructors for the specialized types.
+		/// Every specialized SI type needs to Register itself in a static constructor (with the method <see cref="Register"/>).
+		/// </summary>
+		private static readonly Dictionary<Type, Func<double, T>> Constructors = new Dictionary<Type, Func<double, T>>();
+
 
+		/// <summary>
+		/// Creates the specified special SI object.
+		/// </summary>
+		/// <param name="val">The value of the SI object.</param>
 		public static T Create(double val)
 		{
 			RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
 			return Constructors[typeof(T)](val);
 		}
 
-		protected SIBase(Type type, Func<double, T> constructor)
+		/// <summary>
+		/// Registers the specified constructor in the constructor list (which is used for the <see cref="Create"/> Method).
+		/// </summary>
+		/// <param name="func">The constructor of the specified type T.</param>
+		protected static void Register(Func<double, T> func)
 		{
-			Constructors[type] = constructor;
+			Constructors[typeof(T)] = func;
 		}
 
+		/// <summary>
+		/// Initializes a new instance of the <see cref="SIBase{T}"/> class. Is used by specialized sub classes.
+		/// </summary>
 		protected SIBase(SI si) : base(si) {}
 
 		#region Operators
 
+		/// <summary>
+		/// Implements the operator + for two specialized SI Classes.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator +(SIBase<T> si1, SIBase<T> si2)
 		{
 			return (si1 as SI) + si2;
 		}
 
+		/// <summary>
+		/// Implements the operator + for a specialized SI Class and a generic SI Class.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator +(SIBase<T> si1, SI si2)
 		{
 			return ((si1 as SI) + si2).Cast<T>();
 		}
 
+		/// <summary>
+		/// Implements the operator + for a generic SI Class and a specialized SI Class.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator +(SI si1, SIBase<T> si2)
 		{
-			return si2 + si1;
+			return (si1 + (si2 as SI)).Cast<T>();
 		}
 
-		public static T operator +(SIBase<T> si1, double d)
-		{
-			return ((si1 as SI) + d).Cast<T>();
-		}
-
-		public static T operator +(double d, SIBase<T> si)
-		{
-			return si + d;
-		}
-
-
+		/// <summary>
+		/// Implements the unary operator -.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator -(SIBase<T> si1)
 		{
-			return 0 - si1;
+			return (-(si1 as SI)).Cast<T>();
 		}
 
+		/// <summary>
+		/// Implements the operator - for two specialized SI classes.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator -(SIBase<T> si1, SIBase<T> si2)
 		{
-			return (si1 as SI) - si2;
+			return ((si1 as SI) - (si2 as SI)).Cast<T>();
 		}
 
+		/// <summary>
+		/// Implements the operator - for a specialized SI class and a generic SI class.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator -(SIBase<T> si1, SI si2)
 		{
-			return (-1 * si2) + si1;
+			return ((si1 as SI) - si2).Cast<T>();
 		}
 
+		/// <summary>
+		/// Implements the operator - for a generic SI class and a specialized SI class.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator -(SI si1, SIBase<T> si2)
 		{
 			return (si1 - (si2 as SI)).Cast<T>();
 		}
 
-		public static T operator -(SIBase<T> si, double d)
-		{
-			return ((si as SI) - d).Cast<T>();
-		}
-
-		public static T operator -(double d, SIBase<T> si)
-		{
-			return (d - (si as SI)).Cast<T>();
-		}
-
+		/// <summary>
+		/// Implements the operator * for a double and a specialized SI class.
+		/// </summary>
+		/// <param name="d">The double value.</param>
+		/// <param name="si">The si.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator *(double d, SIBase<T> si)
 		{
-			return si * d;
+			return (d * (si as SI)).Cast<T>();
 		}
 
+		/// <summary>
+		/// Implements the operator * for a specialized SI class and a double.
+		/// </summary>
+		/// <param name="si">The si.</param>
+		/// <param name="d">The double.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator *(SIBase<T> si, double d)
 		{
 			return ((si as SI) * d).Cast<T>();
 		}
 
-		public static T operator /(double d, SIBase<T> si)
-		{
-			return si / d;
-		}
-
+		/// <summary>
+		/// Implements the operator / for a specialized SI class and a double.
+		/// </summary>
+		/// <param name="si">The si.</param>
+		/// <param name="d">The double.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static T operator /(SIBase<T> si, double d)
 		{
 			return ((si as SI) / d).Cast<T>();
@@ -354,18 +507,50 @@ namespace TUGraz.VectoCore.Utils
 	}
 
 	/// <summary>
-	/// Class for Representing SI Units.
+	/// Class for representing generic SI Units.
 	/// </summary>
+	/// <remarks>
+	/// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute
+	/// </remarks>
 	[DataContract]
 	public class SI : IComparable
 	{
+		/// <summary>
+		/// The basic scalar value of the SI.
+		/// </summary>
+		[DataMember] protected readonly double Val;
+
+		/// <summary>
+		/// The denominator of the SI.
+		/// </summary>
 		[DataMember] protected readonly Unit[] Denominator;
-		[DataMember] protected readonly int Exponent;
+
+		/// <summary>
+		/// The numerator of the SI.
+		/// </summary>
 		[DataMember] protected readonly Unit[] Numerator;
+
+		/// <summary>
+		/// The current exponent for conversion operations (Square, Cubic, Linear, e.g. new SI(3).Square.Meter).
+		/// Can be reseted with Reset, Per, Cast.
+		/// </summary>
+		[DataMember] protected readonly int Exponent;
+
+		/// <summary>
+		/// A flag indicating if the current SI is in reciprocal mode (used in the <see cref="Per"/> method for reciprocal units: e.g. new SI(2).Meter.Per.Second) ==> [m/s]
+		/// Can be reseted with Reset, Per, Cast.
+		/// </summary>
 		[DataMember] protected readonly bool Reciproc;
+
+		/// <summary>
+		/// A flag indicating if the current SI is in reverse mode (used for conversions: e.g. new SI(2).Rounds.Per.Minute.ConverTo.Radian.Per.Second ==> [rpm/min] => [rad/s]).
+		/// </summary>
 		[DataMember] protected readonly bool Reverse;
-		[DataMember] protected readonly double Val;
 
+
+		/// <summary>
+		/// Enum for defining the Units.
+		/// </summary>
 		[SuppressMessage("ReSharper", "InconsistentNaming")]
 		protected enum Unit
 		{
@@ -384,9 +569,9 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		/// Creates a new dimensionless SI Unit.
+		/// Initializes a new instance of the <see cref="SI"/> class without any units (dimensionless, scalar) [-].
 		/// </summary>
-		/// <param name="val"></param>
+		/// <param name="val">The value.</param>
 		public SI(double val = 0.0)
 		{
 			Val = val;
@@ -397,8 +582,16 @@ namespace TUGraz.VectoCore.Utils
 			Exponent = 1;
 		}
 
-		protected SI(double val, IEnumerable<Unit> numerator, IEnumerable<Unit> denominator,
-			bool reciproc = false,
+		/// <summary>
+		/// Initializes a new instance of the <see cref="SI"/> class which allows to construct a new SI with all parameters.
+		/// </summary>
+		/// <param name="val">The value.</param>
+		/// <param name="numerator">The numerator.</param>
+		/// <param name="denominator">The denominator.</param>
+		/// <param name="reciproc">if set to <c>true</c> then the object is in reciproc mode (1/...)</param>
+		/// <param name="reverse">if set to <c>true</c> then the object is in reverse convertion mode (e.g. rpm/min => rad/s).</param>
+		/// <param name="exponent">The exponent for further conversions (e.g. Square.Meter).</param>
+		protected SI(double val, IEnumerable<Unit> numerator, IEnumerable<Unit> denominator, bool reciproc = false,
 			bool reverse = false, int exponent = 1)
 		{
 			Contract.Requires(numerator != null);
@@ -421,8 +614,12 @@ namespace TUGraz.VectoCore.Utils
 			Denominator = tmpDenominator.ToArray();
 		}
 
-		protected SI(double val, SI unit)
-			: this(val, unit.Numerator, unit.Denominator) {}
+		/// <summary>
+		/// Initializes a new instance of the <see cref="SI"/> class which copies the units from an already existing SI.
+		/// </summary>
+		/// <param name="val">The value.</param>
+		/// <param name="unit">The unit.</param>
+		protected SI(double val, SI unit) : this(val, unit.Numerator, unit.Denominator) {}
 
 		protected SI(SI si, double? factor = null, Unit? fromUnit = null, Unit? toUnit = null,
 			bool? reciproc = null, bool? reverse = null, int? exponent = null)
@@ -439,6 +636,7 @@ namespace TUGraz.VectoCore.Utils
 			Reverse = reverse ?? si.Reverse;
 			Exponent = exponent ?? si.Exponent;
 
+			// if reverse mode then swap fromUnit and toUnit and invert factor.
 			if (Reverse) {
 				var tmp = fromUnit;
 				fromUnit = toUnit;
@@ -446,6 +644,7 @@ namespace TUGraz.VectoCore.Utils
 				factor = 1 / factor;
 			}
 
+			// add the unit as often as is defined by the exponent.
 			for (var i = 0; i < Exponent; i++) {
 				if (!Reciproc) {
 					UpdateUnit(fromUnit, toUnit, denominator);
@@ -460,15 +659,17 @@ namespace TUGraz.VectoCore.Utils
 				}
 			}
 
-			foreach (var v in numerator.ToArray().Where(v => denominator.Contains(v))) {
-				denominator.Remove(v);
-				numerator.Remove(v);
-			}
-
 			Numerator = denominator.ToArray();
 			Denominator = numerator.ToArray();
 		}
 
+		/// <summary>
+		/// Adds the new toUnit to the units collection and removes the fromUnit.
+		/// </summary>
+		/// <param name="fromUnit">From unit.</param>
+		/// <param name="toUnit">To unit.</param>
+		/// <param name="units">The units.</param>
+		/// <exception cref="VectoException"></exception>
 		private void UpdateUnit(Unit? fromUnit, Unit? toUnit, ICollection<Unit> units)
 		{
 			if (Reverse && fromUnit.HasValue) {
@@ -489,7 +690,7 @@ namespace TUGraz.VectoCore.Utils
 		/// Converts the SI unit to another SI unit, defined by term(s) following after the ConvertTo().
 		/// The Conversion Mode is active until an arithmetic operator is used (+,-,*,/), 
 		/// or the .Value-Method, or the .Cast-Method were called.
-		/// ATTENTION: Before returning an SI Unit, ensure to cancel Conversion Mode (with .Value or .Cast).
+		/// ATTENTION: Before returning an SI Unit, ensure to cancel Conversion Mode (with or Cast).
 		/// </summary>
 		/// <returns></returns>
 		public SI ConvertTo()
@@ -500,8 +701,7 @@ namespace TUGraz.VectoCore.Utils
 		/// <summary>
 		/// Casts the SI Unit to the concrete unit type (if the units allow such an cast).
 		/// </summary>
-		/// <typeparam name="T"></typeparam>
-		/// <returns></returns>
+		/// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam>
 		public T Cast<T>() where T : SIBase<T>
 		{
 			var t = SIBase<T>.Create(Val);
@@ -514,19 +714,27 @@ namespace TUGraz.VectoCore.Utils
 		/// <summary>
 		/// Converts the derived SI units to the basic units and returns this as a new SI object.
 		/// </summary>
-		/// <returns></returns>
 		public SI ToBasicUnits()
 		{
 			var numerator = new List<Unit>();
 			var denominator = new List<Unit>();
-			Numerator.ToList().ForEach(unit => ConvertToBasicUnits(unit, numerator, denominator));
-			Denominator.ToList().ForEach(unit => ConvertToBasicUnits(unit, denominator, numerator));
-			return new SI(Val, numerator, denominator);
+			var numeratorFactor = 1.0;
+			Numerator.ToList().ForEach(unit => ConvertToBasicUnits(unit, numerator, denominator, ref numeratorFactor));
+			var denominatorFactor = 1.0;
+			Denominator.ToList().ForEach(unit => ConvertToBasicUnits(unit, denominator, numerator, ref denominatorFactor));
+			return new SI(Val * numeratorFactor / denominatorFactor, numerator, denominator);
 		}
 
 
+		/// <summary>
+		/// Converts to basic units. e.g [W] => [kgm�/s�]
+		/// </summary>
+		/// <param name="unit">The unit.</param>
+		/// <param name="numerator">The numerator.</param>
+		/// <param name="denominator">The denominator.</param>
+		/// <param name="factor">The factor.</param>
 		private static void ConvertToBasicUnits(Unit unit, ICollection<Unit> numerator,
-			ICollection<Unit> denominator)
+			ICollection<Unit> denominator, ref double factor)
 		{
 			switch (unit) {
 				case Unit.W:
@@ -546,7 +754,7 @@ namespace TUGraz.VectoCore.Utils
 					denominator.Add(Unit.s);
 					break;
 				case Unit.t:
-					numerator.Add(Unit.k);
+					factor *= 1000;
 					numerator.Add(Unit.k);
 					numerator.Add(Unit.g);
 					break;
@@ -557,13 +765,17 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Gets the basic double value.
+		/// Gets the underlying scalar double value.
 		/// </summary>
 		public double Value()
 		{
 			return Val;
 		}
 
+
+		/// <summary>
+		/// Clones this instance.
+		/// </summary>
 		public SI Clone()
 		{
 			return new SI(Val, Numerator, Denominator);
@@ -578,22 +790,42 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		/// Returns the absolute value.
+		/// Returns the Square root of value and units of the SI.
 		/// </summary>
 		public SI Sqrt()
 		{
 			var si = ToBasicUnits();
-			var numerator = si.Numerator.Where((u, i) => i % 2 == 0);
-			var denominator = si.Denominator.Where((u, i) => i % 2 == 0);
-			var root = new SI(Math.Sqrt(si.Val), numerator, denominator);
-			Contract.Requires(root * root == this);
-			return root;
+			if (si.Numerator.Length % 2 != 0 || si.Denominator.Length % 2 != 0) {
+				throw new VectoException(
+					string.Format("The squareroot cannot be calculated because the Unit-Exponents are not even: [{0}]",
+						si.GetUnitString()));
+			}
+
+			var numerator = new List<Unit>();
+			var currentNumerator = si.Numerator.ToList();
+			while (currentNumerator.Count != 0) {
+				var unit = currentNumerator.First();
+				currentNumerator.Remove(unit);
+				currentNumerator.Remove(unit);
+				numerator.Add(unit);
+			}
+
+			var denominator = new List<Unit>();
+			var currentDenominator = si.Denominator.ToList();
+			while (currentDenominator.Count != 0) {
+				var unit = currentDenominator.First();
+				currentDenominator.Remove(unit);
+				currentDenominator.Remove(unit);
+				denominator.Add(unit);
+			}
+
+			return new SI(Math.Sqrt(si.Val), numerator, denominator);
 		}
 
 		#region Unit Definitions
 
 		/// <summary>
-		///     Defines the denominator by the terms following after the Per.
+		/// Defines the denominator by the terms following after the Per.
 		/// </summary>
 		[DebuggerHidden]
 		public SI Per
@@ -602,7 +834,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Takes all following terms as cubic terms (=to the power of 3).
+		/// Takes all following terms as cubic terms (=to the power of 3).
 		/// </summary>
 		[DebuggerHidden]
 		public SI Cubic
@@ -611,7 +843,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Takes all following terms as quadratic terms (=to the power of 2).
+		/// Takes all following terms as quadratic terms (=to the power of 2).
 		/// </summary>
 		[DebuggerHidden]
 		public SI Square
@@ -620,7 +852,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Takes all following terms as linear terms (=to the power of 1).
+		/// Takes all following terms as linear terms (=to the power of 1).
 		/// </summary>
 		[DebuggerHidden]
 		public SI Linear
@@ -629,7 +861,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     [g] (to basic unit: [kg])
+		/// [g] (to basic unit: [kg])
 		/// </summary>
 		[DebuggerHidden]
 		public SI Gramm
@@ -638,7 +870,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///  [t] (to basic unit: [kg])
+		/// [t] (to basic unit: [kg])
 		/// </summary>
 		[DebuggerHidden]
 		public SI Ton
@@ -648,7 +880,7 @@ namespace TUGraz.VectoCore.Utils
 
 
 		/// <summary>
-		///     [N]
+		/// [N]
 		/// </summary>
 		[DebuggerHidden]
 		public SI Newton
@@ -657,7 +889,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     [W]
+		/// [W]
 		/// </summary>
 		[DebuggerHidden]
 		public SI Watt
@@ -666,7 +898,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     [m]
+		/// [m]
 		/// </summary>
 		[DebuggerHidden]
 		public SI Meter
@@ -675,7 +907,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     [s]
+		/// [s]
 		/// </summary>
 		[DebuggerHidden]
 		public SI Second
@@ -684,7 +916,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     [rad]
+		/// [-]. Defines radian. Only virtual. Has no real SI unit.
 		/// </summary>
 		[DebuggerHidden]
 		public SI Radian
@@ -694,7 +926,7 @@ namespace TUGraz.VectoCore.Utils
 
 
 		/// <summary>
-		///     Converts to/from Radiant
+		/// [-]. Converts to/from Radiant. Internally everything is stored in radian.
 		/// </summary>
 		[DebuggerHidden]
 		public SI Rounds
@@ -703,7 +935,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Converts to/from Second
+		/// [s] Converts to/from Second. Internally everything is stored in seconds.
 		/// </summary>
 		[DebuggerHidden]
 		public SI Hour
@@ -712,7 +944,7 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Converts to/from Second
+		/// [s] Converts to/from Second. Internally everything is stored in seconds.
 		/// </summary>
 		[DebuggerHidden]
 		public SI Minute
@@ -720,13 +952,17 @@ namespace TUGraz.VectoCore.Utils
 			get { return new SI(this, 60.0, Unit.min, Unit.s); }
 		}
 
+		/// <summary>
+		/// Quantifier for milli (1/1000).
+		/// </summary>
+		[DebuggerHidden]
 		public SI Milli
 		{
 			get { return new SI(this, 0.001, Unit.milli); }
 		}
 
 		/// <summary>
-		///     Converts to/from 1000 * Basic Unit
+		/// Quantifier for Kilo (1000).
 		/// </summary>
 		[DebuggerHidden]
 		public SI Kilo
@@ -735,18 +971,28 @@ namespace TUGraz.VectoCore.Utils
 		}
 
 		/// <summary>
-		///     Converts to/from Basic Unit / 100
+		/// Quantifier for Centi (1/100)
 		/// </summary>
 		[DebuggerHidden]
 		public SI Centi
 		{
-			get { return new SI(this, 1.0 / 100.0, Unit.c); }
+			get { return new SI(this, 0.01, Unit.c); }
 		}
 
 		#endregion
 
 		#region Operators
 
+		/// <summary>
+		/// Implements the operator +.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		/// <exception cref="VectoException"></exception>
+		[DebuggerHidden]
 		public static SI operator +(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
@@ -759,179 +1005,309 @@ namespace TUGraz.VectoCore.Utils
 			return new SI(si1.Val + si2.Val, si1.Numerator, si1.Denominator);
 		}
 
+		/// <summary>
+		/// Implements the operator -.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		/// <exception cref="VectoException"></exception>
+		[DebuggerHidden]
 		public static SI operator -(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
 			Contract.Requires(si2 != null);
 			if (!si1.HasEqualUnit(si2)) {
 				throw new VectoException(
-					string.Format("Operator '-' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+					string.Format("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2));
 			}
 			return new SI(si1.Val - si2.Val, si1.Numerator, si1.Denominator);
 		}
 
-		public static SI operator *(SI si1, SI si2)
+		/// <summary>
+		/// Implements the operator -.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static SI operator -(SI si1)
 		{
 			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			var numerator = si1.Numerator.Concat(si2.Numerator);
-			var denominator = si1.Denominator.Concat(si2.Denominator);
-			return new SI(si1.Val * si2.Val, numerator, denominator);
+			return new SI(-si1.Val, si1);
 		}
 
-		public static SI operator /(SI si1, SI si2)
+		/// <summary>
+		/// Implements the operator *.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static SI operator *(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
 			Contract.Requires(si2 != null);
-			var numerator = si1.Numerator.Concat(si2.Denominator);
-			var denominator = si1.Denominator.Concat(si2.Numerator);
-			return new SI(si1.Val / si2.Val, numerator, denominator);
-		}
-
-		public static SI operator +(SI si1, double d)
-		{
-			Contract.Requires(si1 != null);
-			return new SI(si1.Val + d, si1);
-		}
-
-		public static SI operator +(double d, SI si1)
-		{
-			Contract.Requires(si1 != null);
-			return si1 + d;
-		}
-
-		public static SI operator -(SI si1, double d)
-		{
-			Contract.Requires(si1 != null);
-			return new SI(si1.Val - d, si1);
-		}
-
-		public static SI operator -(double d, SI si1)
-		{
-			Contract.Requires(si1 != null);
-			return new SI(d - si1.Val, si1);
-		}
-
-		public static SI operator -(SI si1)
-		{
-			Contract.Requires(si1 != null);
-			return 0 - si1;
+			var numerator = si1.Numerator.Concat(si2.Numerator);
+			var denominator = si1.Denominator.Concat(si2.Denominator);
+			return new SI(si1.Val * si2.Val, numerator, denominator);
 		}
 
+		/// <summary>
+		/// Implements the operator *.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="d">The d.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static SI operator *(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
 			return new SI(si1.Val * d, si1);
 		}
 
+		/// <summary>
+		/// Implements the operator *.
+		/// </summary>
+		/// <param name="d">The d.</param>
+		/// <param name="si1">The si1.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static SI operator *(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
 			return new SI(d * si1.Val, si1);
 		}
 
+		/// <summary>
+		/// Implements the operator /.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static SI operator /(SI si1, SI si2)
+		{
+			Contract.Requires(si1 != null);
+			Contract.Requires(si2 != null);
+			var numerator = si1.Numerator.Concat(si2.Denominator);
+			var denominator = si1.Denominator.Concat(si2.Numerator);
+			return new SI(si1.Val / si2.Val, numerator, denominator);
+		}
+
+		/// <summary>
+		/// Implements the operator /.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="d">The d.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static SI operator /(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
 			return new SI(si1.Val / d, si1);
 		}
 
+		/// <summary>
+		/// Implements the operator /.
+		/// </summary>
+		/// <param name="d">The d.</param>
+		/// <param name="si1">The si1.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
 		public static SI operator /(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
-			return new SI(d / si1.Val, si1);
+			return new SI(d / si1.Val, si1.Denominator, si1.Numerator);
 		}
 
+		/// <summary>
+		/// Implements the operator &lt;.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		/// <exception cref="VectoException"></exception>
+		[DebuggerHidden]
 		public static bool operator <(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
 			Contract.Requires(si2 != null);
 			if (!si1.HasEqualUnit(si2)) {
 				throw new VectoException(
-					string.Format("Operator '<' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+					string.Format("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2));
 			}
 			return si1.Val < si2.Val;
 		}
 
-		public static bool operator >(SI si1, SI si2)
+		/// <summary>
+		/// Implements the operator &lt;.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="d">The d.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static bool operator <(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			if (!si1.HasEqualUnit(si2)) {
-				throw new VectoException(
-					string.Format("Operator '>' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
-			}
-			return si1.Val > si2.Val;
+			return si1 != null && si1.Val < d;
 		}
 
-		public static bool operator <=(SI si1, SI si2)
+		/// <summary>
+		/// Implements the operator &gt;.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		/// <exception cref="VectoException"></exception>
+		[DebuggerHidden]
+		public static bool operator >(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
 			Contract.Requires(si2 != null);
 			if (!si1.HasEqualUnit(si2)) {
 				throw new VectoException(
-					string.Format("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
+					string.Format("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2));
 			}
-			return si1.Val <= si2.Val;
+			return si1.Val > si2.Val;
 		}
 
-		public static bool operator >=(SI si1, SI si2)
+		/// <summary>
+		/// Implements the operator &gt;.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="d">The d.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static bool operator >(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
-			Contract.Requires(si2 != null);
-			if (!si1.HasEqualUnit(si2)) {
-				throw new VectoException(
-					string.Format("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2));
-			}
-			return si1.Val >= si2.Val;
+			return si1 != null && si1.Val > d;
 		}
 
-		public static bool operator <(SI si1, double d)
+		/// <summary>
+		/// Implements the operator &gt;.
+		/// </summary>
+		/// <param name="d">The d.</param>
+		/// <param name="si1">The si1.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static bool operator >(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val < d;
+			return si1 != null && d > si1.Val;
 		}
 
-		public static bool operator >(SI si1, double d)
+		/// <summary>
+		/// Implements the operator &lt;.
+		/// </summary>
+		/// <param name="d">The d.</param>
+		/// <param name="si1">The si1.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static bool operator <(double d, SI si1)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val > d;
+			return si1 != null && d < si1.Val;
 		}
 
-		public static bool operator <=(SI si1, double d)
+		/// <summary>
+		/// Implements the operator &lt;=.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		/// <exception cref="VectoException"></exception>
+		[DebuggerHidden]
+		public static bool operator <=(SI si1, SI si2)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val <= d;
+			Contract.Requires(si2 != null);
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1, si2));
+			}
+			return si1.Val <= si2.Val;
 		}
 
-		public static bool operator >=(SI si1, double d)
+		/// <summary>
+		/// Implements the operator &lt;=.
+		/// </summary>
+		/// <param name="si1">The si1.</param>
+		/// <param name="d">The d.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static bool operator <=(SI si1, double d)
 		{
 			Contract.Requires(si1 != null);
-			return si1 != null && si1.Val >= d;
+			return si1 != null && si1.Val <= d;
 		}
 
-		#endregion
-
-		#region Double Conversion
-
 		/// <summary>
-		///     Casts an SI Unit to an double.
+		/// Implements the operator &gt;=.
 		/// </summary>
-		/// <param name="si"></param>
-		/// <returns></returns>
-		public static explicit operator double(SI si)
+		/// <param name="si1">The si1.</param>
+		/// <param name="si2">The si2.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		/// <exception cref="VectoException"></exception>
+		[DebuggerHidden]
+		public static bool operator >=(SI si1, SI si2)
 		{
-			return si.Val;
+			Contract.Requires(si1 != null);
+			Contract.Requires(si2 != null);
+			if (!si1.HasEqualUnit(si2)) {
+				throw new VectoException(
+					string.Format("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1, si2));
+			}
+			return si1.Val >= si2.Val;
 		}
 
 		/// <summary>
-		///     Casts a double to an SI Unit.
+		/// Implements the operator &gt;=.
 		/// </summary>
-		/// <param name="d"></param>
-		/// <returns></returns>
-		public static explicit operator SI(double d)
+		/// <param name="si1">The si1.</param>
+		/// <param name="d">The d.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
+		[DebuggerHidden]
+		public static bool operator >=(SI si1, double d)
 		{
-			return new SI(d);
+			Contract.Requires(si1 != null);
+			return si1 != null && si1.Val >= d;
 		}
 
 		#endregion
@@ -966,6 +1342,13 @@ namespace TUGraz.VectoCore.Utils
 			return ToString(null);
 		}
 
+		/// <summary>
+		/// Returns a <see cref="System.String" /> that represents this instance.
+		/// </summary>
+		/// <param name="format">The format.</param>
+		/// <returns>
+		/// A <see cref="System.String" /> that represents this instance.
+		/// </returns>
 		public virtual string ToString(string format)
 		{
 			if (string.IsNullOrEmpty(format)) {
@@ -982,6 +1365,8 @@ namespace TUGraz.VectoCore.Utils
 		/// <summary>
 		/// Compares the Unit-Parts of two SI Units.
 		/// </summary>
+		/// <param name="si">The si.</param>
+		/// <returns></returns>
 		public bool HasEqualUnit(SI si)
 		{
 			Contract.Requires(si != null);
@@ -992,6 +1377,13 @@ namespace TUGraz.VectoCore.Utils
 					ToBasicUnits().Numerator.OrderBy(x => x).SequenceEqual(si.ToBasicUnits().Numerator.OrderBy(x => x));
 		}
 
+		/// <summary>
+		/// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
+		/// </summary>
+		/// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
+		/// <returns>
+		///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
+		/// </returns>
 		public override bool Equals(object obj)
 		{
 			if (ReferenceEquals(null, obj)) {
@@ -1004,16 +1396,34 @@ namespace TUGraz.VectoCore.Utils
 			return other != null && Val.Equals(other.Val) && HasEqualUnit(other);
 		}
 
+		/// <summary>
+		/// Determines whether the specified si is equal.
+		/// </summary>
+		/// <param name="si">The si.</param>
+		/// <param name="tolerance">The tolerance.</param>
+		/// <returns></returns>
 		public bool IsEqual(SI si, double tolerance = DoubleExtensionMethods.Tolerance)
 		{
 			return HasEqualUnit(si) && Val.IsEqual(si.Val, tolerance);
 		}
 
+		/// <summary>
+		/// Determines whether the specified value is equal.
+		/// </summary>
+		/// <param name="val">The value.</param>
+		/// <param name="tolerance">The tolerance.</param>
+		/// <returns></returns>
 		public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
 		{
 			return Val.IsEqual(val, tolerance);
 		}
 
+		/// <summary>
+		/// Returns a hash code for this instance.
+		/// </summary>
+		/// <returns>
+		/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
+		/// </returns>
 		public override int GetHashCode()
 		{
 			unchecked {
@@ -1025,6 +1435,13 @@ namespace TUGraz.VectoCore.Utils
 			}
 		}
 
+		/// <summary>
+		/// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.
+		/// </summary>
+		/// <param name="obj">An object to compare with this instance.</param>
+		/// <returns>
+		/// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less than zero This instance precedes <paramref name="obj" /> in the sort order. Zero This instance occurs in the same position in the sort order as <paramref name="obj" />. Greater than zero This instance follows <paramref name="obj" /> in the sort order.
+		/// </returns>
 		public int CompareTo(object obj)
 		{
 			var si = (obj as SI);
@@ -1045,11 +1462,27 @@ namespace TUGraz.VectoCore.Utils
 			return this < si ? -1 : 0;
 		}
 
+		/// <summary>
+		/// Implements the operator ==.
+		/// </summary>
+		/// <param name="left">The left.</param>
+		/// <param name="right">The right.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
 		public static bool operator ==(SI left, SI right)
 		{
 			return Equals(left, right);
 		}
 
+		/// <summary>
+		/// Implements the operator !=.
+		/// </summary>
+		/// <param name="left">The left.</param>
+		/// <param name="right">The right.</param>
+		/// <returns>
+		/// The result of the operator.
+		/// </returns>
 		public static bool operator !=(SI left, SI right)
 		{
 			return !Equals(left, right);
@@ -1057,23 +1490,20 @@ namespace TUGraz.VectoCore.Utils
 
 		#endregion
 
-		public Scalar Scalar()
-		{
-			var si = ToBasicUnits();
-			if (si.Numerator.Length == 0 && si.Denominator.Length == 0) {
-				return Val.SI<Scalar>();
-			}
-			throw new InvalidCastException("The SI Unit is not a scalar.");
-		}
-
-
+		/// <summary>
+		/// Convert the SI to a string in the wished output format.
+		/// </summary>
+		/// <param name="decimals">The decimals.</param>
+		/// <param name="outputFactor">The output factor.</param>
+		/// <param name="showUnit">The show unit.</param>
+		/// <returns></returns>
 		public virtual string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null)
 		{
 			decimals = decimals ?? 4;
 			outputFactor = outputFactor ?? 1.0;
 			showUnit = showUnit ?? false;
 
-			var format = string.Format("{{0:F{0}}}" + (showUnit.Value ? " [{2}]" : ""), decimals);
+			var format = string.Format("{{0:F{0}}}" + (showUnit.Value ? " [{{1}}]" : ""), decimals);
 			return string.Format(CultureInfo.InvariantCulture, format, Val * outputFactor, GetUnitString());
 		}
 	}
diff --git a/VectoCore/Utils/VectoMath.cs b/VectoCore/Utils/VectoMath.cs
index 2cb276d6bca0177640d0be00f32b92b6518a4936..74bd781f55533d1c0e2e7a2ad6edb2c89b1a119c 100644
--- a/VectoCore/Utils/VectoMath.cs
+++ b/VectoCore/Utils/VectoMath.cs
@@ -21,7 +21,7 @@ namespace TUGraz.VectoCore.Utils
 		/// <returns></returns>
 		public static TResult Interpolate<T, TResult>(T x1, T x2, TResult y1, TResult y2, T xint) where T : SI
 			where TResult : SIBase<TResult>
-		{ 
+		{
 			return ((xint - x1) * (y2 - y1) / (x2 - x1) + y1).Cast<TResult>();
 		}
 
@@ -29,7 +29,7 @@ namespace TUGraz.VectoCore.Utils
 		public static double Interpolate<T>(T x1, T x2, double y1, double y2, T xint)
 			where T : SI
 		{
-			return ((xint - x1) * (y2 - y1) / (x2 - x1) + y1).Value();
+			return (((xint - x1) * (y2 - y1) / (x2 - x1)).Cast<Scalar>() + y1).Value();
 		}
 
 		public static TResult Interpolate<TResult>(double x1, double x2, TResult y1, TResult y2, double xint)
diff --git a/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs
index e36915c55b25b5bfa6f00e5b35d6676e2b54a3b5..81b1d0d7a95974e2cd93a41288cc6eeb101ebd7b 100644
--- a/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs
+++ b/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs
@@ -172,7 +172,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 
 				var angularSpeed = r.Next(1000).SI<PerSecond>();
 				var torque = tc.LookupTorque(exp.nu, angularSpeed, referenceSpeed);
-				AssertHelper.AreRelativeEqual(exp.torque * Math.Pow(angularSpeed.Value() / referenceSpeed.Value(), 2), torque.Value());
+				AssertHelper.AreRelativeEqual(
+					exp.torque.SI<NewtonMeter>() * Math.Pow((angularSpeed / referenceSpeed).Cast<Scalar>(), 2), torque);
 			}
 		}
 
@@ -411,7 +412,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(longHaulMission.CycleFile).ReadLine()));
 
 			Assert.AreEqual(0.SI<Kilogram>(), longHaulMission.MinLoad);
-			Assert.AreEqual(0.5882 * vehicleData.GrossVehicleMassRating - 2511.8, longHaulMission.RefLoad);
+			Assert.AreEqual(0.5882 * vehicleData.GrossVehicleMassRating - 2511.8.SI<Kilogram>(), longHaulMission.RefLoad);
 			Assert.AreEqual(vehicleData.GrossVehicleMassRating - longHaulMission.MassExtra - vehicleData.CurbWeight,
 				longHaulMission.MaxLoad);
 
@@ -428,7 +429,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(regionalDeliveryMission.CycleFile).ReadLine()));
 
 			Assert.AreEqual(0.SI<Kilogram>(), regionalDeliveryMission.MinLoad);
-			Assert.AreEqual(0.3941 * vehicleData.GrossVehicleMassRating - 1705.9, regionalDeliveryMission.RefLoad);
+			Assert.AreEqual(0.3941 * vehicleData.GrossVehicleMassRating - 1705.9.SI<Kilogram>(), regionalDeliveryMission.RefLoad);
 			Assert.AreEqual(vehicleData.GrossVehicleMassRating - regionalDeliveryMission.MassExtra - vehicleData.CurbWeight,
 				regionalDeliveryMission.MaxLoad);
 
@@ -445,7 +446,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			Assert.IsTrue(!string.IsNullOrEmpty(new StreamReader(urbanDeliveryMission.CycleFile).ReadLine()));
 
 			Assert.AreEqual(0.SI<Kilogram>(), urbanDeliveryMission.MinLoad);
-			Assert.AreEqual(0.3941 * vehicleData.GrossVehicleMassRating - 1705.9, urbanDeliveryMission.RefLoad);
+			Assert.AreEqual(0.3941 * vehicleData.GrossVehicleMassRating - 1705.9.SI<Kilogram>(), urbanDeliveryMission.RefLoad);
 			Assert.AreEqual(vehicleData.GrossVehicleMassRating - urbanDeliveryMission.MassExtra - vehicleData.CurbWeight,
 				urbanDeliveryMission.MaxLoad);
 		}
diff --git a/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs b/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs
index 0adcb3e64171a6bb6b1e1e11225d96c4c8894c8d..70bd286fa728e0fffe42957a5ad77a0464ce45da 100644
--- a/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs
+++ b/VectoCoreTest/Models/SimulationComponent/RetarderTest.cs
@@ -32,21 +32,21 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 			// --------
 			outPort.Request(absTime, dt, 0.SI<NewtonMeter>(), 10.RPMtoRad());
 
-			Assert.AreEqual(10.RPMtoRad().Value(), (double)nextRequest.AngularVelocity, Delta);
-			Assert.AreEqual(10.002, (double)nextRequest.Torque, Delta);
+			Assert.AreEqual(10.RPMtoRad().Value(), nextRequest.AngularVelocity.Value(), Delta);
+			Assert.AreEqual(10.002, nextRequest.Torque.Value(), Delta);
 
 			// --------
 			outPort.Request(absTime, dt, 100.SI<NewtonMeter>(), 1000.RPMtoRad());
 
-			Assert.AreEqual(1000.RPMtoRad().Value(), (double)nextRequest.AngularVelocity, Delta);
-			Assert.AreEqual(112, (double)nextRequest.Torque, Delta);
+			Assert.AreEqual(1000.RPMtoRad().Value(), nextRequest.AngularVelocity.Value(), Delta);
+			Assert.AreEqual(112, nextRequest.Torque.Value(), Delta);
 
 			// --------
 
 			outPort.Request(absTime, dt, 50.SI<NewtonMeter>(), 1550.RPMtoRad());
 
-			Assert.AreEqual(1550.RPMtoRad().Value(), (double)nextRequest.AngularVelocity, Delta);
-			Assert.AreEqual(50 + 14.81, (double)nextRequest.Torque, Delta);
+			Assert.AreEqual(1550.RPMtoRad().Value(), nextRequest.AngularVelocity.Value(), Delta);
+			Assert.AreEqual(50 + 14.81, nextRequest.Torque.Value(), Delta);
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs b/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
index 2fbb805e92de9c0932e1dc1a4a85379569e0f545..d0b1e4011d67a6e16583682a3031cc8d2ca219e6 100644
--- a/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
+++ b/VectoCoreTest/Models/SimulationComponentData/FuelConsumptionMapTest.cs
@@ -34,8 +34,8 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 			for (var i = 1; i < lines.Count(); i++) {
 				var entry = lines[i].Split(',').Select(x => double.Parse(x, CultureInfo.InvariantCulture)).ToArray();
 				try {
-					Assert.AreEqual((double)entry[2].SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second,
-						(double)map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad()),
+					Assert.AreEqual(entry[2].SI().Gramm.Per.Hour.ConvertTo().Kilo.Gramm.Per.Second.Value(),
+						map.GetFuelConsumption(entry[1].SI<NewtonMeter>(), entry[0].RPMtoRad()).Value(),
 						Tolerance,
 						string.Format("Line: {0}, n={1}, T={2}", (i + 2), entry[0].SI().Rounds.Per.Minute, entry[1]));
 				} catch (VectoException ex) {
diff --git a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs
index 013eb36ec3d57812aefa081ffd0d495625c281c1..e554a57921b69771e2f4e5d82f071ada2b6165a8 100644
--- a/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs
+++ b/VectoCoreTest/Models/SimulationComponentData/FullLoadCurveTest.cs
@@ -27,7 +27,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 		public void TestFullLoadEngineSpeedRated()
 		{
 			var fldCurve = EngineFullLoadCurve.ReadFromFile(CoachEngineFLD);
-			Assert.AreEqual(181.8444, (double)fldCurve.RatedSpeed, Tolerance);
+			Assert.AreEqual(181.8444, fldCurve.RatedSpeed.Value(), Tolerance);
 		}
 
 		[TestMethod]
@@ -77,12 +77,12 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 		{
 			var fldCurve = EngineFullLoadCurve.ReadFromFile(CoachEngineFLD);
 			fldCurve.EngineData = new CombustionEngineData() { IdleSpeed = 560.RPMtoRad() };
-			Assert.AreEqual(130.691151551712, fldCurve.PreferredSpeed.Value(), Tolerance);
-			Assert.AreEqual(194.515816596908, fldCurve.N95hSpeed.Value(), Tolerance);
-			Assert.AreEqual(94.2463966015023, fldCurve.LoSpeed.Value(), Tolerance);
-			Assert.AreEqual(219.084329211505, fldCurve.HiSpeed.Value(), Tolerance);
-			Assert.AreEqual(2300, fldCurve.MaxLoadTorque.Value(), Tolerance);
-			Assert.AreEqual(-320, fldCurve.MaxDragTorque.Value(), Tolerance);
+			AssertHelper.AreRelativeEqual(130.691151551712.SI<PerSecond>(), fldCurve.PreferredSpeed);
+			AssertHelper.AreRelativeEqual(194.515816596908.SI<PerSecond>(), fldCurve.N95hSpeed);
+			AssertHelper.AreRelativeEqual(94.2463966015023.SI<PerSecond>(), fldCurve.LoSpeed);
+			AssertHelper.AreRelativeEqual(219.084329211505.SI<PerSecond>(), fldCurve.HiSpeed);
+			AssertHelper.AreRelativeEqual(2300.SI<NewtonMeter>(), fldCurve.MaxLoadTorque);
+			AssertHelper.AreRelativeEqual(-320.SI<NewtonMeter>(), fldCurve.MaxDragTorque);
 		}
 
 		/// <summary>
diff --git a/VectoCoreTest/Utils/AssertHelper.cs b/VectoCoreTest/Utils/AssertHelper.cs
index 079d3ef0cc9ea08b604cd988c6f1d8971a395f6f..62cc70ae187d9a1f37b9dedf2748c4eb30bf775b 100644
--- a/VectoCoreTest/Utils/AssertHelper.cs
+++ b/VectoCoreTest/Utils/AssertHelper.cs
@@ -17,22 +17,31 @@ namespace TUGraz.VectoCore.Tests.Utils
 				Assert.Fail("Expected Exception {0}, but no exception occured.", typeof(T));
 			} catch (T ex) {
 				if (!string.IsNullOrEmpty(message)) {
-					Assert.AreEqual(message, ex.Message,
-						string.Format("Expected Exception message: {0}, but got message: {1}", message, ex.Message));
+					Assert.AreEqual(message, ex.Message);
 				}
 			}
 		}
 
-		public static void AreRelativeEqual(SI expected, SI actual)
+		[DebuggerHidden]
+		public static void AreRelativeEqual(SI expected, SI actual,
+			double toleranceFactor = DoubleExtensionMethods.ToleranceFactor)
 		{
 			Assert.IsTrue(actual.HasEqualUnit(expected),
 				string.Format("Wrong SI Units: expected: {0}, actual: {1}", expected.ToBasicUnits(), actual.ToBasicUnits()));
-			AreRelativeEqual(expected.Value(), actual.Value());
+			AreRelativeEqual(expected.Value(), actual.Value(), toleranceFactor: toleranceFactor);
+		}
+
+		[DebuggerHidden]
+		public static void AreRelativeEqual(Scalar expected, Scalar actual,
+			double toleranceFactor = DoubleExtensionMethods.ToleranceFactor)
+		{
+			Assert.IsTrue(expected.HasEqualUnit(new SI()) && actual.HasEqualUnit(new SI()), "Units of Scalars must be empty.");
+			AreRelativeEqual(expected.Value(), actual.Value(), toleranceFactor: toleranceFactor);
 		}
 
 		[DebuggerHidden]
 		public static void AreRelativeEqual(double expected, double actual, string message = null,
-			double toleranceFactor = DoubleExtensionMethods.Tolerance)
+			double toleranceFactor = DoubleExtensionMethods.ToleranceFactor)
 		{
 			if (!string.IsNullOrWhiteSpace(message)) {
 				message = "\n" + message;
@@ -48,13 +57,13 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 			if (expected.IsEqual(0.0)) {
 				Assert.AreEqual(expected, actual, DoubleExtensionMethods.Tolerance,
-					string.Format("Actual value is different. Difference: {3} Expected: {0}, Actual: {1}, Tolerance: {2}{4}",
+					string.Format("Actual value is different. Expected: {0}, Actual: {1}, Difference: {3}, ToleranceFactor: {2}{4}",
 						expected, actual, toleranceFactor, expected - actual, message));
 				return;
 			}
 
 			Assert.IsTrue(Math.Abs(actual / expected - 1) < toleranceFactor,
-				string.Format("Actual value is different. Difference: {3} Expected: {0}, Actual: {1}, Tolerance: {2}{4}",
+				string.Format("Actual value is different. Expected: {0}, Actual: {1}, Difference: {3}, ToleranceFactor: {2}{4}",
 					expected, actual, toleranceFactor, expected - actual, message));
 		}
 	}
diff --git a/VectoCoreTest/Utils/SITest.cs b/VectoCoreTest/Utils/SITest.cs
index a98b038e5dd93421815689b553bd311e1251daf1..1572bf5d1a22e23159f1bde3b72ed5109333b1e4 100644
--- a/VectoCoreTest/Utils/SITest.cs
+++ b/VectoCoreTest/Utils/SITest.cs
@@ -1,5 +1,4 @@
 using System;
-using System.Diagnostics.CodeAnalysis;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using TUGraz.VectoCore.Exceptions;
 using TUGraz.VectoCore.Utils;
@@ -9,24 +8,6 @@ namespace TUGraz.VectoCore.Tests.Utils
 	[TestClass]
 	public class SITest
 	{
-		/// <summary>
-		/// Assert an expected Exception.
-		/// </summary>
-		/// <typeparam name="T"></typeparam>
-		/// <param name="func"></param>
-		/// <param name="message"></param>
-		public static void AssertException<T>(Action func, string message = null) where T : Exception
-		{
-			try {
-				func();
-				Assert.Fail("Expected Exception {0}, but no exception occured.", typeof(T));
-			} catch (T ex) {
-				if (message != null) {
-					Assert.AreEqual(message, ex.Message);
-				}
-			}
-		}
-
 		[TestMethod]
 		public void SI_TypicalUsageTest()
 		{
@@ -62,7 +43,7 @@ namespace TUGraz.VectoCore.Tests.Utils
 			var angVeloSum = angularVelocity + angularVelocity2;
 			Assert.IsInstanceOfType(angVeloSum, typeof(PerSecond));
 			Assert.AreEqual((400.0 + 600) / 60 * 2 * Math.PI, angVeloSum.Value(), 0.0000001);
-			AssertException<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; });
+			AssertHelper.Exception<VectoException>(() => { var x = 500.SI().Watt + 300.SI().Newton; });
 
 			//subtract
 			var angVeloDiff = angularVelocity - angularVelocity2;
@@ -92,11 +73,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 
 
 			// ConvertTo only allows conversion if the units are correct.
-			AssertException<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo().Watt; });
+			AssertHelper.Exception<VectoException>(() => { var x = 40.SI<Newton>().ConvertTo().Watt; });
 			var res1 = 40.SI<Newton>().ConvertTo().Newton;
 
 			// Cast only allows the cast if the units are correct.
-			AssertException<VectoException>(() => { var x = 40.SI().Newton.Cast<Watt>(); });
+			AssertHelper.Exception<VectoException>(() => { var x = 40.SI().Newton.Cast<Watt>(); });
 			var res2 = 40.SI().Newton.Cast<Newton>();
 		}
 
@@ -156,21 +137,55 @@ namespace TUGraz.VectoCore.Tests.Utils
 		}
 
 		[TestMethod]
-		public void SI_Test_Addition_Subtraction()
+		public void SI_Comparison_Operators()
 		{
 			var v1 = 600.SI<NewtonMeter>();
 			var v2 = 455.SI<NewtonMeter>();
+			var v3 = 600.SI<NewtonMeter>();
+			var v4 = 100.SI<Watt>();
+			var d = 700;
 
 			Assert.IsTrue(v1 > v2);
-			Assert.IsTrue(v2 < v1);
-			Assert.IsTrue(v1 >= v2);
-			Assert.IsTrue(v2 <= v1);
-
 			Assert.IsFalse(v1 < v2);
+			AssertHelper.Exception<VectoException>(() => { var x = v1 < v4; },
+				"Operator '<' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] < 100.0000 [W]");
+			AssertHelper.Exception<VectoException>(() => { var x = v1 > v4; },
+				"Operator '>' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] > 100.0000 [W]");
+			AssertHelper.Exception<VectoException>(() => { var x = v1 <= v4; },
+				"Operator '<=' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] <= 100.0000 [W]");
+			AssertHelper.Exception<VectoException>(() => { var x = v1 >= v4; },
+				"Operator '>=' can only operate on SI Objects with the same unit. Got: 600.0000 [Nm] >= 100.0000 [W]");
+
+			SI si = null;
+			Assert.IsFalse(si > 3);
+			Assert.IsFalse(si < 3);
+			Assert.IsFalse(si >= 3);
+			Assert.IsFalse(si <= 3);
+
+			Assert.IsFalse(3 > si);
+			Assert.IsFalse(3 < si);
+			Assert.IsFalse(si >= 3);
+			Assert.IsFalse(si <= 3);
+
+
+			Assert.IsTrue(v2 < v1);
 			Assert.IsFalse(v2 > v1);
+
+			Assert.IsTrue(v1 >= v2);
 			Assert.IsFalse(v1 <= v2);
+
+			Assert.IsTrue(v2 <= v1);
 			Assert.IsFalse(v2 >= v1);
 
+			Assert.IsTrue(v1 <= v3);
+			Assert.IsTrue(v1 >= v3);
+
+			Assert.IsTrue(v1 < d);
+			Assert.IsFalse(v1 > d);
+			Assert.IsFalse(v1 >= d);
+			Assert.IsTrue(v1 <= d);
+
+
 			Assert.AreEqual(1, new SI().CompareTo(null));
 			Assert.AreEqual(1, new SI().CompareTo("not an SI"));
 			Assert.AreEqual(-1, new SI().Meter.CompareTo(new SI().Kilo.Meter.Per.Hour));
@@ -179,43 +194,237 @@ namespace TUGraz.VectoCore.Tests.Utils
 			Assert.AreEqual(0, 1.SI().CompareTo(1.SI()));
 			Assert.AreEqual(-1, 1.SI().CompareTo(2.SI()));
 			Assert.AreEqual(1, 2.SI().CompareTo(1.SI()));
+		}
 
 
-			NewtonMeter v3 = v1 + v2;
+		[TestMethod]
+		public void SI_Test_Addition_Subtraction()
+		{
+			AssertHelper.AreRelativeEqual(3.SI(), 1.SI() + 2.SI());
+			AssertHelper.AreRelativeEqual(-1.SI(), 1.SI() - 2.SI());
 
-			NewtonMeter v4 = v1 - v2;
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 1.SI<Scalar>() + 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 1 + 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 1.SI<Scalar>() + 2);
+			AssertHelper.AreRelativeEqual(-1.SI<Scalar>(), 1.SI<Scalar>() - 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(-1.SI<Scalar>(), 1 - 2.SI<Scalar>());
+			AssertHelper.AreRelativeEqual(-1.SI<Scalar>(), 1.SI<Scalar>() - 2);
 
-			var v5 = v1 * v2;
-			Assert.IsTrue(v5.HasEqualUnit(0.SI().Square.Newton.Meter));
-			Assert.AreEqual(v1.Value() * v2.Value(), v5.Value());
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 1.SI<NewtonMeter>() + 2.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(-1.SI<NewtonMeter>(), 1.SI<NewtonMeter>() - 2.SI<NewtonMeter>());
 
-			var v6 = v1 / v2;
-			Assert.IsTrue(v6.HasEqualUnit(0.SI()));
-			Assert.AreEqual(v1.Value() / v2.Value(), v6.Value());
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 1.SI().Newton.Meter + 2.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(-1.SI<NewtonMeter>(), 1.SI().Newton.Meter - 2.SI<NewtonMeter>());
 
-			var t = 10.SI<NewtonMeter>();
-			var angVelo = 5.SI<PerSecond>();
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 1.SI<NewtonMeter>() + 2.SI().Newton.Meter);
+			AssertHelper.AreRelativeEqual(-1.SI<NewtonMeter>(), 1.SI<NewtonMeter>() - 2.SI().Newton.Meter);
 
-			Watt w = t * angVelo;
-			Watt w1 = angVelo * t;
+			AssertHelper.Exception<VectoException>(() => { var x = 1.SI().Second - 1.SI<Meter>(); },
+				"Operator '-' can only operate on SI Objects with the same unit. Got: 1.0000 [s] - 1.0000 [m]");
+		}
 
-			NewtonMeter t1 = w / angVelo;
+		[TestMethod]
+		public void SI_SpecialUnits()
+		{
+			Scalar scalar = 3.SI<Scalar>();
+			AssertHelper.AreRelativeEqual(3.SI(), scalar);
+			double scalarDouble = scalar;
+			AssertHelper.AreRelativeEqual(3, scalarDouble);
+
+			MeterPerSecond meterPerSecond = 2.SI<MeterPerSecond>();
+			AssertHelper.AreRelativeEqual(2.SI().Meter.Per.Second, meterPerSecond);
+
+			Second second = 1.SI<Second>();
+			AssertHelper.AreRelativeEqual(1.SI().Second, second);
+
+			Watt watt = 2.SI<Watt>();
+			AssertHelper.AreRelativeEqual(2.SI().Watt, watt);
+
+			PerSecond perSecond = 1.SI<PerSecond>();
+			AssertHelper.AreRelativeEqual(1.SI().Per.Second, perSecond);
+
+			RoundsPerMinute rpm = 20.SI<RoundsPerMinute>();
+			AssertHelper.AreRelativeEqual(20.SI().Rounds.Per.Minute, rpm);
+			AssertHelper.AreRelativeEqual(20.RPMtoRad(), rpm);
+			AssertHelper.AreRelativeEqual(2.0943951023931953, rpm.Value());
+
+			Radian radian = 30.SI<Radian>();
+			AssertHelper.AreRelativeEqual(30.SI().Radian, radian);
+			AssertHelper.AreRelativeEqual(30, radian.Value());
+
+			Newton newton = 3.SI<Newton>();
+			AssertHelper.AreRelativeEqual(3.SI().Newton, newton);
+
+			NewtonMeter newtonMeter = 5.SI<NewtonMeter>();
+			AssertHelper.AreRelativeEqual(5.SI().Newton.Meter, newtonMeter);
+			AssertHelper.AreRelativeEqual(5.SI().Meter.Newton, newtonMeter);
+
+			MeterPerSquareSecond meterPerSquareSecond = 3.SI<MeterPerSquareSecond>();
+			AssertHelper.AreRelativeEqual(3.SI().Meter.Per.Square.Second, meterPerSquareSecond);
 
-			PerSecond angVelo1 = w / t;
-			Second sec = t / w;
+			Kilogram kilogram = 3.SI<Kilogram>();
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm, kilogram);
+			AssertHelper.AreRelativeEqual(3, kilogram.Value());
+
+			Ton ton = 5.SI<Ton>();
+			AssertHelper.AreRelativeEqual(5.SI().Ton, ton);
+			AssertHelper.AreRelativeEqual(5000.SI<Kilogram>(), ton);
+
+			SquareMeter squareMeter = 3.SI<SquareMeter>();
+			AssertHelper.AreRelativeEqual(3.SI().Square.Meter, squareMeter);
+
+			CubicMeter cubicMeter = 3.SI<CubicMeter>();
+			AssertHelper.AreRelativeEqual(3.SI().Cubic.Meter, cubicMeter);
+
+			KilogramSquareMeter kilogramSquareMeter = 3.SI<KilogramSquareMeter>();
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Square.Meter, kilogramSquareMeter);
+
+			KilogramPerWattSecond kilogramPerWattSecond = 3.SI<KilogramPerWattSecond>();
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Per.Watt.Second, kilogramPerWattSecond);
 		}
 
+		/// <summary>
+		/// VECTO-111
+		/// </summary>
 		[TestMethod]
-		public void SI_SpecialUnits()
+		public void SI_ReziprokDivision()
+		{
+			var test = 2.0.SI<Second>();
+
+			var actual = 1.0 / test;
+			var expected = 0.5.SI<PerSecond>();
+
+			AssertHelper.AreRelativeEqual(expected, actual);
+		}
+
+		[TestMethod]
+		public void SI_Multiplication_Division()
+		{
+			AssertHelper.AreRelativeEqual(12.SI(), 3.SI() * 4.SI());
+			AssertHelper.AreRelativeEqual(12.SI(), 3 * 4.SI());
+			AssertHelper.AreRelativeEqual(12.SI(), 3.SI() * 4);
+
+			AssertHelper.AreRelativeEqual(12.SI<NewtonMeter>(), 3.SI<Newton>() * 4.SI<Meter>());
+			AssertHelper.AreRelativeEqual(12.SI<NewtonMeter>(), 3 * 4.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(12.SI<NewtonMeter>(), 3.SI<NewtonMeter>() * 4);
+			AssertHelper.AreRelativeEqual(12.SI().Square.Newton.Meter, 3.SI<NewtonMeter>() * 4.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI(), 12.SI() / 4);
+			AssertHelper.AreRelativeEqual(3.SI(), 12.SI() / 4.SI());
+			AssertHelper.AreRelativeEqual(3.SI(), 12.SI<NewtonMeter>() / 4.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(3.SI<Scalar>(), 12.SI<NewtonMeter>() / 4.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI<NewtonMeter>(), 12.SI<NewtonMeter>() / 4);
+			AssertHelper.AreRelativeEqual(3.SI().Per.Newton.Meter, 12 / 4.SI<NewtonMeter>());
+
+
+			var newtonMeter = 10.SI<NewtonMeter>();
+			var perSecond = 5.SI<PerSecond>();
+			var watt = (10 * 5).SI<Watt>();
+			var second = (1.0 / 5.0).SI<Second>();
+
+			AssertHelper.AreRelativeEqual(watt, newtonMeter * perSecond);
+			AssertHelper.AreRelativeEqual(watt, perSecond * newtonMeter);
+
+			AssertHelper.AreRelativeEqual(newtonMeter, watt / perSecond);
+			AssertHelper.AreRelativeEqual(perSecond, watt / newtonMeter);
+
+			AssertHelper.AreRelativeEqual(second, newtonMeter / watt);
+		}
+
+		[TestMethod]
+		public void SI_MeterPerSecond_Div_Meter()
+		{
+			PerSecond actual = 6.SI<MeterPerSecond>() / 2.SI<Meter>();
+			AssertHelper.AreRelativeEqual(3.SI().Per.Second, actual);
+		}
+
+		[TestMethod]
+		public void SI_SimplifyUnits()
+		{
+			AssertHelper.AreRelativeEqual(3.SI(), 18.SI().Kilo.Gramm / 6.SI().Kilo.Gramm);
+			AssertHelper.AreRelativeEqual(3.SI(), 18.SI<NewtonMeter>() / 6.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(18.SI(), 3.SI().Kilo.Gramm * 6.SI().Per.Kilo.Gramm);
+			AssertHelper.AreRelativeEqual(18.SI<Meter>(), 3.SI().Kilo.Gramm.Meter * 6.SI().Per.Kilo.Gramm);
+
+
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Square.Meter.Per.Cubic.Second, 3.SI<Watt>());
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Gramm.Meter.Per.Square.Second, 3.SI<Newton>());
+			AssertHelper.AreRelativeEqual(3000.SI().Kilo.Gramm, 3.SI<Ton>());
+			AssertHelper.AreRelativeEqual(3.SI().Kilo.Kilo.Gramm.ConvertTo().Ton, 3.SI<Ton>().ConvertTo().Ton);
+
+			AssertHelper.AreRelativeEqual(3.SI<Meter>(), 3000.SI().Milli.Meter);
+
+			AssertHelper.AreRelativeEqual(36.SI().Square.Newton.Meter, 6.SI<NewtonMeter>() * 6.SI<NewtonMeter>());
+			AssertHelper.AreRelativeEqual(36.SI().Newton.Newton.Meter.Meter, 6.SI<NewtonMeter>() * 6.SI<NewtonMeter>());
+
+			AssertHelper.AreRelativeEqual(3.SI().Meter.Per.Second, 3.SI<Newton>().Second.Per.Kilo.Gramm);
+		}
+
+		[TestMethod]
+		public void SI_Math()
+		{
+			AssertHelper.AreRelativeEqual(-3, -3.SI().Value());
+			AssertHelper.AreRelativeEqual(3.SI(), (-3).SI().Abs());
+
+			AssertHelper.AreRelativeEqual(6.SI(), 36.SI().Sqrt());
+			AssertHelper.AreRelativeEqual(6.SI<NewtonMeter>(), (6.SI<NewtonMeter>() * 6.SI<NewtonMeter>()).Sqrt());
+			AssertHelper.AreRelativeEqual(6.SI().Second, 36.SI().Square.Second.Sqrt());
+
+			AssertHelper.Exception<VectoException>(() => 36.SI().Second.Sqrt(),
+				"The squareroot cannot be calculated because the Unit-Exponents are not even: [s]");
+		}
+
+		[TestMethod]
+		public void SI_Equality()
+		{
+			Assert.AreEqual(3.SI(), 3.SI());
+			Assert.AreEqual(3.SI<NewtonMeter>(), 3.SI<NewtonMeter>());
+
+
+			Assert.IsFalse(3.SI<NewtonMeter>().IsEqual(4.SI<NewtonMeter>()));
+			Assert.IsFalse(3.SI<NewtonMeter>().IsEqual(3.SI<Meter>()));
+
+			Assert.IsTrue(3.SI().IsEqual(4, 10));
+
+			var x = 4.SI();
+			var y = x;
+			var z = 4.SI();
+			Assert.IsTrue(x.Equals(y));
+
+			Assert.IsFalse(3.SI().Equals(null));
+			Assert.IsFalse(3.SI().IsEqual(4.SI()));
+			Assert.IsTrue(z.Equals(x));
+			Assert.IsFalse(3.SI().Equals(3.SI<Newton>()));
+
+			var newton1 = 3.SI<Newton>();
+			var newton2 = 3.SI<Newton>();
+			Assert.IsTrue(newton1.Equals(newton2));
+
+
+			Assert.IsTrue(3.SI().IsEqual(3.SI()));
+			Assert.IsTrue(3.SI().IsEqual(3));
+
+			Assert.IsFalse(3.SI().IsEqual(2.9.SI()));
+			Assert.IsFalse(3.SI().IsEqual(2.9));
+
+			// just calling to test wether the functions are not throwing an exception.
+			3.SI().GetHashCode();
+			3.0.SI().GetHashCode();
+			4.SI<NewtonMeter>().GetHashCode();
+		}
+
+		[TestMethod]
+		public void SI_Output()
 		{
-			2.SI<MeterPerSecond>();
-			1.SI<Second>();
-			2.SI<Watt>();
-			1.SI<PerSecond>();
-			2.SI<RoundsPerMinute>();
-			3.SI<Newton>();
-			4.SI<Radian>();
-			5.SI<NewtonMeter>();
+			Assert.AreEqual("3.0000", 3.SI().ToOutputFormat());
+			Assert.AreEqual("3.0000 [-]", 3.SI().ToOutputFormat(showUnit: true));
+			Assert.AreEqual("3.5000", 3.5.SI().ToOutputFormat());
+			Assert.AreEqual("3.5000", 3.5.SI<Newton>().ToOutputFormat());
+			Assert.AreEqual("3.50 [N]", 3.5.SI<Newton>().ToOutputFormat(2, showUnit: true));
+			Assert.AreEqual("18.00 [m/s]", 5.SI<MeterPerSecond>().ToOutputFormat(2, 3.6, true));
+			Assert.AreEqual("18.0000", 5.SI<MeterPerSecond>().ToOutputFormat(outputFactor: 3.6));
 		}
 	}
 }
\ No newline at end of file