From 726533c46a10eed27ca4f9fbcdec1062383e557c Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Mon, 13 Nov 2017 13:56:08 +0100
Subject: [PATCH] make all testcases green

---
 VECTO.sln                                     |   54 +-
 VectoCommon/VectoCommon/Utils/SI.cs           | 3268 +++++++++--------
 .../Utils/SIConvertExtensionMethods.cs        |   81 +-
 VectoCommon/VectoCommon/Utils/SIUtils.cs      |  754 ++--
 .../OutputData/SummaryDataContainer.cs        |  105 +-
 .../Models/Simulation/AuxTests.cs             |    9 +
 .../Models/Simulation/PwheelModeTests.cs      |    8 +
 .../Models/Simulation/SimulationTests.cs      |    9 +
 .../VectoCoreTest/Reports/ModDataTest.cs      |   78 +-
 .../VectoCoreTest/Reports/SumWriterTest.cs    |    8 +-
 VectoCore/VectoCoreTest/Utils/SITest.cs       |   45 +-
 11 files changed, 2230 insertions(+), 2189 deletions(-)

diff --git a/VECTO.sln b/VECTO.sln
index d3fe7288cf..ec0fd339db 100644
--- a/VECTO.sln
+++ b/VECTO.sln
@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VECTO", "VECTO\VECTO.vbproj", "{AAC0F132-0A9F-45B3-B682-77AC9B24B352}"
 	ProjectSection(ProjectDependencies) = postProject
@@ -65,11 +65,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashingTool", "HashingTool\
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HashingCmd", "HashingCmd\HashingCmd.csproj", "{33F9848E-9257-4BE2-915F-68E748AEB204}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{B5A298FD-8117-4443-9419-66BADA094716}"
-	ProjectSection(SolutionItems) = preProject
-		.nuget\packages.config = .nuget\packages.config
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug PerformanceStats|Any CPU = Debug PerformanceStats|Any CPU
@@ -144,8 +139,8 @@ Global
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{FDEEE460-0B8A-4EF6-8D9E-72F203A50F65}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -172,8 +167,8 @@ Global
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -199,7 +194,6 @@ Global
 		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{6F31F8B2-6AB3-4F85-8AC9-D09ADCA6432D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -227,7 +221,6 @@ Global
 		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{6A27F93E-4A58-48F6-B00B-3908C5D3D5A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -273,8 +266,8 @@ Global
 		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{B4B9BD2F-FD8F-4BB8-82FA-E2154D2C7FBD}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -301,8 +294,8 @@ Global
 		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{60AD4DF0-6648-4374-83CB-C7A162EFB391}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -330,7 +323,6 @@ Global
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{6589CAEC-ECC9-4BCC-9699-DE3F22BBCBD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -358,7 +350,6 @@ Global
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{2320CD6F-FE7B-4341-A9BB-3ABCA7EF18F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -386,7 +377,6 @@ Global
 		{E8B0B447-1A54-4BEC-A160-AF0017000781}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{E8B0B447-1A54-4BEC-A160-AF0017000781}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{E8B0B447-1A54-4BEC-A160-AF0017000781}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{E8B0B447-1A54-4BEC-A160-AF0017000781}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -411,8 +401,8 @@ Global
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{79A066AD-69A9-4223-90F6-6ED5D2D084F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -485,7 +475,6 @@ Global
 		{D959CB7C-F514-4F5E-9C33-684D0012474B}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{D959CB7C-F514-4F5E-9C33-684D0012474B}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{D959CB7C-F514-4F5E-9C33-684D0012474B}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{D959CB7C-F514-4F5E-9C33-684D0012474B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -508,8 +497,8 @@ Global
 		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{41314A40-AB3E-4F43-B1A4-58443F4014F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -556,7 +545,6 @@ Global
 		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{2C58BA97-2954-4D19-920F-A24B78FC80A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -580,7 +568,6 @@ Global
 		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{7C364099-9B85-473A-8A42-BBEBE4798FF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -604,8 +591,8 @@ Global
 		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{B673E12F-D323-4C4C-8805-9915B2C72D3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -631,7 +618,6 @@ Global
 		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
 		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|Any CPU.Build.0 = Debug|Any CPU
 		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{760C1C5B-A767-463E-BA85-F0BCFC23A550}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -656,8 +642,8 @@ Global
 		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.ActiveCfg = Deploy|Any CPU
+		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|Any CPU.Build.0 = Deploy|Any CPU
 		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{E14FC935-30EA-4BE6-AA8A-85CB76FEBA6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -682,8 +668,8 @@ Global
 		{33F9848E-9257-4BE2-915F-68E748AEB204}.DebugTUG|Any CPU.Build.0 = Debug|Any CPU
 		{33F9848E-9257-4BE2-915F-68E748AEB204}.DebugTUG|x64.ActiveCfg = Debug|Any CPU
 		{33F9848E-9257-4BE2-915F-68E748AEB204}.DebugTUG|x86.ActiveCfg = Debug|Any CPU
-		{33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.ActiveCfg = Debug|Any CPU
-		{33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.Build.0 = Debug|Any CPU
+		{33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.ActiveCfg = Release|Any CPU
+		{33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|Any CPU.Build.0 = Release|Any CPU
 		{33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|x64.ActiveCfg = Debug|Any CPU
 		{33F9848E-9257-4BE2-915F-68E748AEB204}.Deploy|x86.ActiveCfg = Debug|Any CPU
 		{33F9848E-9257-4BE2-915F-68E748AEB204}.Release|Any CPU.ActiveCfg = Release|Any CPU
diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs
index 4f2186ef0c..ca229ce4c5 100644
--- a/VectoCommon/VectoCommon/Utils/SI.cs
+++ b/VectoCommon/VectoCommon/Utils/SI.cs
@@ -1,1623 +1,1647 @@
-/*
-* This file is part of VECTO.
-*
-* Copyright © 2012-2017 European Union
-*
-* Developed by Graz University of Technology,
-*              Institute of Internal Combustion Engines and Thermodynamics,
-*              Institute of Technical Informatics
-*
-* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
-* by the European Commission - subsequent versions of the EUPL (the "Licence");
-* You may not use VECTO except in compliance with the Licence.
-* You may obtain a copy of the Licence at:
-*
-* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
-*
-* Unless required by applicable law or agreed to in writing, VECTO
-* distributed under the Licence is distributed on an "AS IS" basis,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Licence for the specific language governing permissions and
-* limitations under the Licence.
-*
-* Authors:
-*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
-*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
-*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
-*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
-*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
-*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using TUGraz.VectoCommon.Exceptions;
-
-// ReSharper disable ClassNeverInstantiated.Global
-
-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) { }
-
-        [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) { }
-
-        /// <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;
-
-            return other != null && Val.Equals(other.Val) && HasEqualUnit(other);
-        }
-
-        /// <summary>
-        /// Determines whether the specified si is equal.
-        /// </summary>
-        /// <param name="si">The si.</param>
-        /// <param name="tolerance">The tolerance.</param>
-        /// <returns></returns>
-        public bool IsEqual(SI si, SI tolerance = null)
-        {
-            return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) &&
-                   Val.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)
-        {
-            return Val.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);
-            }
-
-            return Val.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);
-            }
-
-            return Val.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);
-            }
-
-            return Val.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);
-            }
-
-            return Val.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);
-            }
-
-            return Val.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);
-            }
-
-            return Val.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)) {
-                var sum1 = 0;
-                var sum2 = 0;
-                for (var i = 0; i < _units.Length; i++) {
-                    sum1 = Math.Abs(si._units[i]);
-                    sum2 = Math.Abs(_units[i]);
-                }
-                return sum1 >= sum2 ? 1 : -1;
-            }
-
-            if (this > si) {
-                return 1;
-            }
-
-            if (this < si) {
-                return -1;
-            }
-
-            return 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 y != null && x != null && x.IsEqual(y.Value(), _precision);
-            }
-
-            public int GetHashCode(T obj)
-            {
-                return obj.Value().GetHashCode();
-            }
-        }
-    }
+/*
+* This file is part of VECTO.
+*
+* Copyright © 2012-2017 European Union
+*
+* Developed by Graz University of Technology,
+*              Institute of Internal Combustion Engines and Thermodynamics,
+*              Institute of Technical Informatics
+*
+* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved
+* by the European Commission - subsequent versions of the EUPL (the "Licence");
+* You may not use VECTO except in compliance with the Licence.
+* You may obtain a copy of the Licence at:
+*
+* https://joinup.ec.europa.eu/community/eupl/og_page/eupl
+*
+* Unless required by applicable law or agreed to in writing, VECTO
+* distributed under the Licence is distributed on an "AS IS" basis,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the Licence for the specific language governing permissions and
+* limitations under the Licence.
+*
+* Authors:
+*   Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology
+*   Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology
+*   Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology
+*   Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology
+*   Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology
+*   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using TUGraz.VectoCommon.Exceptions;
+
+// ReSharper disable ClassNeverInstantiated.Global
+
+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) { }
+
+		[DebuggerHidden]
+		public static Liter operator *(LiterPerSecond l, Second second)
+		{
+			return SIBase<Liter>.Create(l.Val * second.Value());
+		}
+
+		[DebuggerHidden]
+		public static Liter operator *(Second second, LiterPerSecond l)
+		{
+			return SIBase<Liter>.Create(l.Val * second.Value());
+		}
+	}
+
+    /// <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 CubicMeter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter)
+        {
+            return SIBase<CubicMeter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value());
+        }
+    }
+
+    public class Liter : SIBase<Liter>
+    {
+        private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
+
+        [DebuggerHidden]
+        //[DebuggerHidden]
+        private Liter(double val) : base(val , 0.001, Units) { }
+
+        public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter)
+        {
+            return SIBase<Kilogram>.Create(liter.AsBasicUnit * 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);
+        }
+
+		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());
+        }
+
+    }
+
+    /// <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) { }
+
+		protected SIBase(double value, double unitFactor, int[] units) : base(value, unitFactor, 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;
+
+		private double UnitFactor;
+
+		/// <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="unitFactor"></param>
+		/// <param name="units">The units.</param>
+		protected SI(double val, double unitFactor, int[] units)
+        {
+            Val = val;
+            _units = units;
+			UnitFactor = unitFactor;
+
+            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());
+            }
+        }
+
+		protected SI(double val, int[] units) : this(val, 1, units) { }
+
+
+		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.UnitFactor,unit._units) { }
+
+        /// <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 zero = SIBase<T>.Create(0);
+            var t = SIBase<T>.Create(si.Val / zero.UnitFactor);
+            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 * UnitFactor, _units);
+        }
+
+		protected double AsBasicUnit
+		{
+			get { return Val * UnitFactor; }
+		}
+
+
+        /// <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.AsBasicUnit * si2.AsBasicUnit, 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.AsBasicUnit / si2.AsBasicUnit;
+
+                // 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.AsBasicUnit, 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.AsBasicUnit < si2.AsBasicUnit;
+        }
+
+        [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.AsBasicUnit > si2.AsBasicUnit;
+        }
+
+        [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.AsBasicUnit <= si2.AsBasicUnit;
+        }
+
+        [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.AsBasicUnit >= si2.AsBasicUnit;
+        }
+
+        [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;
+
+            return other != null && AsBasicUnit.Equals(other.AsBasicUnit) && 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)
+        {
+            return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) &&
+                   AsBasicUnit.IsEqual(si.AsBasicUnit, 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)
+        {
+            return Val.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);
+            }
+
+            return AsBasicUnit.IsSmaller(si.AsBasicUnit, 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);
+            }
+
+            return Val.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);
+            }
+
+            return AsBasicUnit.IsSmallerOrEqual(si.AsBasicUnit, 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);
+            }
+
+            return AsBasicUnit.IsGreater(si.AsBasicUnit, 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);
+            }
+
+            return Val.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);
+            }
+
+            return AsBasicUnit.IsGreaterOrEqual(si.AsBasicUnit, 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)) {
+				// TODO: thow exception!
+                var sum1 = 0;
+                var sum2 = 0;
+                for (var i = 0; i < _units.Length; i++) {
+                    sum1 += Math.Abs(si._units[i]);
+                    sum2 += Math.Abs(_units[i]);
+                }
+                return sum1 >= sum2 ? -1 : 1;
+            }
+
+            if (this > si) {
+                return 1;
+            }
+
+            if (this < si) {
+                return -1;
+            }
+
+            return 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 y != null && x != null && x.IsEqual(y.Value(), _precision);
+            }
+
+            public int GetHashCode(T obj)
+            {
+                return obj.Value().GetHashCode();
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs b/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs
index c359576129..a4b749e7a0 100644
--- a/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs
+++ b/VectoCommon/VectoCommon/Utils/SIConvertExtensionMethods.cs
@@ -14,14 +14,37 @@ namespace TUGraz.VectoCommon.Utils
             _units = units;
         }
 
-        public static implicit operator double(ConvertedSI self)
+		protected bool Equals(ConvertedSI other)
+		{
+			return _value.Equals(other._value) && string.Equals(_units, other._units);
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (ReferenceEquals(null, obj))
+				return false;
+			if (ReferenceEquals(this, obj))
+				return true;
+			if (obj.GetType() != this.GetType())
+				return false;
+			return Equals((ConvertedSI)obj);
+		}
+
+		public override int GetHashCode()
+		{
+			unchecked {
+				return (_value.GetHashCode() * 397) ^ (_units != null ? _units.GetHashCode() : 0);
+			}
+		}
+
+		public static implicit operator double(ConvertedSI self)
         {
             return self._value;
         }
 
         public static implicit operator ConvertedSI(SI self)
         {
-            return new ConvertedSI(self.Value(), self.GetUnitString());
+            return self == null ? null : new ConvertedSI(self.Value(), self.GetUnitString());
         }
 
         public override string ToString()
@@ -41,94 +64,92 @@ namespace TUGraz.VectoCommon.Utils
         private const int Kilo = 1000;
         private const int SecondsPerHour = 60 * 60;
         
-        public static ConvertedSI ConvertToGramm(this SI value)
+        public static ConvertedSI ConvertToGramm(this Kilogram value)
         {
             return new ConvertedSI(value.Value() * Kilo, "g");
         }
-        public static ConvertedSI ConvertToTon(this SI value)
+        public static ConvertedSI ConvertToTon(this Kilogram value)
         {
-            return new ConvertedSI(value.Value() * Kilo, "Ton");
+            return new ConvertedSI(value.Value() / Kilo, "Ton");
         }
-        public static ConvertedSI ConvertToKiloMeterPerHour(this SI value)
+        public static ConvertedSI ConvertToKiloMeterPerHour(this MeterPerSecond value)
         {
             return new ConvertedSI(value.Value() * SecondsPerHour / Kilo, "km/h");
         }
-        public static ConvertedSI ConvertToGrammPerKiloMeter(this SI value)
+        public static ConvertedSI ConvertToGrammPerKiloMeter(this KilogramPerMeter value)
         {
-            return value == null ? null : new ConvertedSI(value.Value() * Kilo / Kilo, "g/km");
+            return value == null ? null : new ConvertedSI(value.Value() * Kilo * Kilo, "g/km");
         }
 
         public static ConvertedSI ConvertToLiterPer100Kilometer(this SI value)
         {
-            return new ConvertedSI(value.Value() * (10*10*10) / (100*1000), "l/100km");
+            return value == null ? null : new ConvertedSI(value.Value() * (10*10*10) / (100*1000), "l/100km");
         }
         
         public static ConvertedSI ConvertToLiterPer100TonKiloMeter(this SI value)
         {
             const int CubicMeterToLiter = 10 * 10 * 10;
-            const int MeterTo100KiloMeter = 100 * 1000;
-            const int KilogrammToTon = 1000;
-            return new ConvertedSI(value.Value() * CubicMeterToLiter / (MeterTo100KiloMeter * KilogrammToTon), "l/100tkm");
-        }
+            const int MeterTo100KiloMeter = 100 * Kilo;
+            const int KilogrammToTon = Kilo;
 
+            return value == null ? null  : new ConvertedSI(value.Value() * CubicMeterToLiter / (MeterTo100KiloMeter * KilogrammToTon), "l/100tkm");
+        }
 
-        
-        public static ConvertedSI ConvertToLiterPerCubicMeter100KiloMeter(this SI value)
+		public static ConvertedSI ConvertToLiterPerCubicMeter100KiloMeter(this SI value)
         {
             const int CubicMeterToLiter = 10 * 10 * 10;
-            const int MeterTo100KiloMeter = 100 * 1000;
+            const int MeterTo100KiloMeter = 100 * Kilo;
             return new ConvertedSI(value.Value() * CubicMeterToLiter / MeterTo100KiloMeter, "l/100m^3km");
         }
 
-        public static ConvertedSI ConvertToGrammPerHour(this SI value)
+        public static ConvertedSI ConvertToGrammPerHour(this KilogramPerSecond value)
         {
-            return new ConvertedSI(value.Value() * Kilo / SecondsPerHour, "g/h");
+            return new ConvertedSI(value.Value() * Kilo * SecondsPerHour, "g/h");
         }
 
-        public static ConvertedSI ConvertToKiloMeter(this SI value)
+        public static ConvertedSI ConvertToKiloMeter(this Meter value)
         {
-            return new ConvertedSI(value.Value() / Kilo, "km");
+            return new ConvertedSI(value.Value() / Kilo, "km");	
         }
 
-        public static ConvertedSI ConvertToCubicCentiMeter(this SI value)
+        public static ConvertedSI ConvertToCubicCentiMeter(this CubicMeter value)
         {
             return new ConvertedSI(value.Value() * 100 * 100 * 100, "cm^3");
         }
 
         public static ConvertedSI ConvertToGrammPerCubicMeterKiloMeter(this SI value)
         {
-            return new ConvertedSI(value.Value() * Kilo / Kilo * Kilo / Kilo / Kilo / Kilo, "g/m^3km");
+            return new ConvertedSI(value.Value()  * Kilo * Kilo, "g/m^3km");
         }
 
         public static ConvertedSI ConvertToGrammPerTonKilometer(this SI value)
         {
-            return new ConvertedSI(value.Value() * Kilo / Kilo * Kilo, "g/tkm");
+            return new ConvertedSI(value.Value() * Kilo * Kilo * Kilo, "g/tkm");
         }
-
-
+		
         public static ConvertedSI ConvertToLiterPer100KiloMeter(this SI value)
         {
             return new ConvertedSI(value.Value() * 10 * 10 * 10 * 100 * Kilo, "l/100km");
         }
 
-        public static ConvertedSI ConvertToKiloWattHour(this SI value)
+        public static ConvertedSI ConvertToKiloWattHour(this WattSecond value)
         {
             return new ConvertedSI(value.Value() / Kilo / SecondsPerHour, "kWh");
         }
-        public static ConvertedSI ConvertToKiloWatt(this SI value)
+        public static ConvertedSI ConvertToKiloWatt(this Watt value)
         {
             return new ConvertedSI(value.Value() / Kilo, "kW");
         }
 
-        public static ConvertedSI ConvertToRoundsPerMinute(this SI value)
+        public static ConvertedSI ConvertToRoundsPerMinute(this PerSecond value)
         {
             return new ConvertedSI(value.Value() * 2 * Math.PI / 60, "rpm");
         }
-        public static ConvertedSI ConvertToCubicDeziMeter(this SI value)
+        public static ConvertedSI ConvertToCubicDeziMeter(this CubicMeter value)
         {
             return new ConvertedSI(value.Value() * 10 * 10 * 10, "dm^3");
         }
-        public static ConvertedSI ConvertToMilliMeter(this SI value)
+        public static ConvertedSI ConvertToMilliMeter(this Meter value)
         {
             return new ConvertedSI(value.Value() * Kilo, "mm");
         }
diff --git a/VectoCommon/VectoCommon/Utils/SIUtils.cs b/VectoCommon/VectoCommon/Utils/SIUtils.cs
index fa0e23b123..7cd4d30dcb 100644
--- a/VectoCommon/VectoCommon/Utils/SIUtils.cs
+++ b/VectoCommon/VectoCommon/Utils/SIUtils.cs
@@ -2,394 +2,366 @@
 
 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)
-        {
-            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;
-            }
-        }
-    }
-}
+	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;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
index 3453cecea0..bff31b0912 100644
--- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
@@ -213,15 +213,15 @@ namespace TUGraz.VectoCore.OutputData
 				Tuple.Create(VIN_NUMBER, typeof(string)),
 				Tuple.Create(VEHICLE_MODEL, typeof(string)),
 				Tuple.Create(HDV_CO2_VEHICLE_CLASS, typeof(string)),
-				Tuple.Create(CURB_MASS, typeof(SI)),
-				Tuple.Create(LOADING, typeof(SI)),
-				Tuple.Create(TOTAL_VEHICLE_MASS, typeof(SI)),
+				Tuple.Create(CURB_MASS, typeof(ConvertedSI)),
+				Tuple.Create(LOADING, typeof(ConvertedSI)),
+				Tuple.Create(TOTAL_VEHICLE_MASS, typeof(ConvertedSI)),
 				Tuple.Create(ENGINE_MANUFACTURER, typeof(string)),
 				Tuple.Create(ENGINE_MODEL, typeof(string)),
 				Tuple.Create(ENGINE_FUEL_TYPE, typeof(string)),
                 Tuple.Create(ENGINE_RATED_POWER, typeof(ConvertedSI)),
-				Tuple.Create(ENGINE_IDLING_SPEED, typeof(SI)),
-				Tuple.Create(ENGINE_RATED_SPEED, typeof(SI)),
+				Tuple.Create(ENGINE_IDLING_SPEED, typeof(ConvertedSI)),
+				Tuple.Create(ENGINE_RATED_SPEED, typeof(ConvertedSI)),
                 Tuple.Create(ENGINE_DISPLACEMENT, typeof(ConvertedSI)),
 				Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)),
 				Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)),
@@ -229,19 +229,19 @@ namespace TUGraz.VectoCore.OutputData
 				Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)),
 				Tuple.Create(ENGINE_CF_REG_PER, typeof(double)),
 				Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)),
-				Tuple.Create(CD_x_A_DECLARED, typeof(SI)),
-				Tuple.Create(CD_x_A, typeof(SI)),
+				Tuple.Create(CD_x_A_DECLARED, typeof(ConvertedSI)),
+				Tuple.Create(CD_x_A, typeof(ConvertedSI)),
 				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)),
 				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)),
-				Tuple.Create(R_DYN, typeof(SI)),
+				Tuple.Create(R_DYN, typeof(ConvertedSI)),
 				Tuple.Create(NUM_AXLES_DRIVEN, typeof(int)),
 				Tuple.Create(NUM_AXLES_NON_DRIVEN, typeof(int)),
 				Tuple.Create(NUM_AXLES_TRAILER, typeof(int)),
 				Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)),
 				Tuple.Create(GEARBOX_MODEL, typeof(string)),
 				Tuple.Create(GEARBOX_TYPE, typeof(string)),
-				Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(SI)),
-				Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(SI)),
+				Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(ConvertedSI)),
+				Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(ConvertedSI)),
 				Tuple.Create(TORQUECONVERTER_MANUFACTURER, typeof(string)),
 				Tuple.Create(TORQUECONVERTER_MODEL, typeof(string)),
 				Tuple.Create(RETARDER_MANUFACTURER, typeof(string)),
@@ -252,7 +252,7 @@ namespace TUGraz.VectoCore.OutputData
 				Tuple.Create(ANGLEDRIVE_RATIO, typeof(string)),
 				Tuple.Create(AXLE_MANUFACTURER, typeof(string)),
 				Tuple.Create(AXLE_MODEL, typeof(string)),
-				Tuple.Create(AXLE_RATIO, typeof(SI)),
+				Tuple.Create(AXLE_RATIO, typeof(ConvertedSI)),
 				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.SteeringPump), typeof(string)),
 				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.Fan), typeof(string)),
 				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition),
@@ -279,7 +279,7 @@ namespace TUGraz.VectoCore.OutputData
 				ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE,
 				MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS,
 				STOP_TIMESHARE, ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE
-            }.Select(x => new DataColumn(x)).ToArray());
+            }.Select(x => new DataColumn(x, typeof(ConvertedSI))).ToArray());
 		}
 
 		/// <summary>
@@ -328,7 +328,7 @@ namespace TUGraz.VectoCore.OutputData
 
 
 			var totalTime = modData.Duration();
-			row[TIME] = totalTime;
+			row[TIME] = (ConvertedSI)totalTime;
 
 			var distance = modData.Distance();
 			if (distance != null) {
@@ -340,7 +340,7 @@ namespace TUGraz.VectoCore.OutputData
                 row[SPEED] = speed.ConvertToKiloMeterPerHour();
 			}
 
-			row[ALTITUDE_DELTA] = modData.AltitudeDelta();
+			row[ALTITUDE_DELTA] = (ConvertedSI)modData.AltitudeDelta();
 
 			WriteFuelconsumptionEntries(modData, row, vehicleLoading, cargoVolume);
 
@@ -365,9 +365,9 @@ namespace TUGraz.VectoCore.OutputData
 
 			WritePerformanceEntries(modData, row);
 
-			row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare();
-			row[COASTING_TIME_SHARE] = modData.CoastingTimeShare();
-			row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare();
+			row[ENGINE_FULL_LOAD_TIME_SHARE] = (ConvertedSI)modData.EngineMaxLoadTimeShare();
+			row[COASTING_TIME_SHARE] = (ConvertedSI)modData.CoastingTimeShare();
+			row[BRAKING_TIME_SHARE] = (ConvertedSI)modData.BrakingTimeShare();
 
 			if (gearCount <= 0) {
 				return;
@@ -379,7 +379,8 @@ namespace TUGraz.VectoCore.OutputData
 		private static void WriteFuelconsumptionEntries(IModalDataContainer modData, DataRow row, Kilogram vehicleLoading,
 			CubicMeter cargoVolume)
 		{
-            row[FCMAP_H] = modData.FCMapPerSecond().ConvertToGrammPerHour();
+			var tmp = modData.FCMapPerSecond();
+			row[FCMAP_H] = tmp.ConvertToGrammPerHour();
 			var fcMapPerMeter = modData.FCMapPerMeter();
 			if (fcMapPerMeter != null) {
                 row[FCMAP_KM] = fcMapPerMeter.ConvertToGrammPerKiloMeter();
@@ -434,37 +435,37 @@ namespace TUGraz.VectoCore.OutputData
 
 		private void WriteGearshiftStats(IModalDataContainer modData, DataRow row, uint gearCount)
 		{
-			row[NUM_GEARSHIFTS] = modData.GearshiftCount();
+			row[NUM_GEARSHIFTS] = (ConvertedSI)modData.GearshiftCount();
 			var timeSharePerGear = modData.TimeSharePerGear(gearCount);
 
 			for (uint i = 0; i <= gearCount; i++) {
 				var colName = string.Format(TIME_SHARE_PER_GEAR_FORMAT, i);
 				if (!Table.Columns.Contains(colName)) {
-					Table.Columns.Add(colName, typeof(SI));
+					Table.Columns.Add(colName, typeof(ConvertedSI));
 				}
-				row[colName] = timeSharePerGear[i];
+				row[colName] = (ConvertedSI)timeSharePerGear[i];
 			}
 		}
 
 		private void WritePerformanceEntries(IModalDataContainer modData, DataRow row)
 		{
-			row[ACC] = modData.AccelerationAverage();
-			row[ACC_POS] = modData.AccelerationsPositive();
-			row[ACC_NEG] = modData.AccelerationsNegative();
+			row[ACC] = (ConvertedSI)modData.AccelerationAverage();
+			row[ACC_POS] = (ConvertedSI)modData.AccelerationsPositive();
+			row[ACC_NEG] = (ConvertedSI)modData.AccelerationsNegative();
 			var accTimeShare = modData.AccelerationTimeShare();
-			row[ACC_TIMESHARE] = accTimeShare;
+			row[ACC_TIMESHARE] = (ConvertedSI)accTimeShare;
 			var decTimeShare = modData.DecelerationTimeShare();
-			row[DEC_TIMESHARE] = decTimeShare;
+			row[DEC_TIMESHARE] = (ConvertedSI)decTimeShare;
 			var cruiseTimeShare = modData.CruiseTimeShare();
-			row[CRUISE_TIMESHARE] = cruiseTimeShare;
+			row[CRUISE_TIMESHARE] = (ConvertedSI)cruiseTimeShare;
 			var stopTimeShare = modData.StopTimeShare();
-			row[STOP_TIMESHARE] = stopTimeShare;
+			row[STOP_TIMESHARE] = (ConvertedSI)stopTimeShare;
 
-			row[MAX_SPEED] = modData.MaxSpeed().AsKmph.SI<Scalar>();
-			row[MAX_ACCELERATION] = modData.MaxAcceleration();
-			row[MAX_DECELERATION] = modData.MaxDeceleration();
-			row[AVG_ENGINE_SPEED] = modData.AvgEngineSpeed().AsRPM.SI<Scalar>();
-			row[MAX_ENGINE_SPEED] = modData.MaxEngineSpeed().AsRPM.SI<Scalar>();
+			row[MAX_SPEED] = (ConvertedSI)modData.MaxSpeed().AsKmph.SI<Scalar>();
+			row[MAX_ACCELERATION] = (ConvertedSI)modData.MaxAcceleration();
+			row[MAX_DECELERATION] = (ConvertedSI)modData.MaxDeceleration();
+			row[AVG_ENGINE_SPEED] = (ConvertedSI)modData.AvgEngineSpeed().AsRPM.SI<Scalar>();
+			row[MAX_ENGINE_SPEED] = (ConvertedSI)modData.MaxEngineSpeed().AsRPM.SI<Scalar>();
 			if (accTimeShare != null && decTimeShare != null && cruiseTimeShare != null) {
 				var shareSum = accTimeShare + decTimeShare + cruiseTimeShare + stopTimeShare;
 				if (!shareSum.IsEqual(100)) {
@@ -504,22 +505,22 @@ namespace TUGraz.VectoCore.OutputData
 			row[VEHICLE_MODEL] = runData.VehicleData.ModelName;
 
 			row[HDV_CO2_VEHICLE_CLASS] = runData.VehicleData.VehicleClass.GetClassNumber();
-			row[CURB_MASS] = runData.VehicleData.CurbWeight;
+			row[CURB_MASS] = (ConvertedSI)runData.VehicleData.CurbWeight;
 			// - (runData.VehicleData.BodyAndTrailerWeight ?? 0.SI<Kilogram>());
-			row[LOADING] = runData.VehicleData.Loading;
-			row[CARGO_VOLUME] = runData.VehicleData.CargoVolume;
+			row[LOADING] = (ConvertedSI)runData.VehicleData.Loading;
+			row[CARGO_VOLUME] = (ConvertedSI)runData.VehicleData.CargoVolume;
 
-			row[TOTAL_VEHICLE_MASS] = runData.VehicleData.TotalVehicleWeight;
+			row[TOTAL_VEHICLE_MASS] = (ConvertedSI)runData.VehicleData.TotalVehicleWeight;
 			row[ENGINE_MANUFACTURER] = runData.EngineData.Manufacturer;
 			row[ENGINE_MODEL] = runData.EngineData.ModelName;
 			row[ENGINE_FUEL_TYPE] = runData.EngineData.FuelType.GetLabel();
 			row[ENGINE_RATED_POWER] = runData.EngineData.RatedPowerDeclared != null && runData.EngineData.RatedPowerDeclared > 0
                 ? runData.EngineData.RatedPowerDeclared.ConvertToKiloWatt()
                 : runData.EngineData.FullLoadCurves[0].MaxPower.ConvertToKiloWatt();
-			row[ENGINE_IDLING_SPEED] = runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>();
+			row[ENGINE_IDLING_SPEED] = (ConvertedSI)runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>();
 			row[ENGINE_RATED_SPEED] = runData.EngineData.RatedSpeedDeclared != null && runData.EngineData.RatedSpeedDeclared > 0
-				? runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>()
-				: runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>();
+				? (ConvertedSI)runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>()
+				: (ConvertedSI)runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>();
             row[ENGINE_DISPLACEMENT] = runData.EngineData.Displacement.ConvertToCubicCentiMeter();
 
 			row[ENGINE_WHTC_URBAN] = runData.EngineData.WHTCUrban;
@@ -529,15 +530,15 @@ namespace TUGraz.VectoCore.OutputData
 			row[ENGINE_CF_REG_PER] = runData.EngineData.CorrectionFactorRegPer;
 			row[ENGINE_ACTUAL_CORRECTION_FACTOR] = runData.EngineData.FuelConsumptionCorrectionFactor;
 
-			row[CD_x_A_DECLARED] = runData.AirdragData.DeclaredAirdragArea;
-			row[CD_x_A] = runData.AirdragData.CrossWindCorrectionCurve.AirDragArea;
+			row[CD_x_A_DECLARED] = (ConvertedSI)runData.AirdragData.DeclaredAirdragArea;
+			row[CD_x_A] = (ConvertedSI)runData.AirdragData.CrossWindCorrectionCurve.AirDragArea;
 
 			row[ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER] =
 				runData.VehicleData.RollResistanceCoefficientWithoutTrailer;
 			row[ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER] =
 				runData.VehicleData.TotalRollResistanceCoefficient;
 
-			row[R_DYN] = runData.VehicleData.DynamicTyreRadius;
+			row[R_DYN] = (ConvertedSI)runData.VehicleData.DynamicTyreRadius;
 
 			row[NUM_AXLES_DRIVEN] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.VehicleDriven);
 			row[NUM_AXLES_NON_DRIVEN] = runData.VehicleData.AxleData.Count(x => x.AxleType == AxleType.VehicleNonDriven);
@@ -555,7 +556,7 @@ namespace TUGraz.VectoCore.OutputData
 
 			row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer;
 			row[AXLE_MODEL] = runData.AxleGearData.ModelName;
-			row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>();
+			row[AXLE_RATIO] = (ConvertedSI)runData.AxleGearData.AxleGear.Ratio.SI<Scalar>();
 
 			WriteAuxTechnologies(runData, row);
 		}
@@ -607,21 +608,21 @@ namespace TUGraz.VectoCore.OutputData
 			if (runData.GearboxData.Type.AutomaticTransmission()) {
 				row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
 					? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio)
-						? runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>()
-						: runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>())
+						? (ConvertedSI)runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>()
+						: (ConvertedSI)runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>())
 					: 0.SI<Scalar>();
 				row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0
-					? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
-					: 0.SI<Scalar>();
+					? (ConvertedSI)runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
+					: (ConvertedSI)0.SI<Scalar>();
 				row[TORQUECONVERTER_MANUFACTURER] = runData.GearboxData.TorqueConverterData.Manufacturer;
 				row[TORQUECONVERTER_MODEL] = runData.GearboxData.TorqueConverterData.ModelName;
 			} else {
 				row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
-					? runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()
-					: 0.SI<Scalar>();
+					? (ConvertedSI)runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()
+					: (ConvertedSI)0.SI<Scalar>();
 				row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0
-					? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
-					: 0.SI<Scalar>();
+					? (ConvertedSI)runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
+					: (ConvertedSI)0.SI<Scalar>();
 				row[TORQUECONVERTER_MANUFACTURER] = "n.a.";
 				row[TORQUECONVERTER_MODEL] = "n.a.";
 			}
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs
index e4e0424d43..3ada562901 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/AuxTests.cs
@@ -30,6 +30,7 @@
 */
 
 using System.Collections.Generic;
+using System.IO;
 using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
@@ -56,6 +57,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 	[TestFixture]
 	public class AuxTests
 	{
+
+		[OneTimeSetUp]
+		public void RunBeforeAnyTests()
+		{
+			Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
+		}
+
+
 		[TestCase]
 		public void AuxWriteModFileSumFile()
 
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs
index ac977d06fe..74e110abf6 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/PwheelModeTests.cs
@@ -54,6 +54,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 	[TestFixture]
 	public class PwheelModeTests
 	{
+
+		[OneTimeSetUp]
+		public void RunBeforeAnyTests()
+		{
+			Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
+		}
+
+
 		/// <summary>
 		/// Test if the cycle file can be read.
 		/// </summary>
diff --git a/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs b/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs
index 196fdd8733..858bd32ff7 100644
--- a/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs
+++ b/VectoCore/VectoCoreTest/Models/Simulation/SimulationTests.cs
@@ -29,6 +29,7 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
+using System.IO;
 using System.Linq;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Utils;
@@ -47,6 +48,14 @@ namespace TUGraz.VectoCore.Tests.Models.Simulation
 	{
 		private const string EngineOnlyJob = @"TestData\Jobs\EngineOnlyJob.vecto";
 
+
+		[OneTimeSetUp]
+		public void RunBeforeAnyTests()
+		{
+			Directory.SetCurrentDirectory(TestContext.CurrentContext.TestDirectory);
+		}
+
+
 		[TestCase]
 		public void TestSimulationEngineOnly()
 		{
diff --git a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs
index 5b9852f05c..27ca18ea03 100644
--- a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs
+++ b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs
@@ -156,36 +156,36 @@ namespace TUGraz.VectoCore.Tests.Reports
 				var inputFile = row[SummaryDataContainer.INPUTFILE].ToString();
 				var cycle = row[SummaryDataContainer.CYCLE].ToString();
 				var loading = row[SummaryDataContainer.LOADING].ToString();
-				var eFcMapPos = ((SI)row[SummaryDataContainer.E_FCMAP_POS]).Value();
-				var eFcMapNeg = ((SI)row[SummaryDataContainer.E_FCMAP_NEG]).Value();
-				var ePowertrainInertia = ((SI)row[SummaryDataContainer.E_POWERTRAIN_INERTIA]).Value();
-				var eAux = ((SI)row[SummaryDataContainer.E_AUX]).Value();
-				var eClutchLoss = ((SI)row[SummaryDataContainer.E_CLUTCH_LOSS]).Value();
-				var eTcLoss = ((SI)row[SummaryDataContainer.E_TC_LOSS]).Value();
-				//var eShiftLoss = ((SI)row[SummaryDataContainer.E_SHIFT_LOSS]).Value();
-				var eGbxLoss = ((SI)row[SummaryDataContainer.E_GBX_LOSS]).Value();
-				var eRetLoss = ((SI)row[SummaryDataContainer.E_RET_LOSS]).Value();
-				var eAngleLoss = ((SI)row[SummaryDataContainer.E_ANGLE_LOSS]).Value();
-				var eAxlLoss = ((SI)row[SummaryDataContainer.E_AXL_LOSS]).Value();
-				var eBrakeLoss = ((SI)row[SummaryDataContainer.E_BRAKE]).Value();
-				var eVehInertia = ((SI)row[SummaryDataContainer.E_VEHICLE_INERTIA]).Value();
-				var eAir = ((SI)row[SummaryDataContainer.E_AIR]).Value();
-				var eRoll = ((SI)row[SummaryDataContainer.E_ROLL]).Value();
-				var eGrad = ((SI)row[SummaryDataContainer.E_GRAD]).Value();
-				var cargoVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CARGO_VOLUME]).Value();
-
-				var loadingValue = ((SI)row[SummaryDataContainer.LOADING]).Value() / 1000;
-				var fcPer100km = ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]).Value();
+				var eFcMapPos = ((ConvertedSI)row[SummaryDataContainer.E_FCMAP_POS]);
+				var eFcMapNeg = ((ConvertedSI)row[SummaryDataContainer.E_FCMAP_NEG]);
+				var ePowertrainInertia = ((ConvertedSI)row[SummaryDataContainer.E_POWERTRAIN_INERTIA]);
+				var eAux = ((ConvertedSI)row[SummaryDataContainer.E_AUX]);
+				var eClutchLoss = ((ConvertedSI)row[SummaryDataContainer.E_CLUTCH_LOSS]);
+				var eTcLoss = ((ConvertedSI)row[SummaryDataContainer.E_TC_LOSS]);
+				//var eShiftLoss = ((SI)row[SummaryDataContainer.E_SHIFT_LOSS]);
+				var eGbxLoss = ((ConvertedSI)row[SummaryDataContainer.E_GBX_LOSS]);
+				var eRetLoss = ((ConvertedSI)row[SummaryDataContainer.E_RET_LOSS]);
+				var eAngleLoss = ((ConvertedSI)row[SummaryDataContainer.E_ANGLE_LOSS]);
+				var eAxlLoss = ((ConvertedSI)row[SummaryDataContainer.E_AXL_LOSS]);
+				var eBrakeLoss = ((ConvertedSI)row[SummaryDataContainer.E_BRAKE]);
+				var eVehInertia = ((ConvertedSI)row[SummaryDataContainer.E_VEHICLE_INERTIA]);
+				var eAir = ((ConvertedSI)row[SummaryDataContainer.E_AIR]);
+				var eRoll = ((ConvertedSI)row[SummaryDataContainer.E_ROLL]);
+				var eGrad = ((ConvertedSI)row[SummaryDataContainer.E_GRAD]);
+				var cargoVolume = mode == ExecutionMode.Engineering ? 0.0 : ((ConvertedSI)row[SummaryDataContainer.CARGO_VOLUME]);
+
+				var loadingValue = ((ConvertedSI)row[SummaryDataContainer.LOADING]) / 1000;
+				var fcPer100km = ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]);
 				var fcPerVolume = mode == ExecutionMode.Engineering
-					? 0
-					: ((SI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]).Value();
-				var fcPerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]).Value() : 0;
-				var co2Per100km = ((SI)row[SummaryDataContainer.CO2_KM]).Value();
-				var co2PerVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CO2_M3KM]).Value();
-				var co2PerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.CO2_TKM]).Value() : 0;
+					? 0.0
+					: ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]);
+				var fcPerLoad = loadingValue > 0 ? ((ConvertedSI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]) : 0.0;
+				var co2PerKm = ((ConvertedSI)row[SummaryDataContainer.CO2_KM]);
+				var co2PerVolume = mode == ExecutionMode.Engineering ? 0.0 : ((ConvertedSI)row[SummaryDataContainer.CO2_M3KM]);
+				var co2PerLoad = loadingValue > 0 ? ((ConvertedSI)row[SummaryDataContainer.CO2_TKM]) : 0.0;
 
-				var ePTOtransm = ptoTransmissionColumn != null ? ((SI)row[ptoTransmissionColumn]).Value() : 0;
-				var ePTOconsumer = ptoConsumerColumn != null ? ((SI)row[ptoConsumerColumn]).Value() : 0;
+				var ePTOtransm = ptoTransmissionColumn != null ? ((ConvertedSI)row[ptoTransmissionColumn]) : 0.0;
+				var ePTOconsumer = ptoConsumerColumn != null ? ((ConvertedSI)row[ptoConsumerColumn]) : 0.0;
 
 				// E_fcmap_pos = E_fcmap_neg + E_powertrain_inertia + E_aux_xxx + E_aux_sum + E_clutch_loss + E_tc_loss + E_gbx_loss + E_shift_loss + E_ret_loss + E_angle_loss + E_axl_loss + E_brake + E_vehicle_inertia + E_air + E_roll + E_grad + E_PTO_CONSUM + E_PTO_TRANSM
 				Assert.AreEqual(eFcMapPos,
@@ -194,8 +194,8 @@ namespace TUGraz.VectoCore.Tests.Reports
 					"input file: {0}  cycle: {1} loading: {2}",
 					inputFile, cycle, loading);
 
-				var pFcmapPos = ((SI)row[SummaryDataContainer.P_FCMAP_POS]).Value();
-				var time = ((SI)row[SummaryDataContainer.TIME]).Value();
+				var pFcmapPos = ((ConvertedSI)row[SummaryDataContainer.P_FCMAP_POS]);
+				var time = ((ConvertedSI)row[SummaryDataContainer.TIME]);
 
 				// E_fcmap_pos = P_fcmap_pos * t
 				Assert.AreEqual(eFcMapPos, pFcmapPos * (time / 3600), 1e-3, "input file: {0}  cycle: {1} loading: {2}", inputFile,
@@ -205,30 +205,30 @@ namespace TUGraz.VectoCore.Tests.Reports
 					Assert.AreEqual(fcPerVolume, fcPer100km / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}", inputFile,
 						cycle, loading);
 
-					Assert.AreEqual(co2PerVolume, co2Per100km / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
+					Assert.AreEqual(co2PerVolume, co2PerKm / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
 						inputFile,
 						cycle, loading);
 				}
 
 				if (loadingValue > 0) {
-					Assert.AreEqual(co2PerLoad, co2Per100km / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
+					Assert.AreEqual(co2PerLoad, co2PerKm / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
 						inputFile, cycle, loading);
 					Assert.AreEqual(fcPerLoad, fcPer100km / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
 						inputFile, cycle, loading);
 				}
 
-				var stopTimeShare = ((SI)row[SummaryDataContainer.STOP_TIMESHARE]).Value();
-				var accTimeShare = ((SI)row[SummaryDataContainer.ACC_TIMESHARE]).Value();
-				var decTimeShare = ((SI)row[SummaryDataContainer.DEC_TIMESHARE]).Value();
-				var cruiseTimeShare = ((SI)row[SummaryDataContainer.CRUISE_TIMESHARE]).Value();
+				var stopTimeShare = ((ConvertedSI)row[SummaryDataContainer.STOP_TIMESHARE]);
+				var accTimeShare = ((ConvertedSI)row[SummaryDataContainer.ACC_TIMESHARE]);
+				var decTimeShare = ((ConvertedSI)row[SummaryDataContainer.DEC_TIMESHARE]);
+				var cruiseTimeShare = ((ConvertedSI)row[SummaryDataContainer.CRUISE_TIMESHARE]);
 
 				Assert.AreEqual(100, stopTimeShare + accTimeShare + decTimeShare + cruiseTimeShare, 1e-3,
 					"input file: {0}  cycle: {1} loading: {2}", inputFile, cycle, loading);
 
-				Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_POS]).Value() > 0);
-				Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_NEG]).Value() < 0);
+				Assert.IsTrue(((ConvertedSI)row[SummaryDataContainer.ACC_POS]) > 0);
+				Assert.IsTrue(((ConvertedSI)row[SummaryDataContainer.ACC_NEG]) < 0);
 
-				var gearshifts = ((SI)row[SummaryDataContainer.NUM_GEARSHIFTS]).Value();
+				var gearshifts = ((ConvertedSI)row[SummaryDataContainer.NUM_GEARSHIFTS]);
 				Assert.IsTrue(gearshifts > 0);
 
 				//var acc = ((SI)row[SummaryDataContainer.ACC]).Value();
diff --git a/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs b/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs
index 5730cb9139..32689fe80a 100644
--- a/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs
+++ b/VectoCore/VectoCoreTest/Reports/SumWriterTest.cs
@@ -193,14 +193,14 @@ namespace TUGraz.VectoCore.Tests.Reports
 			Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.Manufacturer,
 				sumRow[SummaryDataContainer.ENGINE_MANUFACTURER]);
 			Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.Model, sumRow[SummaryDataContainer.ENGINE_MODEL]);
-            Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.RatedPowerDeclared.ConvertToKiloWatt(),
+            Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.FuelType.ToXMLFormat(),
 				sumRow[SummaryDataContainer.ENGINE_FUEL_TYPE]);
 			Assert.AreEqual((dataProvider.JobInputData.Vehicle.EngineInputData.RatedPowerDeclared.ConvertToKiloWatt()),
-				((SI)sumRow[SummaryDataContainer.ENGINE_RATED_POWER]).Value());
+				((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_RATED_POWER]));
 			Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.RatedSpeedDeclared.AsRPM,
-				((SI)sumRow[SummaryDataContainer.ENGINE_RATED_SPEED]).Value());
+				(double)((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_RATED_SPEED]));
             Assert.AreEqual(dataProvider.JobInputData.Vehicle.EngineInputData.Displacement.ConvertToCubicCentiMeter(),
-				((SI)sumRow[SummaryDataContainer.ENGINE_DISPLACEMENT]).Value());
+				((ConvertedSI)sumRow[SummaryDataContainer.ENGINE_DISPLACEMENT]));
 			Assert.AreEqual(dataProvider.JobInputData.Vehicle.GearboxInputData.Manufacturer,
 				sumRow[SummaryDataContainer.GEARBOX_MANUFACTURER]);
 			Assert.AreEqual(dataProvider.JobInputData.Vehicle.GearboxInputData.Model, sumRow[SummaryDataContainer.GEARBOX_MODEL]);
diff --git a/VectoCore/VectoCoreTest/Utils/SITest.cs b/VectoCore/VectoCoreTest/Utils/SITest.cs
index 886ac427fe..31c01ccfcf 100644
--- a/VectoCore/VectoCoreTest/Utils/SITest.cs
+++ b/VectoCore/VectoCoreTest/Utils/SITest.cs
@@ -195,8 +195,8 @@ namespace TUGraz.VectoCore.Tests.Utils
 
             Assert.AreEqual(1, 0.SI().CompareTo(null));
             Assert.AreEqual(1, 0.SI().CompareTo("not an SI"));
-            Assert.AreEqual(-1, new SI(Unit.SI.Meter).CompareTo(new SI(Unit.SI.Kilo.Meter.Per.Hour)));
-            Assert.AreEqual(1, new SI(Unit.SI.Newton.Meter).CompareTo(new SI(Unit.SI.Meter)));
+			Assert.AreEqual(-1, new SI(Unit.SI.Meter).CompareTo(new SI(Unit.SI.Kilo.Meter.Per.Hour)));
+			Assert.AreEqual(1, new SI(Unit.SI.Newton.Meter).CompareTo(new SI(Unit.SI.Meter)));
 
 			Assert.AreEqual(0, 1.SI().CompareTo(1.SI()));
 			Assert.AreEqual(-1, 1.SI().CompareTo(2.SI()));
@@ -331,6 +331,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 			AssertHelper.AreRelativeEqual(perSecond, watt / newtonMeter);
 
 			AssertHelper.AreRelativeEqual(second, newtonMeter / watt);
+
+
+			AssertHelper.AreRelativeEqual(2.SI<NormLiterPerSecond>(), 2.SI<NormLiterPerSecond>() / 1);
+
+			AssertHelper.AreRelativeEqual(2.SI<NormLiterPerSecond>(), 2.SI<NormLiterPerSecond>() * 1);
 		}
 
 		[TestCase]
@@ -352,7 +357,7 @@ namespace TUGraz.VectoCore.Tests.Utils
             AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Gramm.Square.Meter.Per.Cubic.Second), 3.SI<Watt>());
             AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Gramm.Meter.Per.Square.Second), 3.SI<Newton>());
             AssertHelper.AreRelativeEqual(3000.SI(Unit.SI.Kilo.Gramm), 3.SI(Unit.SI.Ton));
-            AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Kilo.Gramm).ConvertToTon(), 3000.SI(Unit.SI.Kilo.Gramm).ConvertToTon());
+            AssertHelper.AreRelativeEqual(3.SI(Unit.SI.Kilo.Kilo.Gramm).Cast<Kilogram>().ConvertToTon(), 3000.SI(Unit.SI.Kilo.Gramm).Cast<Kilogram>().ConvertToTon());
 
             AssertHelper.AreRelativeEqual(3.SI<Meter>(), 3000.SI(Unit.SI.Milli.Meter));
 
@@ -550,31 +555,37 @@ namespace TUGraz.VectoCore.Tests.Utils
             Assert.AreEqual("m^3", 1.SI().GetUnitString(uni2.GetSIUnits()));
             AssertHelper.AreRelativeEqual(0.000001, uni2.Factor);
 
-            var val2 = 7.SI(Unit.SI.Cubic.Dezi.Meter).ConvertToCubicDeziMeter();
-            AssertHelper.AreRelativeEqual(0.007, val2);
-
-            var val3 = 5.SI(Unit.SI.Cubic.Dezi.Meter).ConvertToCubicCentiMeter();
-            AssertHelper.AreRelativeEqual(0.005, val3); // 5000 cm^3
-
-            var val4 = 5.SI(Unit.SI.Cubic.Centi.Meter).ConvertToCubicDeziMeter();
-            AssertHelper.AreRelativeEqual(0.000005, val4); // 0.005 dm^3
-
-            var uni1 = Unit.SI.Kilo.Meter.Per.Hour;
+           var uni1 = Unit.SI.Kilo.Meter.Per.Hour;
             Assert.AreEqual("m/s", 1.SI().GetUnitString(uni1.GetSIUnits()));
             AssertHelper.AreRelativeEqual(0.2777777777, uni1.Factor);
 
             NewtonMeter newtonMeter = 5.SI<NewtonMeter>();
             AssertHelper.AreRelativeEqual(5.SI(Unit.SI.Newton.Meter), newtonMeter);
             AssertHelper.AreRelativeEqual(5.SI(Unit.SI.Meter.Newton), newtonMeter);
-        }
 
-        [TestCase]
+			AssertHelper.AreRelativeEqual(5.SI<Liter>(), 1.SI<Second>() * 5.SI<LiterPerSecond>());
+
+			AssertHelper.AreRelativeEqual((6.0/3600).SI<Liter>(), (2.SI<Second>() * 3.SI(Unit.SI.Liter.Per.Hour)).Cast<Liter>());
+
+			AssertHelper.AreRelativeEqual(2.13093, 2.13093.SI(Unit.SI.Liter).Cast<Liter>().Value());
+			Assert.AreEqual("m^3", 2.13093.SI(Unit.SI.Liter).GetUnitString());
+		}
+
+		[TestCase]
         public void SI_ConvertValues()
         {
             var sig1 = 5.SI(Unit.SI.Gramm);
             Assert.AreEqual(0.005, sig1.Value());
-            
-        }
+
+			var val2 = 7.SI(Unit.SI.Cubic.Dezi.Meter).Cast<CubicMeter>().ConvertToCubicDeziMeter();
+			AssertHelper.AreRelativeEqual(7, val2);
+
+			var val3 = 5.SI(Unit.SI.Cubic.Dezi.Meter).Cast<CubicMeter>().ConvertToCubicCentiMeter();
+			AssertHelper.AreRelativeEqual(5000, val3); // 5000 cm^3
+
+			var val4 = 5.SI(Unit.SI.Cubic.Centi.Meter).Cast<CubicMeter>().ConvertToCubicDeziMeter();
+			AssertHelper.AreRelativeEqual(0.005, val4); // 0.005 dm^3
+		}
 
     }
 
-- 
GitLab