From bd6599df615e20ba283b89dc3f9c6bc500a4da1b Mon Sep 17 00:00:00 2001
From: Michael Krisper <michael.krisper@tugraz.at>
Date: Mon, 2 Oct 2017 15:53:07 +0200
Subject: [PATCH] removed GtoKG and _isMass

---
 VectoCommon/VectoCommon/Utils/SI.cs           | 3329 ++++++++---------
 VectoCommon/VectoCommon/Utils/SIUtils.cs      |  859 ++---
 .../OutputData/IModalDataContainer.cs         |    1 -
 .../OutputData/SummaryDataContainer.cs        |    7 +-
 4 files changed, 2061 insertions(+), 2135 deletions(-)

diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs
index fdcc631b9a..6fc55efe82 100644
--- a/VectoCommon/VectoCommon/Utils/SI.cs
+++ b/VectoCommon/VectoCommon/Utils/SI.cs
@@ -42,1686 +42,1651 @@ using TUGraz.VectoCommon.Exceptions;
 
 namespace TUGraz.VectoCommon.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>
-	{
-		private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Scalar(double val) : base(val, Units) { }
-
-		public static implicit operator double(Scalar self)
-		{
-			return self.Val;
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator +(Scalar si1, Scalar si2)
-		{
-			return Create(si1.Val + si2.Val);
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator +(Scalar si1, double si2)
-		{
-			return Create(si1.Val + si2);
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator +(double si1, Scalar si2)
-		{
-			return Create(si1 + si2.Val);
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator -(Scalar si1, Scalar si2)
-		{
-			return Create(si1.Val - si2.Val);
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator -(Scalar si1, double si2)
-		{
-			return Create(si1.Val - si2);
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator -(double si1, Scalar si2)
-		{
-			return Create(si1 - si2.Val);
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Newton [N].
-	/// </summary>
-	public class Newton : SIBase<Newton>
-	{
-		private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Newton(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static NewtonMeter operator *(Newton newton, Meter meter)
-		{
-			return SIBase<NewtonMeter>.Create(newton.Val * meter.Value());
-		}
-
-		[DebuggerHidden]
-		public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond)
-		{
-			return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value());
-		}
-
-		[DebuggerHidden]
-		public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton)
-		{
-			return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Radian [] (rad).
-	/// </summary>
-	public class Radian : SIBase<Radian>
-	{
-		private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Radian(double val) : base(val, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for PerSquareSecond [1/s^2].
-	/// </summary>
-	public class PerSquareSecond : SIBase<PerSquareSecond>
-	{
-		private static readonly int[] Units = { 0, 0, -2, 0, 0, 0, 0 };
-		[DebuggerHidden]
-		private PerSquareSecond(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second)
-		{
-			return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Meter per square second [m/s^2].
-	/// </summary>
-	public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond>
-	{
-		private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private MeterPerSquareSecond(double val) : base(val, Units) { }
-
-		/// <summary>
-		/// Implements the operator *.
-		/// </summary>
-		[DebuggerHidden]
-		public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second)
-		{
-			return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Second [s].
-	/// </summary>
-	public class Second : SIBase<Second>
-	{
-		private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Second(double val) : base(val, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for Meter [m].
-	/// </summary>
-	public class Meter : SIBase<Meter>
-	{
-		private static readonly int[] Units = { 0, 1, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Meter(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static MeterPerSecond operator /(Meter meter, Second second)
-		{
-			return SIBase<MeterPerSecond>.Create(meter.Val / second.Value());
-		}
-
-		[DebuggerHidden]
-		public static MeterPerSecond operator *(Meter meter, PerSecond perSecond)
-		{
-			return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator /.
-		/// </summary>
-		[DebuggerHidden]
-		public static Second operator /(Meter second, MeterPerSecond meterPerSecond)
-		{
-			return SIBase<Second>.Create(second.Val / meterPerSecond.Value());
-		}
-	}
-
-	/// <summary>
-	///  SI Class for KilogramPerMeter [kg/m].
-	/// </summary>
-	public class KilogramPerMeter : SIBase<KilogramPerMeter>
-	{
-		private static readonly int[] Units = { 1, -1, 0, 0, 0, 0, 0 };
-		[DebuggerHidden]
-		private KilogramPerMeter(double val) : base(val, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for Liter per Second [l/s].
-	/// </summary>
-	public class LiterPerSecond : SIBase<LiterPerSecond>
-	{
-		private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 };
-
-		private LiterPerSecond(double val) : base(val * 0.001, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for Kilogram [kg].
-	/// </summary>
-	public class Kilogram : SIBase<Kilogram>
-	{
-		private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Kilogram(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static KilogramPerSecond operator /(Kilogram kg, Second second)
-		{
-			return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value());
-		}
-
-		[DebuggerHidden]
-		public static SI operator /(Kilogram kg, Joule j)
-		{
-			return (kg as SI) / j;
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator /(Kilogram kg, Kilogram kg2)
-		{
-			return SIBase<Scalar>.Create(kg.Val / kg2.Val);
-		}
-
-		[DebuggerHidden]
-		public static KilogramPerMeter operator /(Kilogram kg, Meter m)
-		{
-			return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value());
-		}
-
-		[DebuggerHidden]
-		public static Newton operator *(Kilogram kg, MeterPerSquareSecond m)
-		{
-			return SIBase<Newton>.Create(kg.Val * m.Value());
-		}
-
-		[DebuggerHidden]
-		public static Kilogram operator *(Kilogram kg, double d)
-		{
-			return new Kilogram(kg.Val * d);
-		}
-
-		[DebuggerHidden]
-		public static Kilogram operator *(double d, Kilogram kg)
-		{
-			return new Kilogram(d * kg.Val);
-		}
-
-		public static Liter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter)
-		{
-			return SIBase<Liter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value() * 1000);
-		}
-	}
-
-	public class Liter : SIBase<Liter>
-	{
-		private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Liter(double val) : base(val * 0.001, Units) { }
-
-		public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter)
-		{
-			return SIBase<Kilogram>.Create(liter.Val / 1000 * kilogramPerCubicMeter.Value());
-		}
-	}
-
-	/// <summary>
-	/// 
-	/// </summary>
-	public class NormLiter : SIBase<NormLiter>
-	{
-		private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private NormLiter(double val) : base(val * 0.001, Units) { }
-
-		public static NormLiterPerSecond operator /(NormLiter nl, Second s)
-		{
-			return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value());
-		}
-	}
-
-	/// <summary>
-	/// 
-	/// </summary>
-	public class NormLiterPerSecond : SIBase<NormLiterPerSecond>
-	{
-		private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private NormLiterPerSecond(double val) : base(val * 0.001, Units) { }
-
-		public static NormLiter operator *(NormLiterPerSecond nips, Second s)
-		{
-			return SIBase<NormLiter>.Create(nips.Val * s.Value());
-		}
-
-		public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val)
-		{
-			return Create(nps.Val * val);
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Kilogram per Second [kg].
-	/// </summary>
-	public class KilogramPerSecond : SIBase<KilogramPerSecond>
-	{
-		private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private KilogramPerSecond(double value) : base(value, Units) { }
-
-		[DebuggerHidden]
-		public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second)
-		{
-			return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Square meter [m^2].
-	/// </summary>
-	public class SquareMeter : SIBase<SquareMeter>
-	{
-		private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private SquareMeter(double value) : base(value, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for cubic meter [m^3].
-	/// </summary>
-	public class CubicMeter : SIBase<CubicMeter>
-	{
-		private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private CubicMeter(double value)
-			: base(value, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for Kilogram Square Meter [kgm^2].
-	/// </summary>
-	public class KilogramSquareMeter : SIBase<KilogramSquareMeter>
-	{
-		private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private KilogramSquareMeter(double value) : base(value, Units) { }
-
-		[DebuggerHidden]
-		public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond)
-		{
-			return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Kilogram Square Meter [kgm^2].
-	/// </summary>
-	public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter>
-	{
-		private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private KilogramPerCubicMeter(double value) : base(value, Units) { }
-
-		[DebuggerHidden]
-		public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter)
-		{
-			return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value());
-		}
-
-		public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, Liter liter)
-		{
-			return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * liter.Value() / 1000);
-		}
-
-		//public static CubicMeter operator /(Kilogram kg, KilogramPerCubicMeter kgm3)
-		//{
-		//	return SIBase<CubicMeter>.Create(kg.Value() / kgm3.Val);
-		//}
-	}
-
-	/// <summary>
-	/// SI Class for Kilogramm per watt second [kg/Ws].
-	/// W = kgm^2/s^3
-	/// </summary>
-	public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond>
-	{
-		private static readonly int[] Units = { 0, -2, 2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private KilogramPerWattSecond(double val) : base(val, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for watt second [Ws].
-	/// W = kgm^2/s^3
-	/// </summary>
-	public class WattSecond : SIBase<WattSecond>
-	{
-		private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private WattSecond(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static Watt operator /(WattSecond wattSecond, Second second)
-		{
-			return SIBase<Watt>.Create(wattSecond.Val / second.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Watt [W].
-	/// </summary>
-	public class Watt : SIBase<Watt>
-	{
-		private static readonly int[] Units = { 1, 2, -3, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Watt(double val) : base(val, Units) { }
-
-		/// <summary>
-		/// Implements the operator /.
-		/// </summary>
-		/// <param name="watt">The watt.</param>
-		/// <param name="newtonMeter">The newton meter.</param>
-		/// <returns>
-		/// The result of the operator.
-		/// </returns>
-		[DebuggerHidden]
-		public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter)
-		{
-			return SIBase<PerSecond>.Create(watt.Val / newtonMeter.Value());
-		}
-
-		[DebuggerHidden]
-		public static Newton operator /(Watt watt, MeterPerSecond meterPerSecond)
-		{
-			return SIBase<Newton>.Create(watt.Val / meterPerSecond.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator /.
-		/// </summary>
-		/// <param name="watt">The watt.</param>
-		/// <param name="perSecond">The per second.</param>
-		/// <returns>
-		/// The result of the operator.
-		/// </returns>
-		[DebuggerHidden]
-		public static NewtonMeter operator /(Watt watt, PerSecond perSecond)
-		{
-			return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value());
-		}
-
-		[DebuggerHidden]
-		public static WattSecond operator *(Watt watt, Second second)
-		{
-			return SIBase<WattSecond>.Create(watt.Val * second.Value());
-		}
-
-		[DebuggerHidden]
-		public static Watt operator *(Watt watt, double val)
-		{
-			return Create(watt.Val * val);
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Joule [J].
-	/// J = Ws = kgm^2/s^2
-	/// </summary>
-	public class Joule : SIBase<Joule>
-	{
-		private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private Joule(double val) : base(val, Units) { }
-
-		public static implicit operator Joule(WattSecond self)
-		{
-			return Create(self.Value());
-		}
-
-		public static Joule operator +(Joule joule, WattSecond ws)
-		{
-			return Create(joule.Val + ws.Value());
-		}
-
-		public static Watt operator /(Joule joule, Second s)
-		{
-			return SIBase<Watt>.Create(joule.Val / s.Value());
-		}
-
-		public static JoulePerMeter operator /(Joule joule, Meter meter)
-		{
-			return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Watt [W].
-	/// J = Ws
-	/// W = kgm^2/s^3
-	/// </summary>
-	public class JoulePerKilogramm : SIBase<JoulePerKilogramm>
-	{
-		private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 };
-
-		private JoulePerKilogramm(double val) : base(val, Units) { }
-
-		public static Joule operator *(Kilogram kg, JoulePerKilogramm jpg)
-		{
-			return SIBase<Joule>.Create(kg.Value() * jpg.Val);
-		}
-	}
-
-	/// <summary>
-	///  SI Class for Joule per Meter [J/m].
-	///  J = Ws
-	///  W = kgm^2/s^3
-	/// </summary>
-	public class JoulePerMeter : SIBase<JoulePerMeter>
-	{
-		private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private JoulePerMeter(double val) : base(val, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for one per second [1/s].
-	/// </summary>
-	[DebuggerDisplay("rad/s: {Val} | rpm: {AsRPM}")]
-	public class PerSecond : SIBase<PerSecond>
-	{
-		private static readonly int[] Units = { 0, 0, -1, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private PerSecond(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static PerSquareSecond operator /(PerSecond perSecond, Second second)
-		{
-			return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value());
-		}
-
-		public double AsRPM
-		{
-			get { return Val * 60 / (2 * Math.PI); }
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Meter per second [m/s].
-	/// </summary>
-	[DebuggerDisplay("{Val} | {AsKmph}")]
-	public class MeterPerSecond : SIBase<MeterPerSecond>
-	{
-		private static readonly int[] Units = { 0, 1, -1, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private MeterPerSecond(double val) : base(val, Units) { }
-
-		public double AsKmph
-		{
-			get { return Val * 3.6; }
-		}
-
-		/// <summary>
-		/// Implements the operator /.
-		/// </summary>
-		[DebuggerHidden]
-		public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter)
-		{
-			return SIBase<PerSecond>.Create(meterPerSecond.Val / meter.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator /.
-		/// </summary>
-		[DebuggerHidden]
-		public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond)
-		{
-			return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator /.
-		/// </summary>
-		[DebuggerHidden]
-		public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second)
-		{
-			return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator *.
-		/// </summary>
-		[DebuggerHidden]
-		public static Meter operator *(MeterPerSecond meterPerSecond, Second second)
-		{
-			return SIBase<Meter>.Create(meterPerSecond.Val * second.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator *.
-		/// </summary>
-		[DebuggerHidden]
-		public static MeterPerSquareSecond operator *(MeterPerSecond meterPerSecond, PerSecond perSecond)
-		{
-			return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val * perSecond.Value());
-		}
-
-		/// <summary>
-		/// Implements the operator *.
-		/// </summary>
-		[DebuggerHidden]
-		public static Meter operator *(Second second, MeterPerSecond meterPerSecond)
-		{
-			return SIBase<Meter>.Create(second.Value() * meterPerSecond.Val);
-		}
-	}
-
-	/// <summary>
-	/// SI Class for NewtonMeter [Nm].
-	/// N = kgm/s^2
-	/// </summary>
-	public class NewtonMeter : SIBase<NewtonMeter>
-	{
-		private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 };
-
-		[DebuggerHidden]
-		private NewtonMeter(double val) : base(val, Units) { }
-
-		[DebuggerHidden]
-		public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond)
-		{
-			return SIBase<Watt>.Create(newtonMeter.Val * perSecond.Value());
-		}
-
-		[DebuggerHidden]
-		public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter)
-		{
-			return SIBase<Watt>.Create(perSecond.Value() * newtonMeter.Val);
-		}
-
-		[DebuggerHidden]
-		public static Second operator /(NewtonMeter newtonMeter, Watt watt)
-		{
-			return SIBase<Second>.Create(newtonMeter.Val / watt.Value());
-		}
-
-		[DebuggerHidden]
-		public static PerSquareSecond operator /(NewtonMeter newtonMeter, KilogramSquareMeter kgKilogramSquareMeter)
-		{
-			return SIBase<PerSquareSecond>.Create(newtonMeter.Val / kgKilogramSquareMeter.Value());
-		}
-
-		[DebuggerHidden]
-		public static PerSecond operator /(NewtonMeter newtonMeter, NewtonMeterSecond newtonMeterSecond)
-		{
-			return SIBase<PerSecond>.Create(newtonMeter.Val / newtonMeterSecond.Value());
-		}
-
-		[DebuggerHidden]
-		public static Newton operator /(NewtonMeter newtonMeter, Meter meter)
-		{
-			return SIBase<Newton>.Create(newtonMeter.Val / meter.Value());
-		}
-
-		[DebuggerHidden]
-		public static NewtonMeterSecond operator /(NewtonMeter newtonMeter, PerSecond perSecond)
-		{
-			return SIBase<NewtonMeterSecond>.Create(newtonMeter.Val / perSecond.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for NewtonMeterSecond [Nms].
-	/// N = kgm/s^2
-	/// </summary>
-	public class NewtonMeterSecond : SIBase<NewtonMeterSecond>
-	{
-		private static readonly int[] Units = { 1, 2, -1, 0, 0, 0, 0 };
-		private NewtonMeterSecond(double val) : base(val, Units) { }
-	}
-
-	/// <summary>
-	/// SI Class for Amperer [A].
-	/// </summary>
-	public class Ampere : SIBase<Ampere>
-	{
-		private static readonly int[] Units = { 0, 0, 0, 1, 0, 0, 0 };
-		private Ampere(double val) : base(val, Units) { }
-
-		public static Watt operator *(Ampere ampere, Volt volt)
-		{
-			return SIBase<Watt>.Create(volt.Value() * ampere.Val);
-		}
-
-		public static Ampere operator *(Ampere ampere, double val)
-		{
-			return Create(ampere.Val * val);
-		}
-
-		public static Volt operator /(Watt watt, Ampere ampere)
-		{
-			return SIBase<Volt>.Create(watt.Value() / ampere.Value());
-		}
-	}
-
-	/// <summary>
-	/// SI Class for Amperer [V].
-	/// V = kgm^2/As^2
-	/// </summary>
-	public class Volt : SIBase<Volt>
-	{
-		private static readonly int[] Units = { 1, 2, -2, -1, 0, 0, 0 };
-		private Volt(double val) : base(val, Units) { }
-
-		public static Watt operator *(Volt volt, Ampere ampere)
-		{
-			return SIBase<Watt>.Create(volt.Val * ampere.Value());
-		}
-
-		public static Ampere operator /(Watt watt, Volt volt)
-		{
-			return SIBase<Ampere>.Create(watt.Value() / volt.Value());
-		}
-	}
-
-	/// <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>
-	{
-		private static readonly T ZeroPrototype;
-
-		static SIBase()
-		{
-			const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
-			var constructorInfo = typeof(T).GetConstructor(bindingFlags, null, new[] { typeof(double) }, null);
-			var parameter = Expression.Parameter(typeof(double));
-			var lambda = Expression.Lambda<Func<double, T>>(Expression.New(constructorInfo, parameter), parameter);
-			Constructor = lambda.Compile();
-			ZeroPrototype = Constructor(0);
-		}
-
-		/// <summary>
-		/// The constructor for the generic type T.
-		/// </summary>
-		private static readonly Func<double, T> Constructor;
-
-		/// <summary>
-		/// Creates the specified special SI object.
-		/// </summary>
-		/// <param name="val">The value of the SI object.</param>
-		[DebuggerStepThrough]
-		public static T Create(double val)
-		{
-			if (val == 0)
-			{
-				return ZeroPrototype;
-			}
-
-			return Constructor(val);
-		}
-
-		[DebuggerStepThrough]
-		protected SIBase(double value, int[] units) : base(value, units, 0) { }
-
-		[DebuggerStepThrough]
-		public new T Abs()
-		{
-			return Create(Math.Abs(Val));
-		}
-
-		#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 Create(si1.Val + si2.Val);
-		}
-
-		/// <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 (si1 + (si2 as SI)).Cast<T>();
-		}
-
-		/// <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 Create(-si1.Val);
-		}
-
-		/// <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 Create(si1.Val - si2.Val);
-		}
-
-		/// <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 (si1 - (si2 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 Create(d * si.Val);
-		}
-
-		/// <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 Create(si.Val * 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 Create(si.Val / d);
-		}
-
-		[DebuggerHidden]
-		public static Scalar operator /(SIBase<T> si, SIBase<T> si2)
-		{
-			return SIBase<Scalar>.Create(si.Val / si2.Val);
-		}
-
-		#endregion
-	}
-
-	/// <summary>
-	/// Class for representing generic SI Units.
-	/// </summary>
-	/// <remarks>
-	/// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute
-	/// </remarks>
-	[DebuggerDisplay("{Val}")]
-	public class SI : IComparable
-	{
-		/// <summary>
-		/// The basic scalar value of the SI.
-		/// </summary>
-		protected readonly double Val;
-
-		/// <summary>
-		/// The array of the SI units.
-		/// </summary>
-		private readonly int[] _units;
-
-		// TODO mk-2017-09-14: can the mass be solved differently?
-		private UnitInstance.IsMass _isMass;
-
-		/// <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="units">The units.</param>
-		/// <param name="isMassParam"></param>
-		protected SI(double val, int[] units, UnitInstance.IsMass isMassParam)
-		{
-			Val = val;
-			_isMass = isMassParam;
-			_units = units;
-
-			if (double.IsNaN(Val))
-			{
-				throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
-			}
-
-			if (double.IsInfinity(Val))
-			{
-				throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
-			}
-		}
-
-		public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits(), si.GetGrammMode())
-		{
-
-		}
-
-		/// <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>
-		[DebuggerHidden]
-		private SI(double val, SI unit) : this(val, unit._units, unit._isMass) { }
-
-		[DebuggerHidden]
-		private SI(SI si, double factor, int[] unitsParam, UnitInstance.IsMass isMassParam)
-		{
-			Val = si.Val / factor;
-			_isMass = isMassParam;
-			_units = unitsParam;
-
-			if (double.IsNaN(Val))
-			{
-				throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
-			}
-
-			if (double.IsInfinity(Val))
-			{
-				throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
-			}
-		}
-
-		public SI ConvertTo(UnitInstance si)
-		{
-
-			if (!SIUtils.CompareUnits(_units, si.GetSIUnits()))
-			{
-				throw new VectoException(
-					"Unit missing. Conversion not possible. [{0}] does not contain a [{1}].",
-					GetUnitString(_units), si.GetSIUnits());
-			}
-
-			var factorValue = si.Factor;
-
-
-			if ((_isMass & UnitInstance.IsMass.IsGramm) == UnitInstance.IsMass.IsGramm)
-			{
-				factorValue *= 1000;
-			}
-
-			if ((si.GetGrammMode() & UnitInstance.IsMass.IsGramm) == UnitInstance.IsMass.IsGramm)
-			{
-				factorValue /= 1000;
-				_isMass |= UnitInstance.IsMass.IsGramm;
-			}
-
-
-			return new SI(this, unitsParam: si.GetSIUnits(), factor: factorValue,
-				isMassParam: _isMass);
-		}
-
-		/// <summary>
-		/// Casts the SI Unit to the concrete unit type (if the units allow such an cast).
-		/// </summary>
-		/// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam>
-		[DebuggerHidden]
-		public T Cast<T>() where T : SIBase<T>
-		{
-			var si = ToBasicUnits();
-			var t = SIBase<T>.Create(si.Val);
-			if (!si.HasEqualUnit(t))
-			{
-				throw new VectoException("SI Unit Conversion failed: From {0} to {1}", si, t);
-			}
-			return t;
-		}
-
-		/// <summary>
-		/// Converts the derived SI units to the basic units and returns this as a new SI object.
-		/// </summary>
-		public SI ToBasicUnits()
-		{
-			return new SI(Val, _units, _isMass);
-		}
-
-
-		/// <summary>
-		/// Gets the underlying scalar double value.
-		/// </summary>
-		[DebuggerHidden]
-		public double Value()
-		{
-			return Val;
-		}
-
-		/// <summary>
-		/// Clones this instance.
-		/// </summary>
-		public SI Clone()
-		{
-			return new SI(Val, _units, _isMass);
-		}
-
-		/// <summary>
-		/// Returns the absolute value.
-		/// </summary>
-		public SI Abs()
-		{
-			return new SI(Math.Abs(Val), this);
-		}
-
-		/// <summary>
-		/// Returns the numerical sign of the SI.
-		/// </summary>
-		/// <returns>-1 if si &lt; 0. 0 if si==0, 1 if si &gt; 0.</returns>
-		[DebuggerHidden]
-		public int Sign()
-		{
-			return Math.Sign(Val);
-		}
-
-		// TODO mk 2017-09-14: can this method be removed?
-		private static double GtoKg(SI si)
-		{
-			var result = 1.0;
-
-			if ((si._isMass & UnitInstance.IsMass.IsGramm) == UnitInstance.IsMass.IsGramm)
-			{
-				result = 0.001;
-			}
-
-			return result;
-		}
-
-		#region Operators
-
-		[DebuggerHidden]
-		public static SI operator +(SI si1, SI si2)
-		{
-			if (!si1.HasEqualUnit(si2))
-			{
-				throw new VectoException("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2);
-			}
-
-
-			return new SI(si1.Val * GtoKg(si1) + si2.Val * GtoKg(si2), si1);
-		}
-
-		[DebuggerHidden]
-		public static SI operator -(SI si1, SI si2)
-		{
-			if (!si1.HasEqualUnit(si2))
-			{
-				throw new VectoException("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2);
-			}
-			return new SI(si1.Val * GtoKg(si1) - si2.Val * GtoKg(si2), si1);
-		}
-
-		[DebuggerHidden]
-		public static SI operator -(SI si1)
-		{
-			return new SI(-si1.Val * GtoKg(si1), si1);
-		}
-
-		public static SI operator *(SI si1, SI si2)
-		{
-			var unitArray = SIUtils.CombineUnits(si1._units, si2._units);
-			return new SI(si1.Val * GtoKg(si1) * (si2.Val * GtoKg(si2)), unitArray, UnitInstance.IsMass.IsKiloGramm);
-		}
-
-		[DebuggerHidden]
-		public static SI operator *(SI si1, double d)
-		{
-			return new SI(si1.Val * GtoKg(si1) * d, si1);
-		}
-
-		[DebuggerHidden]
-		public static SI operator *(double d, SI si1)
-		{
-			return new SI(d * si1.Val * GtoKg(si1), si1);
-		}
-
-		public static SI operator /(SI si1, SI si2)
-		{
-			double result;
-			try
-			{
-				result = si1.Val * GtoKg(si1) / (si2.Val * GtoKg(si2));
-
-				// bad cases: Infinity = x / 0.0  (for x != 0), NaN = 0.0 / 0.0
-				if (double.IsInfinity(result) || double.IsNaN(result))
-				{
-					throw new DivideByZeroException();
-				}
-			}
-			catch (DivideByZeroException ex)
-			{
-				throw new VectoException(
-					string.Format("Can not compute division by zero ([{0}] / 0[{1}])", si1.GetUnitString(), si2.GetUnitString()), ex);
-			}
-
-			var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1));
-
-			return new SI(result, unitArray, UnitInstance.IsMass.IsKiloGramm);
-		}
-
-		[DebuggerHidden]
-		public static SI operator /(SI si1, double d)
-		{
-			if (d.IsEqual(0))
-			{
-				throw new VectoException(string.Format("Can not compute division by zero ([{0}] / 0)", si1.GetUnitString()), new DivideByZeroException());
-			}
-
-			return new SI(si1.Val * GtoKg(si1) / d, si1);
-		}
-
-		[DebuggerHidden]
-		public static SI operator /(double d, SI si1)
-		{
-			if (si1.IsEqual(0))
-			{
-				throw new VectoException(string.Format("Can not compute division by zero (x / 0[{0}])", si1.GetUnitString()),
-					new DivideByZeroException());
-			}
-
-			return new SI(d / (si1.Val * GtoKg(si1)), si1._units.Select(u => -u).ToArray(), si1._isMass);
-		}
-
-		[DebuggerHidden]
-		public static bool operator <(SI si1, SI si2)
-		{
-			if (!si1.HasEqualUnit(si2))
-			{
-				throw new VectoException("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2);
-			}
-			return si1.Val * GtoKg(si1) < si2.Val * GtoKg(si2);
-		}
-
-		[DebuggerHidden]
-		public static bool operator <(SI si1, double d)
-		{
-			return si1 != null && si1.Val * GtoKg(si1) < d;
-		}
-
-		[DebuggerHidden]
-		public static bool operator >(SI si1, SI si2)
-		{
-			if (!si1.HasEqualUnit(si2))
-			{
-				throw new VectoException("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2);
-			}
-			return si1.Val * GtoKg(si1) > si2.Val * GtoKg(si2);
-		}
-
-		[DebuggerHidden]
-		public static bool operator >(SI si1, double d)
-		{
-			return si1 != null && si1.Val * GtoKg(si1) > d;
-		}
-
-		[DebuggerHidden]
-		public static bool operator >(double d, SI si1)
-		{
-			return si1 != null && d > si1.Val * GtoKg(si1);
-		}
-
-		[DebuggerHidden]
-		public static bool operator <(double d, SI si1)
-		{
-			return si1 != null && d < si1.Val * GtoKg(si1);
-		}
-
-		[DebuggerHidden]
-		public static bool operator <=(SI si1, SI si2)
-		{
-			if (!si1.HasEqualUnit(si2))
-			{
-				throw new VectoException("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1,
-					si2);
-			}
-			return si1.Val * GtoKg(si1) <= si2.Val * GtoKg(si2);
-		}
-
-		[DebuggerHidden]
-		public static bool operator <=(SI si1, double d)
-		{
-			return si1 != null && si1.Val * GtoKg(si1) <= d;
-		}
-
-		[DebuggerHidden]
-		public static bool operator >=(SI si1, SI si2)
-		{
-			if (!si1.HasEqualUnit(si2))
-			{
-				throw new VectoException("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1,
-					si2);
-			}
-			return si1.Val * GtoKg(si1) >= si2.Val * GtoKg(si2);
-		}
-
-		[DebuggerHidden]
-		public static bool operator >=(SI si1, double d)
-		{
-			return si1 != null && si1.Val * GtoKg(si1) >= d;
-		}
-
-		[DebuggerHidden]
-		public static bool operator >=(double d, SI si1)
-		{
-			return si1 != null && d >= si1.Val * GtoKg(si1);
-		}
-
-		[DebuggerHidden]
-		public static bool operator <=(double d, SI si1)
-		{
-			return si1 != null && d <= si1.Val * GtoKg(si1);
-		}
-
-		/// <summary>
-		/// Determines whether the SI is between lower and uppper bound.
-		/// </summary>
-		/// <param name="lower">The lower bound.</param>
-		/// <param name="upper">The upper bound.</param>
-		/// <returns></returns>
-		public bool IsBetween(SI lower, SI upper)
-		{
-			return lower <= Val * GtoKg(this) && Val * GtoKg(this) <= upper;
-		}
-
-		/// <summary>
-		/// Determines whether the SI is between lower and upper bound.
-		/// </summary>
-		/// <param name="lower">The lower bound.</param>
-		/// <param name="upper">The upper bound.</param>
-		/// <returns></returns>
-		public bool IsBetween(double lower, double upper)
-		{
-			return lower <= Val * GtoKg(this) && Val * GtoKg(this) <= upper;
-		}
-
-		#endregion
-
-		#region ToString
-
-		/// <summary>
-		///     Returns the Unit Part of the SI Unit Expression.
-		/// </summary>
-		public string GetUnitString(int[] units = null)
-		{
-			if (units == null)
-			{
-				units = _units;
-			}
-			return Unit.GetUnitString(units, (_isMass & UnitInstance.IsMass.IsGramm) == UnitInstance.IsMass.IsGramm);
-		}
-
-		public override string ToString()
-		{
-			return ToString(null);
-		}
-
-		private string ToString(string format)
-		{
-			if (string.IsNullOrEmpty(format))
-			{
-				format = "F4";
-			}
-
-			return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, GetUnitString());
-		}
-
-		#endregion
-
-		#region Equality members
-
-		/// <summary>
-		/// Compares the Unit-Parts of two SI Units.
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <returns></returns>
-		[DebuggerHidden]
-		public bool HasEqualUnit(SI si)
-		{
-			return SIUtils.CompareUnits(_units, si._units);
-		}
-
-		/// <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))
-			{
-				return false;
-			}
-			if (ReferenceEquals(this, obj))
-			{
-				return true;
-			}
-			var other = obj as SI;
-
-			var valFac = Val * GtoKg(this);
-			return other != null && valFac.Equals(other.Val * GtoKg(other)) && 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, SI tolerance = null)
-		{
-			var valFac = Val * GtoKg(this);
-			return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) && valFac.IsEqual(si.Val * GtoKg(si), tolerance == null ? DoubleExtensionMethods.Tolerance : (tolerance.Value() * GtoKg(tolerance)));
-		}
-
-		/// <summary>
-		/// Determines whether the specified value is equal.
-		/// </summary>
-		/// <param name="val">The value.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerHidden]
-		public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
-		{
-			var valFac = Val * GtoKg(this);
-			return valFac.IsEqual(val, tolerance);
-		}
-
-		/// <summary>
-		/// Determines whether the specified si is smaller.
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		public bool IsSmaller(SI si, SI tolerance = null)
-		{
-			if (!HasEqualUnit(si))
-			{
-				throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
-			}
-			if (tolerance != null && !HasEqualUnit(tolerance))
-			{
-				throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
-			}
-
-			var valFac = Val * GtoKg(this);
-			return valFac.IsSmaller(si.Val * GtoKg(si), tolerance == null ? DoubleExtensionMethods.Tolerance : (tolerance.Value() * GtoKg(tolerance)));
-		}
-
-		/// <summary>
-		/// Determines whether the specified si is smaller.
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		public bool IsSmaller(SI si, double tolerance)
-		{
-			if (!HasEqualUnit(si))
-			{
-				throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
-			}
-
-			var valFac = Val * GtoKg(this);
-			return valFac.IsSmaller(si.Val * GtoKg(si), tolerance);
-		}
-
-		/// <summary>
-		/// Determines whether [is smaller or equal] [the specified si].
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		public bool IsSmallerOrEqual(SI si, SI tolerance = null)
-		{
-			if (!HasEqualUnit(si))
-			{
-				throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
-			}
-			if (tolerance != null && !HasEqualUnit(tolerance))
-			{
-				throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
-			}
-
-			var valFac = Val * GtoKg(this);
-
-			return valFac.IsSmallerOrEqual(si.Val * GtoKg(si), tolerance == null ? DoubleExtensionMethods.Tolerance : (tolerance.Value() * GtoKg(tolerance)));
-		}
-
-		/// <summary>
-		/// Determines whether the specified si is greater.
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		public bool IsGreater(SI si, SI tolerance = null)
-		{
-			if (!HasEqualUnit(si))
-			{
-				throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
-			}
-			if (tolerance != null && !HasEqualUnit(tolerance))
-			{
-				throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
-			}
-
-			var valFac = Val * GtoKg(this);
-			return valFac.IsGreater(si.Val * GtoKg(si), tolerance == null ? DoubleExtensionMethods.Tolerance : (tolerance.Value() * GtoKg(tolerance)));
-		}
-
-		/// <summary>
-		/// Determines whether the specified si is greater.
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerStepThrough]
-		public bool IsGreater(SI si, double tolerance)
-		{
-			if (!HasEqualUnit(si))
-			{
-				throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
-			}
-
-			var valFac = Val * GtoKg(this);
-
-			return valFac.IsGreater(si.Val * GtoKg(si), tolerance);
-		}
-
-		/// <summary>
-		/// Determines whether [is greater or equal] [the specified si].
-		/// </summary>
-		/// <param name="si">The si.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerStepThrough]
-		public bool IsGreaterOrEqual(SI si, SI tolerance = null)
-		{
-			if (!HasEqualUnit(si))
-			{
-				throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
-			}
-			if (tolerance != null && !HasEqualUnit(tolerance))
-			{
-				throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
-			}
-
-			var valFac = Val * GtoKg(this);
-			return valFac.IsGreaterOrEqual(si.Val * GtoKg(si), tolerance == null ? DoubleExtensionMethods.Tolerance : (tolerance.Value() * GtoKg(tolerance)));
-		}
-
-		/// <summary>
-		/// Determines whether the specified value is smaller.
-		/// </summary>
-		/// <param name="val">The value.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerStepThrough]
-		public bool IsSmaller(double val, double tolerance = DoubleExtensionMethods.Tolerance)
-		{
-			return Val.IsSmaller(val, tolerance);
-		}
-
-		/// <summary>
-		/// Determines whether [is smaller or equal] [the specified value].
-		/// </summary>
-		/// <param name="val">The value.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerStepThrough]
-		public bool IsSmallerOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
-		{
-			return Val.IsSmallerOrEqual(val, tolerance);
-		}
-
-		/// <summary>
-		/// Determines whether the specified value is greater.
-		/// </summary>
-		/// <param name="val">The value.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerStepThrough]
-		public bool IsGreater(double val, double tolerance = DoubleExtensionMethods.Tolerance)
-		{
-			return Val.IsGreater(val, tolerance);
-		}
-
-		/// <summary>
-		/// Determines whether [is greater or equal] [the specified value].
-		/// </summary>
-		/// <param name="val">The value.</param>
-		/// <param name="tolerance">The tolerance.</param>
-		/// <returns></returns>
-		[DebuggerStepThrough]
-		public bool IsGreaterOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
-		{
-			return Val.IsGreaterOrEqual(val, tolerance);
-		}
-
-		public override int GetHashCode()
-		{
-			unchecked
-			{
-				// ReSharper disable once NonReadonlyMemberInGetHashCode
-				var hashCode = Val.GetHashCode();
-				hashCode = (hashCode * 397) ^ (_units != null ? _units.GetHashCode() : 0);
-				return hashCode;
-			}
-		}
-
-		public int CompareTo(object obj)
-		{
-			var si = obj as SI;
-			if (si == null)
-			{
-				return 1;
-			}
-
-			if (!HasEqualUnit(si))
-			{
-				//if (SIUtils.GetnumberofSIUnits(si.Units) >= SIUtils.GetnumberofSIUnits(Units))
-				if (si._units.Sum<int>(n => Math.Abs(n)) >= _units.Sum<int>(n => Math.Abs(n)))
-				{
-					return -1;
-				}
-				return 1;
-			}
-
-			if (this > si)
-			{
-				return 1;
-			}
-			return this < si ? -1 : 0;
-		}
-
-		public static bool operator ==(SI left, SI right)
-		{
-			return Equals(left, right);
-		}
-
-		public static bool operator !=(SI left, SI right)
-		{
-			return !Equals(left, right);
-		}
-
-		#endregion
-
-		/// <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 string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null)
-		{
-			decimals = decimals ?? 4;
-			outputFactor = outputFactor ?? 1.0;
-			showUnit = showUnit ?? false;
-
-			if (showUnit.Value)
-			{
-				return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture) + " [" +
-						GetUnitString() + "]";
-			}
-
-			return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture);
-		}
-
-		public string ToGUIFormat()
-		{
-			return Val.ToGUIFormat();
-		}
-
-		public string ToXMLFormat(uint? decimals = null)
-		{
-			decimals = decimals ?? 2;
-			return Val.ToString("F" + decimals.Value, CultureInfo.InvariantCulture);
-		}
-
-		public class EqualityComparer<T> : IEqualityComparer<T> where T : SI
-		{
-			private readonly double _precision;
-
-			public EqualityComparer(double precision = DoubleExtensionMethods.Tolerance)
-			{
-				_precision = precision;
-			}
-
-			public bool Equals(T x, T y)
-			{
-				return x.IsEqual(y.Value(), _precision);
-			}
-
-			public int GetHashCode(T obj)
-			{
-				return obj.Value().GetHashCode();
-			}
-		}
-	}
+    /// <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>
+    {
+        private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Scalar(double val) : base(val, Units) { }
+
+        public static implicit operator double(Scalar self)
+        {
+            return self.Val;
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator +(Scalar si1, Scalar si2)
+        {
+            return Create(si1.Val + si2.Val);
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator +(Scalar si1, double si2)
+        {
+            return Create(si1.Val + si2);
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator +(double si1, Scalar si2)
+        {
+            return Create(si1 + si2.Val);
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator -(Scalar si1, Scalar si2)
+        {
+            return Create(si1.Val - si2.Val);
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator -(Scalar si1, double si2)
+        {
+            return Create(si1.Val - si2);
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator -(double si1, Scalar si2)
+        {
+            return Create(si1 - si2.Val);
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Newton [N].
+    /// </summary>
+    public class Newton : SIBase<Newton>
+    {
+        private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Newton(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static NewtonMeter operator *(Newton newton, Meter meter)
+        {
+            return SIBase<NewtonMeter>.Create(newton.Val * meter.Value());
+        }
+
+        [DebuggerHidden]
+        public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond)
+        {
+            return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value());
+        }
+
+        [DebuggerHidden]
+        public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton)
+        {
+            return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Radian [] (rad).
+    /// </summary>
+    public class Radian : SIBase<Radian>
+    {
+        private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Radian(double val) : base(val, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for PerSquareSecond [1/s^2].
+    /// </summary>
+    public class PerSquareSecond : SIBase<PerSquareSecond>
+    {
+        private static readonly int[] Units = { 0, 0, -2, 0, 0, 0, 0 };
+        [DebuggerHidden]
+        private PerSquareSecond(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second)
+        {
+            return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Meter per square second [m/s^2].
+    /// </summary>
+    public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond>
+    {
+        private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private MeterPerSquareSecond(double val) : base(val, Units) { }
+
+        /// <summary>
+        /// Implements the operator *.
+        /// </summary>
+        [DebuggerHidden]
+        public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second)
+        {
+            return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Second [s].
+    /// </summary>
+    public class Second : SIBase<Second>
+    {
+        private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Second(double val) : base(val, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for Meter [m].
+    /// </summary>
+    public class Meter : SIBase<Meter>
+    {
+        private static readonly int[] Units = { 0, 1, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Meter(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static MeterPerSecond operator /(Meter meter, Second second)
+        {
+            return SIBase<MeterPerSecond>.Create(meter.Val / second.Value());
+        }
+
+        [DebuggerHidden]
+        public static MeterPerSecond operator *(Meter meter, PerSecond perSecond)
+        {
+            return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator /.
+        /// </summary>
+        [DebuggerHidden]
+        public static Second operator /(Meter second, MeterPerSecond meterPerSecond)
+        {
+            return SIBase<Second>.Create(second.Val / meterPerSecond.Value());
+        }
+    }
+
+    /// <summary>
+    ///  SI Class for KilogramPerMeter [kg/m].
+    /// </summary>
+    public class KilogramPerMeter : SIBase<KilogramPerMeter>
+    {
+        private static readonly int[] Units = { 1, -1, 0, 0, 0, 0, 0 };
+        [DebuggerHidden]
+        private KilogramPerMeter(double val) : base(val, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for Liter per Second [l/s].
+    /// </summary>
+    public class LiterPerSecond : SIBase<LiterPerSecond>
+    {
+        private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 };
+
+        private LiterPerSecond(double val) : base(val * 0.001, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for Kilogram [kg].
+    /// </summary>
+    public class Kilogram : SIBase<Kilogram>
+    {
+        private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Kilogram(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static KilogramPerSecond operator /(Kilogram kg, Second second)
+        {
+            return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value());
+        }
+
+        [DebuggerHidden]
+        public static SI operator /(Kilogram kg, Joule j)
+        {
+            return (kg as SI) / j;
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator /(Kilogram kg, Kilogram kg2)
+        {
+            return SIBase<Scalar>.Create(kg.Val / kg2.Val);
+        }
+
+        [DebuggerHidden]
+        public static KilogramPerMeter operator /(Kilogram kg, Meter m)
+        {
+            return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value());
+        }
+
+        [DebuggerHidden]
+        public static Newton operator *(Kilogram kg, MeterPerSquareSecond m)
+        {
+            return SIBase<Newton>.Create(kg.Val * m.Value());
+        }
+
+        [DebuggerHidden]
+        public static Kilogram operator *(Kilogram kg, double d)
+        {
+            return new Kilogram(kg.Val * d);
+        }
+
+        [DebuggerHidden]
+        public static Kilogram operator *(double d, Kilogram kg)
+        {
+            return new Kilogram(d * kg.Val);
+        }
+
+        public static Liter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter)
+        {
+            return SIBase<Liter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value() * 1000);
+        }
+    }
+
+    public class Liter : SIBase<Liter>
+    {
+        private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Liter(double val) : base(val * 0.001, Units) { }
+
+        public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter)
+        {
+            return SIBase<Kilogram>.Create(liter.Val / 1000 * kilogramPerCubicMeter.Value());
+        }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class NormLiter : SIBase<NormLiter>
+    {
+        private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private NormLiter(double val) : base(val * 0.001, Units) { }
+
+        public static NormLiterPerSecond operator /(NormLiter nl, Second s)
+        {
+            return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value());
+        }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public class NormLiterPerSecond : SIBase<NormLiterPerSecond>
+    {
+        private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private NormLiterPerSecond(double val) : base(val * 0.001, Units) { }
+
+        public static NormLiter operator *(NormLiterPerSecond nips, Second s)
+        {
+            return SIBase<NormLiter>.Create(nips.Val * s.Value());
+        }
+
+        public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val)
+        {
+            return Create(nps.Val * val);
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Kilogram per Second [kg].
+    /// </summary>
+    public class KilogramPerSecond : SIBase<KilogramPerSecond>
+    {
+        private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private KilogramPerSecond(double value) : base(value, Units) { }
+
+        [DebuggerHidden]
+        public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second)
+        {
+            return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Square meter [m^2].
+    /// </summary>
+    public class SquareMeter : SIBase<SquareMeter>
+    {
+        private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private SquareMeter(double value) : base(value, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for cubic meter [m^3].
+    /// </summary>
+    public class CubicMeter : SIBase<CubicMeter>
+    {
+        private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private CubicMeter(double value)
+            : base(value, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for Kilogram Square Meter [kgm^2].
+    /// </summary>
+    public class KilogramSquareMeter : SIBase<KilogramSquareMeter>
+    {
+        private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private KilogramSquareMeter(double value) : base(value, Units) { }
+
+        [DebuggerHidden]
+        public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond)
+        {
+            return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Kilogram Square Meter [kgm^2].
+    /// </summary>
+    public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter>
+    {
+        private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private KilogramPerCubicMeter(double value) : base(value, Units) { }
+
+        [DebuggerHidden]
+        public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter)
+        {
+            return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value());
+        }
+
+        public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, Liter liter)
+        {
+            return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * liter.Value() / 1000);
+        }
+
+        //public static CubicMeter operator /(Kilogram kg, KilogramPerCubicMeter kgm3)
+        //{
+        //	return SIBase<CubicMeter>.Create(kg.Value() / kgm3.Val);
+        //}
+    }
+
+    /// <summary>
+    /// SI Class for Kilogramm per watt second [kg/Ws].
+    /// W = kgm^2/s^3
+    /// </summary>
+    public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond>
+    {
+        private static readonly int[] Units = { 0, -2, 2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private KilogramPerWattSecond(double val) : base(val, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for watt second [Ws].
+    /// W = kgm^2/s^3
+    /// </summary>
+    public class WattSecond : SIBase<WattSecond>
+    {
+        private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private WattSecond(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static Watt operator /(WattSecond wattSecond, Second second)
+        {
+            return SIBase<Watt>.Create(wattSecond.Val / second.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Watt [W].
+    /// </summary>
+    public class Watt : SIBase<Watt>
+    {
+        private static readonly int[] Units = { 1, 2, -3, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Watt(double val) : base(val, Units) { }
+
+        /// <summary>
+        /// Implements the operator /.
+        /// </summary>
+        /// <param name="watt">The watt.</param>
+        /// <param name="newtonMeter">The newton meter.</param>
+        /// <returns>
+        /// The result of the operator.
+        /// </returns>
+        [DebuggerHidden]
+        public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter)
+        {
+            return SIBase<PerSecond>.Create(watt.Val / newtonMeter.Value());
+        }
+
+        [DebuggerHidden]
+        public static Newton operator /(Watt watt, MeterPerSecond meterPerSecond)
+        {
+            return SIBase<Newton>.Create(watt.Val / meterPerSecond.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator /.
+        /// </summary>
+        /// <param name="watt">The watt.</param>
+        /// <param name="perSecond">The per second.</param>
+        /// <returns>
+        /// The result of the operator.
+        /// </returns>
+        [DebuggerHidden]
+        public static NewtonMeter operator /(Watt watt, PerSecond perSecond)
+        {
+            return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value());
+        }
+
+        [DebuggerHidden]
+        public static WattSecond operator *(Watt watt, Second second)
+        {
+            return SIBase<WattSecond>.Create(watt.Val * second.Value());
+        }
+
+        [DebuggerHidden]
+        public static Watt operator *(Watt watt, double val)
+        {
+            return Create(watt.Val * val);
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Joule [J].
+    /// J = Ws = kgm^2/s^2
+    /// </summary>
+    public class Joule : SIBase<Joule>
+    {
+        private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private Joule(double val) : base(val, Units) { }
+
+        public static implicit operator Joule(WattSecond self)
+        {
+            return Create(self.Value());
+        }
+
+        public static Joule operator +(Joule joule, WattSecond ws)
+        {
+            return Create(joule.Val + ws.Value());
+        }
+
+        public static Watt operator /(Joule joule, Second s)
+        {
+            return SIBase<Watt>.Create(joule.Val / s.Value());
+        }
+
+        public static JoulePerMeter operator /(Joule joule, Meter meter)
+        {
+            return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Watt [W].
+    /// J = Ws
+    /// W = kgm^2/s^3
+    /// </summary>
+    public class JoulePerKilogramm : SIBase<JoulePerKilogramm>
+    {
+        private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 };
+
+        private JoulePerKilogramm(double val) : base(val, Units) { }
+
+        public static Joule operator *(Kilogram kg, JoulePerKilogramm jpg)
+        {
+            return SIBase<Joule>.Create(kg.Value() * jpg.Val);
+        }
+    }
+
+    /// <summary>
+    ///  SI Class for Joule per Meter [J/m].
+    ///  J = Ws
+    ///  W = kgm^2/s^3
+    /// </summary>
+    public class JoulePerMeter : SIBase<JoulePerMeter>
+    {
+        private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private JoulePerMeter(double val) : base(val, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for one per second [1/s].
+    /// </summary>
+    [DebuggerDisplay("rad/s: {Val} | rpm: {AsRPM}")]
+    public class PerSecond : SIBase<PerSecond>
+    {
+        private static readonly int[] Units = { 0, 0, -1, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private PerSecond(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static PerSquareSecond operator /(PerSecond perSecond, Second second)
+        {
+            return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value());
+        }
+
+        public double AsRPM
+        {
+            get { return Val * 60 / (2 * Math.PI); }
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Meter per second [m/s].
+    /// </summary>
+    [DebuggerDisplay("{Val} | {AsKmph}")]
+    public class MeterPerSecond : SIBase<MeterPerSecond>
+    {
+        private static readonly int[] Units = { 0, 1, -1, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private MeterPerSecond(double val) : base(val, Units) { }
+
+        public double AsKmph
+        {
+            get { return Val * 3.6; }
+        }
+
+        /// <summary>
+        /// Implements the operator /.
+        /// </summary>
+        [DebuggerHidden]
+        public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter)
+        {
+            return SIBase<PerSecond>.Create(meterPerSecond.Val / meter.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator /.
+        /// </summary>
+        [DebuggerHidden]
+        public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond)
+        {
+            return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator /.
+        /// </summary>
+        [DebuggerHidden]
+        public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second)
+        {
+            return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator *.
+        /// </summary>
+        [DebuggerHidden]
+        public static Meter operator *(MeterPerSecond meterPerSecond, Second second)
+        {
+            return SIBase<Meter>.Create(meterPerSecond.Val * second.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator *.
+        /// </summary>
+        [DebuggerHidden]
+        public static MeterPerSquareSecond operator *(MeterPerSecond meterPerSecond, PerSecond perSecond)
+        {
+            return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val * perSecond.Value());
+        }
+
+        /// <summary>
+        /// Implements the operator *.
+        /// </summary>
+        [DebuggerHidden]
+        public static Meter operator *(Second second, MeterPerSecond meterPerSecond)
+        {
+            return SIBase<Meter>.Create(second.Value() * meterPerSecond.Val);
+        }
+    }
+
+    /// <summary>
+    /// SI Class for NewtonMeter [Nm].
+    /// N = kgm/s^2
+    /// </summary>
+    public class NewtonMeter : SIBase<NewtonMeter>
+    {
+        private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        private NewtonMeter(double val) : base(val, Units) { }
+
+        [DebuggerHidden]
+        public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond)
+        {
+            return SIBase<Watt>.Create(newtonMeter.Val * perSecond.Value());
+        }
+
+        [DebuggerHidden]
+        public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter)
+        {
+            return SIBase<Watt>.Create(perSecond.Value() * newtonMeter.Val);
+        }
+
+        [DebuggerHidden]
+        public static Second operator /(NewtonMeter newtonMeter, Watt watt)
+        {
+            return SIBase<Second>.Create(newtonMeter.Val / watt.Value());
+        }
+
+        [DebuggerHidden]
+        public static PerSquareSecond operator /(NewtonMeter newtonMeter, KilogramSquareMeter kgKilogramSquareMeter)
+        {
+            return SIBase<PerSquareSecond>.Create(newtonMeter.Val / kgKilogramSquareMeter.Value());
+        }
+
+        [DebuggerHidden]
+        public static PerSecond operator /(NewtonMeter newtonMeter, NewtonMeterSecond newtonMeterSecond)
+        {
+            return SIBase<PerSecond>.Create(newtonMeter.Val / newtonMeterSecond.Value());
+        }
+
+        [DebuggerHidden]
+        public static Newton operator /(NewtonMeter newtonMeter, Meter meter)
+        {
+            return SIBase<Newton>.Create(newtonMeter.Val / meter.Value());
+        }
+
+        [DebuggerHidden]
+        public static NewtonMeterSecond operator /(NewtonMeter newtonMeter, PerSecond perSecond)
+        {
+            return SIBase<NewtonMeterSecond>.Create(newtonMeter.Val / perSecond.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for NewtonMeterSecond [Nms].
+    /// N = kgm/s^2
+    /// </summary>
+    public class NewtonMeterSecond : SIBase<NewtonMeterSecond>
+    {
+        private static readonly int[] Units = { 1, 2, -1, 0, 0, 0, 0 };
+        private NewtonMeterSecond(double val) : base(val, Units) { }
+    }
+
+    /// <summary>
+    /// SI Class for Amperer [A].
+    /// </summary>
+    public class Ampere : SIBase<Ampere>
+    {
+        private static readonly int[] Units = { 0, 0, 0, 1, 0, 0, 0 };
+        private Ampere(double val) : base(val, Units) { }
+
+        public static Watt operator *(Ampere ampere, Volt volt)
+        {
+            return SIBase<Watt>.Create(volt.Value() * ampere.Val);
+        }
+
+        public static Ampere operator *(Ampere ampere, double val)
+        {
+            return Create(ampere.Val * val);
+        }
+
+        public static Volt operator /(Watt watt, Ampere ampere)
+        {
+            return SIBase<Volt>.Create(watt.Value() / ampere.Value());
+        }
+    }
+
+    /// <summary>
+    /// SI Class for Amperer [V].
+    /// V = kgm^2/As^2
+    /// </summary>
+    public class Volt : SIBase<Volt>
+    {
+        private static readonly int[] Units = { 1, 2, -2, -1, 0, 0, 0 };
+        private Volt(double val) : base(val, Units) { }
+
+        public static Watt operator *(Volt volt, Ampere ampere)
+        {
+            return SIBase<Watt>.Create(volt.Val * ampere.Value());
+        }
+
+        public static Ampere operator /(Watt watt, Volt volt)
+        {
+            return SIBase<Ampere>.Create(watt.Value() / volt.Value());
+        }
+    }
+
+    /// <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>
+    {
+        private static readonly T ZeroPrototype;
+
+        static SIBase()
+        {
+            const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
+            var constructorInfo = typeof(T).GetConstructor(bindingFlags, null, new[] { typeof(double) }, null);
+            var parameter = Expression.Parameter(typeof(double));
+            var lambda = Expression.Lambda<Func<double, T>>(Expression.New(constructorInfo, parameter), parameter);
+            Constructor = lambda.Compile();
+            ZeroPrototype = Constructor(0);
+        }
+
+        /// <summary>
+        /// The constructor for the generic type T.
+        /// </summary>
+        private static readonly Func<double, T> Constructor;
+
+        /// <summary>
+        /// Creates the specified special SI object.
+        /// </summary>
+        /// <param name="val">The value of the SI object.</param>
+        [DebuggerStepThrough]
+        public static T Create(double val)
+        {
+            if (val == 0)
+            {
+                return ZeroPrototype;
+            }
+
+            return Constructor(val);
+        }
+
+        [DebuggerStepThrough]
+        protected SIBase(double value, int[] units) : base(value, units) { }
+
+        [DebuggerStepThrough]
+        public new T Abs()
+        {
+            return Create(Math.Abs(Val));
+        }
+
+        #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 Create(si1.Val + si2.Val);
+        }
+
+        /// <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 (si1 + (si2 as SI)).Cast<T>();
+        }
+
+        /// <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 Create(-si1.Val);
+        }
+
+        /// <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 Create(si1.Val - si2.Val);
+        }
+
+        /// <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 (si1 - (si2 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 Create(d * si.Val);
+        }
+
+        /// <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 Create(si.Val * 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 Create(si.Val / d);
+        }
+
+        [DebuggerHidden]
+        public static Scalar operator /(SIBase<T> si, SIBase<T> si2)
+        {
+            return SIBase<Scalar>.Create(si.Val / si2.Val);
+        }
+
+        #endregion
+    }
+
+    /// <summary>
+    /// Class for representing generic SI Units.
+    /// </summary>
+    /// <remarks>
+    /// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute
+    /// </remarks>
+    [DebuggerDisplay("{Val}")]
+    public class SI : IComparable
+    {
+        /// <summary>
+        /// The basic scalar value of the SI.
+        /// </summary>
+        protected readonly double Val;
+
+        /// <summary>
+        /// The array of the SI units.
+        /// </summary>
+        private readonly int[] _units;
+
+        /// <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="units">The units.</param>
+        /// <param name="isMassParam"></param>
+        protected SI(double val, int[] units)
+        {
+            Val = val;
+            _units = units;
+
+            if (double.IsNaN(Val))
+            {
+                throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
+            }
+
+            if (double.IsInfinity(Val))
+            {
+                throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
+            }
+        }
+
+        public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits())
+        {
+
+        }
+
+        /// <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>
+        [DebuggerHidden]
+        private SI(double val, SI unit) : this(val, unit._units) { }
+
+        [DebuggerHidden]
+        private SI(SI si, double factor, int[] unitsParam)
+        {
+            Val = si.Val / factor;
+            _units = unitsParam;
+
+            if (double.IsNaN(Val))
+            {
+                throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
+            }
+
+            if (double.IsInfinity(Val))
+            {
+                throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
+            }
+        }
+
+        public SI ConvertTo(UnitInstance si)
+        {
+
+            if (!SIUtils.CompareUnits(_units, si.GetSIUnits()))
+            {
+                throw new VectoException("Unit missing. Conversion not possible. [{0}] does not contain a [{1}].", GetUnitString(_units), si.GetSIUnits());
+            }
+
+            var factorValue = si.Factor;
+            return new SI(this, unitsParam: si.GetSIUnits(), factor: factorValue);
+        }
+
+        /// <summary>
+        /// Casts the SI Unit to the concrete unit type (if the units allow such an cast).
+        /// </summary>
+        /// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam>
+        [DebuggerHidden]
+        public T Cast<T>() where T : SIBase<T>
+        {
+            var si = ToBasicUnits();
+            var t = SIBase<T>.Create(si.Val);
+            if (!si.HasEqualUnit(t))
+            {
+                throw new VectoException("SI Unit Conversion failed: From {0} to {1}", si, t);
+            }
+            return t;
+        }
+
+        /// <summary>
+        /// Converts the derived SI units to the basic units and returns this as a new SI object.
+        /// </summary>
+        public SI ToBasicUnits()
+        {
+            return new SI(Val, _units);
+        }
+
+
+        /// <summary>
+        /// Gets the underlying scalar double value.
+        /// </summary>
+        [DebuggerHidden]
+        public double Value()
+        {
+            return Val;
+        }
+
+        /// <summary>
+        /// Clones this instance.
+        /// </summary>
+        public SI Clone()
+        {
+            return new SI(Val, _units);
+        }
+
+        /// <summary>
+        /// Returns the absolute value.
+        /// </summary>
+        public SI Abs()
+        {
+            return new SI(Math.Abs(Val), this);
+        }
+
+        /// <summary>
+        /// Returns the numerical sign of the SI.
+        /// </summary>
+        /// <returns>-1 if si &lt; 0. 0 if si==0, 1 if si &gt; 0.</returns>
+        [DebuggerHidden]
+        public int Sign()
+        {
+            return Math.Sign(Val);
+        }
+
+        #region Operators
+
+        [DebuggerHidden]
+        public static SI operator +(SI si1, SI si2)
+        {
+            if (!si1.HasEqualUnit(si2))
+            {
+                throw new VectoException("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2);
+            }
+
+
+            return new SI(si1.Val + si2.Val, si1);
+        }
+
+        [DebuggerHidden]
+        public static SI operator -(SI si1, SI si2)
+        {
+            if (!si1.HasEqualUnit(si2))
+            {
+                throw new VectoException("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2);
+            }
+            return new SI(si1.Val - si2.Val, si1);
+        }
+
+        [DebuggerHidden]
+        public static SI operator -(SI si1)
+        {
+            return new SI(-si1.Val, si1);
+        }
+
+        public static SI operator *(SI si1, SI si2)
+        {
+            var unitArray = SIUtils.CombineUnits(si1._units, si2._units);
+            return new SI(si1.Val * si2.Val, unitArray);
+        }
+
+        [DebuggerHidden]
+        public static SI operator *(SI si1, double d)
+        {
+            return new SI(si1.Val * d, si1);
+        }
+
+        [DebuggerHidden]
+        public static SI operator *(double d, SI si1)
+        {
+            return new SI(d * si1.Val, si1);
+        }
+
+        public static SI operator /(SI si1, SI si2)
+        {
+            double result;
+            try
+            {
+                result = si1.Val / (si2.Val);
+
+                // bad cases: Infinity = x / 0.0  (for x != 0), NaN = 0.0 / 0.0
+                if (double.IsInfinity(result) || double.IsNaN(result))
+                {
+                    throw new DivideByZeroException();
+                }
+            }
+            catch (DivideByZeroException ex)
+            {
+                throw new VectoException(
+                    string.Format("Can not compute division by zero ([{0}] / 0[{1}])", si1.GetUnitString(), si2.GetUnitString()), ex);
+            }
+
+            var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1));
+
+            return new SI(result, unitArray);
+        }
+
+        [DebuggerHidden]
+        public static SI operator /(SI si1, double d)
+        {
+            if (d.IsEqual(0))
+            {
+                throw new VectoException(string.Format("Can not compute division by zero ([{0}] / 0)", si1.GetUnitString()), new DivideByZeroException());
+            }
+
+            return new SI(si1.Val / d, si1);
+        }
+
+        [DebuggerHidden]
+        public static SI operator /(double d, SI si1)
+        {
+            if (si1.IsEqual(0))
+            {
+                throw new VectoException(string.Format("Can not compute division by zero (x / 0[{0}])", si1.GetUnitString()),
+                    new DivideByZeroException());
+            }
+
+            return new SI(d / (si1.Val), si1._units.Select(u => -u).ToArray());
+        }
+
+        [DebuggerHidden]
+        public static bool operator <(SI si1, SI si2)
+        {
+            if (!si1.HasEqualUnit(si2))
+            {
+                throw new VectoException("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2);
+            }
+            return si1.Val < si2.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator <(SI si1, double d)
+        {
+            return si1 != null && si1.Val < d;
+        }
+
+        [DebuggerHidden]
+        public static bool operator >(SI si1, SI si2)
+        {
+            if (!si1.HasEqualUnit(si2))
+            {
+                throw new VectoException("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2);
+            }
+            return si1.Val > si2.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator >(SI si1, double d)
+        {
+            return si1 != null && si1.Val > d;
+        }
+
+        [DebuggerHidden]
+        public static bool operator >(double d, SI si1)
+        {
+            return si1 != null && d > si1.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator <(double d, SI si1)
+        {
+            return si1 != null && d < si1.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator <=(SI si1, SI si2)
+        {
+            if (!si1.HasEqualUnit(si2))
+            {
+                throw new VectoException("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1,
+                    si2);
+            }
+            return si1.Val <= si2.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator <=(SI si1, double d)
+        {
+            return si1 != null && si1.Val <= d;
+        }
+
+        [DebuggerHidden]
+        public static bool operator >=(SI si1, SI si2)
+        {
+            if (!si1.HasEqualUnit(si2))
+            {
+                throw new VectoException("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1,
+                    si2);
+            }
+            return si1.Val >= si2.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator >=(SI si1, double d)
+        {
+            return si1 != null && si1.Val >= d;
+        }
+
+        [DebuggerHidden]
+        public static bool operator >=(double d, SI si1)
+        {
+            return si1 != null && d >= si1.Val;
+        }
+
+        [DebuggerHidden]
+        public static bool operator <=(double d, SI si1)
+        {
+            return si1 != null && d <= si1.Val;
+        }
+
+        /// <summary>
+        /// Determines whether the SI is between lower and uppper bound.
+        /// </summary>
+        /// <param name="lower">The lower bound.</param>
+        /// <param name="upper">The upper bound.</param>
+        /// <returns></returns>
+        public bool IsBetween(SI lower, SI upper)
+        {
+            return lower <= Val && Val <= upper;
+        }
+
+        /// <summary>
+        /// Determines whether the SI is between lower and upper bound.
+        /// </summary>
+        /// <param name="lower">The lower bound.</param>
+        /// <param name="upper">The upper bound.</param>
+        /// <returns></returns>
+        public bool IsBetween(double lower, double upper)
+        {
+            return lower <= Val && Val <= upper;
+        }
+
+        #endregion
+
+        #region ToString
+
+        /// <summary>
+        ///     Returns the Unit Part of the SI Unit Expression.
+        /// </summary>
+        public string GetUnitString(int[] units = null)
+        {
+            if (units == null)
+            {
+                units = _units;
+            }
+            return Unit.GetUnitString(units);
+        }
+
+        public override string ToString()
+        {
+            return ToString(null);
+        }
+
+        private string ToString(string format)
+        {
+            if (string.IsNullOrEmpty(format))
+            {
+                format = "F4";
+            }
+
+            return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, GetUnitString());
+        }
+
+        #endregion
+
+        #region Equality members
+
+        /// <summary>
+        /// Compares the Unit-Parts of two SI Units.
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <returns></returns>
+        [DebuggerHidden]
+        public bool HasEqualUnit(SI si)
+        {
+            return SIUtils.CompareUnits(_units, si._units);
+        }
+
+        /// <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))
+            {
+                return false;
+            }
+            if (ReferenceEquals(this, obj))
+            {
+                return true;
+            }
+            var other = obj as SI;
+
+            var valFac = Val;
+            return other != null && valFac.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, SI tolerance = null)
+        {
+            var valFac = Val;
+            return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) && valFac.IsEqual(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value());
+        }
+
+        /// <summary>
+        /// Determines whether the specified value is equal.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerHidden]
+        public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
+        {
+            var valFac = Val;
+            return valFac.IsEqual(val, tolerance);
+        }
+
+        /// <summary>
+        /// Determines whether the specified si is smaller.
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        public bool IsSmaller(SI si, SI tolerance = null)
+        {
+            if (!HasEqualUnit(si))
+            {
+                throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
+            }
+            if (tolerance != null && !HasEqualUnit(tolerance))
+            {
+                throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
+            }
+
+            var valFac = Val;
+            return valFac.IsSmaller(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value());
+        }
+
+        /// <summary>
+        /// Determines whether the specified si is smaller.
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        public bool IsSmaller(SI si, double tolerance)
+        {
+            if (!HasEqualUnit(si))
+            {
+                throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
+            }
+
+            var valFac = Val;
+            return valFac.IsSmaller(si.Val, tolerance);
+        }
+
+        /// <summary>
+        /// Determines whether [is smaller or equal] [the specified si].
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        public bool IsSmallerOrEqual(SI si, SI tolerance = null)
+        {
+            if (!HasEqualUnit(si))
+            {
+                throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
+            }
+            if (tolerance != null && !HasEqualUnit(tolerance))
+            {
+                throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
+            }
+
+            var valFac = Val;
+
+            return valFac.IsSmallerOrEqual(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value());
+        }
+
+        /// <summary>
+        /// Determines whether the specified si is greater.
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        public bool IsGreater(SI si, SI tolerance = null)
+        {
+            if (!HasEqualUnit(si))
+            {
+                throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
+            }
+            if (tolerance != null && !HasEqualUnit(tolerance))
+            {
+                throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
+            }
+
+            var valFac = Val;
+            return valFac.IsGreater(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value());
+        }
+
+        /// <summary>
+        /// Determines whether the specified si is greater.
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerStepThrough]
+        public bool IsGreater(SI si, double tolerance)
+        {
+            if (!HasEqualUnit(si))
+            {
+                throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
+            }
+
+            var valFac = Val;
+
+            return valFac.IsGreater(si.Val, tolerance);
+        }
+
+        /// <summary>
+        /// Determines whether [is greater or equal] [the specified si].
+        /// </summary>
+        /// <param name="si">The si.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerStepThrough]
+        public bool IsGreaterOrEqual(SI si, SI tolerance = null)
+        {
+            if (!HasEqualUnit(si))
+            {
+                throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si);
+            }
+            if (tolerance != null && !HasEqualUnit(tolerance))
+            {
+                throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance);
+            }
+
+            var valFac = Val;
+            return valFac.IsGreaterOrEqual(si.Val, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value());
+        }
+
+        /// <summary>
+        /// Determines whether the specified value is smaller.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerStepThrough]
+        public bool IsSmaller(double val, double tolerance = DoubleExtensionMethods.Tolerance)
+        {
+            return Val.IsSmaller(val, tolerance);
+        }
+
+        /// <summary>
+        /// Determines whether [is smaller or equal] [the specified value].
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerStepThrough]
+        public bool IsSmallerOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
+        {
+            return Val.IsSmallerOrEqual(val, tolerance);
+        }
+
+        /// <summary>
+        /// Determines whether the specified value is greater.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerStepThrough]
+        public bool IsGreater(double val, double tolerance = DoubleExtensionMethods.Tolerance)
+        {
+            return Val.IsGreater(val, tolerance);
+        }
+
+        /// <summary>
+        /// Determines whether [is greater or equal] [the specified value].
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <param name="tolerance">The tolerance.</param>
+        /// <returns></returns>
+        [DebuggerStepThrough]
+        public bool IsGreaterOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance)
+        {
+            return Val.IsGreaterOrEqual(val, tolerance);
+        }
+
+        public override int GetHashCode()
+        {
+            unchecked
+            {
+                // ReSharper disable once NonReadonlyMemberInGetHashCode
+                var hashCode = Val.GetHashCode();
+                hashCode = (hashCode * 397) ^ (_units != null ? _units.GetHashCode() : 0);
+                return hashCode;
+            }
+        }
+
+        public int CompareTo(object obj)
+        {
+            var si = obj as SI;
+            if (si == null)
+            {
+                return 1;
+            }
+
+            if (!HasEqualUnit(si))
+            {
+                //if (SIUtils.GetnumberofSIUnits(si.Units) >= SIUtils.GetnumberofSIUnits(Units))
+                if (si._units.Sum<int>(n => Math.Abs(n)) >= _units.Sum<int>(n => Math.Abs(n)))
+                {
+                    return -1;
+                }
+                return 1;
+            }
+
+            if (this > si)
+            {
+                return 1;
+            }
+            return this < si ? -1 : 0;
+        }
+
+        public static bool operator ==(SI left, SI right)
+        {
+            return Equals(left, right);
+        }
+
+        public static bool operator !=(SI left, SI right)
+        {
+            return !Equals(left, right);
+        }
+
+        #endregion
+
+        /// <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 string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null)
+        {
+            decimals = decimals ?? 4;
+            outputFactor = outputFactor ?? 1.0;
+            showUnit = showUnit ?? false;
+
+            if (showUnit.Value)
+            {
+                return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture) + " [" +
+                        GetUnitString() + "]";
+            }
+
+            return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture);
+        }
+
+        public string ToGUIFormat()
+        {
+            return Val.ToGUIFormat();
+        }
+
+        public string ToXMLFormat(uint? decimals = null)
+        {
+            decimals = decimals ?? 2;
+            return Val.ToString("F" + decimals.Value, CultureInfo.InvariantCulture);
+        }
+
+        public class EqualityComparer<T> : IEqualityComparer<T> where T : SI
+        {
+            private readonly double _precision;
+
+            public EqualityComparer(double precision = DoubleExtensionMethods.Tolerance)
+            {
+                _precision = precision;
+            }
+
+            public bool Equals(T x, T y)
+            {
+                return x.IsEqual(y.Value(), _precision);
+            }
+
+            public int GetHashCode(T obj)
+            {
+                return obj.Value().GetHashCode();
+            }
+        }
+    }
 }
diff --git a/VectoCommon/VectoCommon/Utils/SIUtils.cs b/VectoCommon/VectoCommon/Utils/SIUtils.cs
index aca1a1b905..fd2af019a9 100644
--- a/VectoCommon/VectoCommon/Utils/SIUtils.cs
+++ b/VectoCommon/VectoCommon/Utils/SIUtils.cs
@@ -2,454 +2,413 @@
 
 namespace TUGraz.VectoCommon.Utils
 {
-	public struct SIUtils
-	{
-		public static bool CompareUnits(int[] units1, int[] units2)
-		{
-			for (var i = 0; i < units1.Length; i++)
-			{
-				if (units1[i] != units2[i])
-				{
-					return false;
-				}
-			}
-			return true;
-		}
-
-		public static int[] CombineUnits(int[] units1, int[] units2)
-		{
-			var units = new int[units1.Length];
-			for (var i = 0; i < units1.Length; i++)
-			{
-				units[i] = units1[i] + units2[i];
-			}
-			return units;
-
-		}
-
-		public static int[] MultiplyUnits(int[] units, int factor)
-		{
-			var result = new int[units.Length];
-			for (var i = 0; i < units.Length; i++)
-			{
-				if (units[i] != 0)
-				{
-					result[i] = units[i] * factor;
-				}
-			}
-			return result;
-		}
-	}
-
-
-	public struct Unit
-	{
-		// TODO mk-2017-09-14: must be exact the same definition as in the SI class - find a way to de-duplicate this
-		private static readonly string[] Unitnames = { "kg", "m", "s", "A", "K", "mol", "cd" };
-
-		public static UnitInstance SI
-		{
-			get
-			{
-				return new UnitInstance(new[] { 0, 0, 0, 0, 0, 0, 0 }, 1, 1, 1);
-			}
-		}
-		
-		public static string GetUnitString(int[] siUnitParam, bool isGramm)
-		{
-			var numerator = "";
-			var denominator = "";
-
-			for (var i = 0; i < siUnitParam.Length; i++)
-			{
-				var currentValue = siUnitParam[i];
-
-				var exponent = Math.Abs(currentValue);
-				var exponentStr = "";
-				if (currentValue != 0)
-				{
-					var currentUnit = Unitnames[i];
-					if (currentUnit == "kg" && isGramm)
-					{
-						currentUnit = "g";
-					}
-
-					if (exponent > 1)
-					{
-						exponentStr = "^" + exponent;
-					}
-
-					if (currentValue > 0)
-					{
-						numerator += currentUnit + exponentStr;
-
-					}
-					else if (currentValue < 0)
-					{
-						denominator += currentUnit + exponentStr;
-					}
-				}
-			}
-			string result;
-
-			if (numerator == "")
-			{
-				if (denominator == "")
-				{
-					result = "-";
-				}
-				else
-				{
-					result = "1/" + denominator;
-				}
-			}
-			else
-			{
-				if (denominator == "")
-				{
-					result = numerator;
-				}
-				else
-				{
-					result = numerator + "/" + denominator;
-				}
-			}
-
-			return result;
-		}
-	}
-
-	public struct UnitInstance
-	{
-		/// <summary>
-		/// kg, m, s, A, K, mol, cd
-		/// </summary>
-		private readonly int[] _units;
-
-		private int _exponent;
-		private int _reciproc;
-
-		[Flags]
-		public enum IsMass
-		{
-			IsKilo = 0x01,     //0001
-			IsGramm = 0x02,    //0010
-			IsKiloGramm = 0x04 //0100
-		}
-		private IsMass _isMassOption;
-
-		public double Factor { get; private set; }
-
-		public UnitInstance(int[] units, double factor, int exponent, int reciproc)
-		{
-			_units = units;
-			Factor = factor;
-			_exponent = exponent;
-			_reciproc = reciproc;
-			_isMassOption = IsMass.IsKiloGramm;
-		}
-
-		public IsMass GetGrammMode()
-		{
-			return _isMassOption;
-		}
-
-		public int[] GetSIUnits()
-		{
-			return _units;
-		}
-
-		/// <summary>
-		/// [g] (to basic unit: [kg])
-		/// </summary>
-		public UnitInstance Gramm
-		{
-			get
-			{
-				_units[0] += 1 * _reciproc * _exponent;
-
-				var factor = Math.Pow(1000, _reciproc * _exponent);
-
-				if ((_isMassOption & IsMass.IsKilo) == IsMass.IsKilo)
-				{
-					//is Kilo -> Kilogramm are selected
-					_isMassOption = _isMassOption | ~IsMass.IsGramm;
-					_isMassOption = _isMassOption | IsMass.IsKiloGramm;
-					Factor /= factor;
-				}
-				else
-				{
-					//is not kilo -> Gramm are selected
-					_isMassOption = _isMassOption | IsMass.IsGramm;
-					_isMassOption = _isMassOption | ~IsMass.IsKiloGramm;
-					//factorValue *= factor;
-				}
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-
-
-				//factorValue /= Math.Pow(1000, exponent * reciproc);
-				return this; // not work
-			}
-		}
-
-		/// <summary>
-		/// Takes all following terms as cubic terms (=to the power of 3).
-		/// </summary>
-		public UnitInstance Cubic
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				_exponent = 3;
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [s] Converts to/from Second. Internally everything is stored in seconds.
-		/// </summary>
-		public UnitInstance Hour
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[2] += 1 * reciprocAndExponent;
-
-				Factor *= Math.Pow(3600, reciprocAndExponent);
-
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// Quantifier for Kilo (1000).
-		/// </summary>
-		public UnitInstance Kilo
-		{
-			get
-			{
-				_isMassOption = _isMassOption | IsMass.IsKilo;
-				Factor *= Math.Pow(1000, _exponent * _reciproc);
-
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [m]
-		/// </summary>
-		public UnitInstance Meter
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				_units[1] += 1 * _reciproc * _exponent;
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// Quantifier for milli (1/1000).
-		/// </summary>
-		public UnitInstance Milli
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				Factor /= Math.Pow(1000, _exponent * _reciproc);
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// Quantifier for Centi (1/100)
-		/// </summary>
-		public UnitInstance Centi
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				Factor /= Math.Pow(100, _exponent * _reciproc);
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// Quantifier for Dezi (1/10)
-		/// </summary>
-		public UnitInstance Dezi
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				Factor /= Math.Pow(10, _exponent * _reciproc);
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [s] Converts to/from Second. Internally everything is stored in seconds.
-		/// </summary>
-		public UnitInstance Minute
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[2] += 1 * reciprocAndExponent;
-				Factor *= Math.Pow(60, reciprocAndExponent);
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [N]
-		/// </summary>
-		public UnitInstance Newton
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[0] += 1 * reciprocAndExponent;
-				_units[1] += 1 * reciprocAndExponent;
-				_units[2] -= 2 * reciprocAndExponent;
-
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// Defines the denominator by the terms following after the Per.
-		/// </summary>
-		public UnitInstance Per
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				_exponent = 1;
-				_reciproc = _reciproc * -1;
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [-]. Defines radian. Only virtual. Has no real SI unit.
-		/// </summary>
-		public UnitInstance Radian
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [-]. Converts to/from Radiant. Internally everything is stored in radian.
-		/// </summary>
-		public UnitInstance Rounds
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				Factor *= Math.Pow(2 * Math.PI, _exponent * _reciproc);
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [s]
-		/// </summary>
-		public UnitInstance Second
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				_units[2] += 1 * _reciproc * _exponent;
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// Takes all following terms as quadratic terms (=to the power of 2).
-		/// </summary>
-		public UnitInstance Square
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				_exponent = 2;
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [t] (to basic unit: [kg])
-		/// </summary>
-		public UnitInstance Ton
-		{
-			get
-			{
-				// remove Gramm and Kilo and KiloGramm is selected.
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-				_isMassOption = _isMassOption | ~IsMass.IsGramm;
-				_isMassOption = _isMassOption | IsMass.IsKiloGramm;
-
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[0] += 1 * reciprocAndExponent;
-				Factor *= Math.Pow(1000, reciprocAndExponent);
-
-				return this;
-			}
-		}
-
-		/// <summary>
-		/// [W]
-		/// </summary>
-		public UnitInstance Watt
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[0] += 1 * reciprocAndExponent;
-				_units[1] += 2 * reciprocAndExponent;
-				_units[2] -= 3 * reciprocAndExponent;
-
-				return this;
-			}
-		}
-		public UnitInstance Joule
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[0] += 1 * reciprocAndExponent;
-				_units[1] += 2 * reciprocAndExponent;
-				_units[2] -= 2 * reciprocAndExponent;
-
-				return this;
-			}
-		}
-
-		public UnitInstance Liter
-		{
-			get
-			{
-				_isMassOption = _isMassOption & ~IsMass.IsKilo;
-
-				var reciprocAndExponent = _reciproc * _exponent;
-				_units[1] += 3 * reciprocAndExponent;
-				Factor /= Math.Pow(1000, reciprocAndExponent);
-
-				return this;
-			}
-		}
-	}
+    public struct SIUtils
+    {
+        public static bool CompareUnits(int[] units1, int[] units2)
+        {
+            for (var i = 0; i < units1.Length; i++)
+            {
+                if (units1[i] != units2[i])
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        public static int[] CombineUnits(int[] units1, int[] units2)
+        {
+            var units = new int[units1.Length];
+            for (var i = 0; i < units1.Length; i++)
+            {
+                units[i] = units1[i] + units2[i];
+            }
+            return units;
+
+        }
+
+        public static int[] MultiplyUnits(int[] units, int factor)
+        {
+            var result = new int[units.Length];
+            for (var i = 0; i < units.Length; i++)
+            {
+                if (units[i] != 0)
+                {
+                    result[i] = units[i] * factor;
+                }
+            }
+            return result;
+        }
+    }
+
+
+    public struct Unit
+    {
+        // TODO mk-2017-09-14: must be exact the same definition as in the SI class - find a way to de-duplicate this
+        private static readonly string[] Unitnames = { "kg", "m", "s", "A", "K", "mol", "cd" };
+
+        public static UnitInstance SI
+        {
+            get
+            {
+                return new UnitInstance(new[] { 0, 0, 0, 0, 0, 0, 0 }, 1, 1, 1);
+            }
+        }
+
+        public static string GetUnitString(int[] siUnitParam)
+        {
+            var numerator = "";
+            var denominator = "";
+
+            for (var i = 0; i < siUnitParam.Length; i++)
+            {
+                var currentValue = siUnitParam[i];
+
+                var exponent = Math.Abs(currentValue);
+                var exponentStr = "";
+                if (currentValue != 0)
+                {
+                    var currentUnit = Unitnames[i];
+
+                    if (exponent > 1)
+                    {
+                        exponentStr = "^" + exponent;
+                    }
+
+                    if (currentValue > 0)
+                    {
+                        numerator += currentUnit + exponentStr;
+
+                    }
+                    else if (currentValue < 0)
+                    {
+                        denominator += currentUnit + exponentStr;
+                    }
+                }
+            }
+            string result;
+
+            if (numerator == "")
+            {
+                if (denominator == "")
+                {
+                    result = "-";
+                }
+                else
+                {
+                    result = "1/" + denominator;
+                }
+            }
+            else
+            {
+                if (denominator == "")
+                {
+                    result = numerator;
+                }
+                else
+                {
+                    result = numerator + "/" + denominator;
+                }
+            }
+
+            return result;
+        }
+    }
+
+    public struct UnitInstance
+    {
+        /// <summary>
+        /// kg, m, s, A, K, mol, cd
+        /// </summary>
+        private readonly int[] _units;
+
+        private int _exponent;
+        private int _reciproc;
+
+        public double Factor { get; private set; }
+
+        public UnitInstance(int[] units, double factor, int exponent, int reciproc)
+        {
+            _units = units;
+            Factor = factor;
+            _exponent = exponent;
+            _reciproc = reciproc;
+        }
+
+        public int[] GetSIUnits()
+        {
+            return _units;
+        }
+
+        /// <summary>
+        /// [g] (to basic unit: [kg])
+        /// </summary>
+        public UnitInstance Gramm
+        {
+            get
+            {
+                _units[0] += 1 * _reciproc * _exponent;
+
+                // division because kg is the base unit (g/1000 = kg)
+                Factor /= Math.Pow(1000, _reciproc * _exponent);
+
+                // todo mk-2017-10-02: visual studio displays wrong units - check if still not working
+                return this; 
+            }
+        }
+
+        /// <summary>
+        /// Takes all following terms as cubic terms (=to the power of 3).
+        /// </summary>
+        public UnitInstance Cubic
+        {
+            get
+            {
+
+                _exponent = 3;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [s] Converts to/from Second. Internally everything is stored in seconds.
+        /// </summary>
+        public UnitInstance Hour
+        {
+            get
+            {
+
+
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[2] += 1 * reciprocAndExponent;
+
+                Factor *= Math.Pow(3600, reciprocAndExponent);
+
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Quantifier for Kilo (1000).
+        /// </summary>
+        public UnitInstance Kilo
+        {
+            get
+            {
+                Factor *= Math.Pow(1000, _exponent * _reciproc);
+
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [m]
+        /// </summary>
+        public UnitInstance Meter
+        {
+            get
+            {
+
+                _units[1] += 1 * _reciproc * _exponent;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Quantifier for milli (1/1000).
+        /// </summary>
+        public UnitInstance Milli
+        {
+            get
+            {
+
+                Factor /= Math.Pow(1000, _exponent * _reciproc);
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Quantifier for Centi (1/100)
+        /// </summary>
+        public UnitInstance Centi
+        {
+            get
+            {
+
+                Factor /= Math.Pow(100, _exponent * _reciproc);
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Quantifier for Dezi (1/10)
+        /// </summary>
+        public UnitInstance Dezi
+        {
+            get
+            {
+
+                Factor /= Math.Pow(10, _exponent * _reciproc);
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [s] Converts to/from Second. Internally everything is stored in seconds.
+        /// </summary>
+        public UnitInstance Minute
+        {
+            get
+            {
+
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[2] += 1 * reciprocAndExponent;
+                Factor *= Math.Pow(60, reciprocAndExponent);
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [N]
+        /// </summary>
+        public UnitInstance Newton
+        {
+            get
+            {
+
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[0] += 1 * reciprocAndExponent;
+                _units[1] += 1 * reciprocAndExponent;
+                _units[2] -= 2 * reciprocAndExponent;
+
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Defines the denominator by the terms following after the Per.
+        /// </summary>
+        public UnitInstance Per
+        {
+            get
+            {
+
+                _exponent = 1;
+                _reciproc = _reciproc * -1;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [-]. Defines radian. Only virtual. Has no real SI unit.
+        /// </summary>
+        public UnitInstance Radian
+        {
+            get
+            {
+
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [-]. Converts to/from Radiant. Internally everything is stored in radian.
+        /// </summary>
+        public UnitInstance Rounds
+        {
+            get
+            {
+
+                Factor *= Math.Pow(2 * Math.PI, _exponent * _reciproc);
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [s]
+        /// </summary>
+        public UnitInstance Second
+        {
+            get
+            {
+
+                _units[2] += 1 * _reciproc * _exponent;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// Takes all following terms as quadratic terms (=to the power of 2).
+        /// </summary>
+        public UnitInstance Square
+        {
+            get
+            {
+
+                _exponent = 2;
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [t] (to basic unit: [kg])
+        /// </summary>
+        public UnitInstance Ton
+        {
+            get
+            {
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[0] += 1 * reciprocAndExponent;
+                Factor *= Math.Pow(1000, reciprocAndExponent);
+
+                return this;
+            }
+        }
+
+        /// <summary>
+        /// [W]
+        /// </summary>
+        public UnitInstance Watt
+        {
+            get
+            {
+
+
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[0] += 1 * reciprocAndExponent;
+                _units[1] += 2 * reciprocAndExponent;
+                _units[2] -= 3 * reciprocAndExponent;
+
+                return this;
+            }
+        }
+        public UnitInstance Joule
+        {
+            get
+            {
+
+
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[0] += 1 * reciprocAndExponent;
+                _units[1] += 2 * reciprocAndExponent;
+                _units[2] -= 2 * reciprocAndExponent;
+
+                return this;
+            }
+        }
+
+        public UnitInstance Liter
+        {
+            get
+            {
+
+
+                var reciprocAndExponent = _reciproc * _exponent;
+                _units[1] += 3 * reciprocAndExponent;
+                Factor /= Math.Pow(1000, reciprocAndExponent);
+
+                return this;
+            }
+        }
+    }
 }
diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
index 61b87638f2..c563053744 100644
--- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
@@ -374,7 +374,6 @@ namespace TUGraz.VectoCore.OutputData
 
 			var fcVolumePerMeter = fuelConsumptionFinal / data.FuelData.FuelDensity;
             // fcVolumePerMeter = [m^2]
-            //return fcVolumePerMeter.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter;
             return fcVolumePerMeter.ConvertTo(Unit.SI.Square.Dezi.Meter) * 100.SI(Unit.SI.Kilo.Meter);
         }
 
diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
index b332560a68..d62335abe6 100644
--- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
@@ -418,11 +418,14 @@ namespace TUGraz.VectoCore.OutputData
 			if (vehicleLoading != null && !vehicleLoading.IsEqual(0) && fcPer100lkm != null) {
                 //row[FCFINAL_LITERPER100TKM] = fcPer100lkm /
                 //							vehicleLoading.ConvertTo().Ton;
-			    row[FCFINAL_LITERPER100TKM] = fcPer100lkm /
-			                                  vehicleLoading.ConvertTo(Unit.SI.Ton);
+			    row[FCFINAL_LITERPER100TKM] = fcPer100lkm / vehicleLoading.ConvertTo(Unit.SI.Ton);
             }
 			if (cargoVolume > 0 && fcPer100lkm != null) {
 				row[FCFINAL_LiterPer100M3KM] = fcPer100lkm / cargoVolume;
+
+
+
+
 			}
 		}
 
-- 
GitLab