From 92a5e5f4a7da487dc8c7b102271d4383b8811cbc Mon Sep 17 00:00:00 2001
From: Markus Quaritsch <markus.quaritsch@tugraz.at>
Date: Thu, 26 Apr 2018 14:45:32 +0200
Subject: [PATCH] implementation of VTP Report

refactoring: move IVectoHash interface to vectocommon project, provide methods for reading manufacturer report in a dedicated class (used by VTP mode and hashing tool)
---
 HashingCmd/Program.cs                         |    1 +
 HashingTool/Helper/HashingHelper.cs           |    1 +
 .../UserControl/ManufacturerReportXMLFile.cs  |   62 +-
 .../ViewModel/UserControl/ReportXMLFile.cs    |   32 +-
 .../ViewModel/UserControl/VectoJobFile.cs     |    1 +
 .../VerifyComponentInputDataViewModel.cs      |    1 +
 VECTO/GUI/MainForm.vb                         | 3698 +++++++++--------
 VECTO/Input Files/Engine.vb                   |    4 +-
 VECTO/Input Files/Gearbox.vb                  |    4 +-
 VECTO/Input Files/VectoEPTPJob.vb             |    7 +
 VECTO/Input Files/Vehicle.vb                  |    4 +-
 .../Hashing}/IVectoHash.cs                    |  333 +-
 .../Hashing}/VectoComponents.cs               |  222 +-
 .../InputData/DeclarationInputData.cs         |    2 +-
 .../InputData/VTPDeclarationInputData.cs      |   70 +
 VectoCommon/VectoCommon/Utils/SI.cs           | 3146 +++++++-------
 VectoCommon/VectoCommon/VectoCommon.csproj    |    2 +
 VectoCommon/VectoHashing/VectoHash.cs         |    1 +
 VectoCommon/VectoHashing/VectoHashing.csproj  |   14 +-
 VectoCommon/VectoHashingTest/VectoHashTest.cs |    1 +
 .../FileIO/JSON/JSONComponentInputData.cs     |    2 +-
 .../InputData/FileIO/JSON/JSONEngineData.cs   |    4 +-
 .../InputData/FileIO/JSON/JSONGearboxData.cs  |    4 +-
 .../InputData/FileIO/JSON/JSONInputData.cs    |  235 +-
 .../InputData/FileIO/JSON/JSONVehicleData.cs  |    4 +-
 ...ractDeclarationXMLComponentDataProvider.cs |   20 +-
 .../XMLDeclarationInputDataProvider.cs        |   28 +-
 .../XMLDeclarationVehicleDataProvider.cs      |    3 +-
 .../XMLManufacturerReportReader.cs            |   72 +
 ...ractEngineeringXMLComponentDataProvider.cs |    4 +-
 .../VectoCore/InputData/Impl/InputData.cs     |    2 +-
 .../AbstractSimulationDataAdapter.cs          |   14 +-
 .../DeclarationDataAdapter.cs                 |    2 +-
 .../Reader/DrivingCycleDataReader.cs          |   86 +-
 .../DeclarationVTPModeVectoRunDataFactory.cs  |   12 +-
 .../Models/Declaration/DeclarationData.cs     |    6 +
 .../Models/Simulation/Data/VectoRunData.cs    |   17 +-
 .../VectoCore/OutputData/DeclarationReport.cs |   10 +-
 VectoCore/VectoCore/OutputData/VTPReport.cs   |   10 +-
 .../OutputData/XML/XMLCustomerReport.cs       |    2 +-
 .../OutputData/XML/XMLDeclarationReport.cs    |    2 +-
 .../OutputData/XML/XMLManufacturerReport.cs   |    2 +-
 .../VectoCore/OutputData/XML/XMLVTPReport.cs  |  375 +-
 .../Resources/XSD/VectoVTPReport.xsd          |   24 +-
 VectoCore/VectoCore/VectoCore.csproj          |    1 +
 .../SimulationComponentData/ValidationTest.cs |    2 +-
 ...or_4x2_vehicle-class-5_Generic vehicle.xml |   98 +-
 .../class_5_generic vehicle_DECL.vecto        |    1 +
 .../Utils/MockEngineDataProvider.cs           |    2 +-
 49 files changed, 4618 insertions(+), 4032 deletions(-)
 rename VectoCommon/{VectoHashing => VectoCommon/Hashing}/IVectoHash.cs (98%)
 rename VectoCommon/{VectoHashing => VectoCommon/Hashing}/VectoComponents.cs (96%)
 create mode 100644 VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs

diff --git a/HashingCmd/Program.cs b/HashingCmd/Program.cs
index 89e4fa8963..785345ff8f 100644
--- a/HashingCmd/Program.cs
+++ b/HashingCmd/Program.cs
@@ -37,6 +37,7 @@ using System.Reflection;
 using System.Text;
 using System.Xml;
 using System.Xml.Schema;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCore.Utils;
 using TUGraz.VectoHashing;
 
diff --git a/HashingTool/Helper/HashingHelper.cs b/HashingTool/Helper/HashingHelper.cs
index d838db3b2a..f44877b648 100644
--- a/HashingTool/Helper/HashingHelper.cs
+++ b/HashingTool/Helper/HashingHelper.cs
@@ -35,6 +35,7 @@ using System.Linq;
 using System.Xml;
 using HashingTool.ViewModel;
 using HashingTool.ViewModel.UserControl;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCommon.Resources;
 using TUGraz.VectoHashing;
 
diff --git a/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs b/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs
index 577aed3639..8587b484e0 100644
--- a/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs
+++ b/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs
@@ -34,9 +34,11 @@ using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
 using System.Xml;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Resources;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.InputData.FileIO.XML.Declaration;
 using TUGraz.VectoHashing;
 
 namespace HashingTool.ViewModel.UserControl
@@ -75,7 +77,7 @@ namespace HashingTool.ViewModel.UserControl
 				RaisePropertyChanged("Components");
 				return;
 			}
-			var components = GetContainigComponents().GroupBy(s => s)
+			var components = XMLManufacturerReportReader.GetContainingComponents(_xmlFile.Document).GroupBy(s => s)
 				.Select(g => new { Entry = g.Key, Count = g.Count() });
 			var jobComponents = _jobData == null ? new ViewModel.ComponentEntry[] { } : _jobData.Components.ToArray();
 			_validationErrors.Clear();
@@ -87,21 +89,19 @@ namespace HashingTool.ViewModel.UserControl
 			// collect c14n, digest method, digest value read, certification nr., digest value from job (re-computed)
 			var componentData = new List<ComponentEntry>();
 			foreach (var component in components) {
-				if (component.Entry == XMLNames.Component_Vehicle) {
+				if (component.Entry == VectoComponents.Vehicle) {
 					continue;
 				}
 				for (var i = 0; i < component.Count; i++) {
-					var node = GetNodes(component.Entry, i);
+					var node = XMLManufacturerReportReader.GetNodes(_xmlFile.Document, component.Entry, i);
 					var entry = new ComponentEntry {
 						Component = component.Count == 1
-							? component.Entry
-							: string.Format("{0} ({1})", component.Entry, i + 1),
+							? component.Entry.XMLElementName()
+							: string.Format("{0} ({1})", component.Entry.XMLElementName(), i + 1),
 						DigestValue = ReadElementValue(node, XMLNames.DI_Signature_Reference_DigestValue),
 						CertificationMethod = ReadElementValue(node, XMLNames.Report_Component_CertificationMethod),
 					};
-					// rename 'Axle' from report to 'Tyre' as in job
-					if (entry.Component.StartsWith("Axle ")) {
-						entry.Component = entry.Component.Replace("Axle", "Tyre");
+					if (entry.Component.StartsWith("Tyre ")) {
 						entry.CertificationNumber = ReadElementValue(node, XMLNames.Report_Tyre_TyreCertificationNumber);
 					} else {
 						entry.CertificationNumber = ReadElementValue(node, XMLNames.Report_Component_CertificationNumber) ??
@@ -171,51 +171,9 @@ namespace HashingTool.ViewModel.UserControl
 			return node.InnerText;
 		}
 
-		protected XmlNode GetNodes(string component, int index)
-		{
-			var nodes = _xmlFile.Document.SelectNodes(GetComponentQueryString(component));
-			if (nodes == null || nodes.Count == 0) {
-				throw new Exception(component == null
-					? "No component found"
-					: string.Format("Component {0} not found", component));
-			}
-			if (index >= nodes.Count) {
-				throw new Exception(string.Format("index exceeds number of components found! index: {0}, #components: {1}", index,
-					nodes.Count));
-			}
-			return nodes[index];
-		}
-
-		protected static string GetComponentQueryString(string component = null)
-		{
-			if (component == null) {
-				return "(//*[@id])[1]";
-			}
-			return string.Format("//*[local-name()='{0}']", component);
-		}
-
-		protected IList<string> GetContainigComponents()
-		{
-			var retVal = new List<string>();
-			foreach (var component in EnumHelper.GetValues<VectoComponents>()) {
-				var nodes = _xmlFile.Document.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']/*[local-name()='Model']",
-					XMLNames.VectoManufacturerReport, component.XMLElementName()));
-				var count = nodes == null ? 0 : nodes.Count;
-				for (var i = 0; i < count; i++) {
-					retVal.Add(component.XMLElementName());
-				}
-			}
-			foreach (var component in new[] { XMLNames.AxleWheels_Axles_Axle }) {
-				var nodes = _xmlFile.Document.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']",
-					XMLNames.VectoManufacturerReport, component));
-				var count = nodes == null ? 0 : nodes.Count;
-				for (var i = 0; i < count; i++) {
-					retVal.Add(component);
-				}
-			}
-			return retVal;
-		}
+		
 
+		
 
 		public ComponentEntry[] Components { get; private set; }
 
diff --git a/HashingTool/ViewModel/UserControl/ReportXMLFile.cs b/HashingTool/ViewModel/UserControl/ReportXMLFile.cs
index 770390873b..6c639360d9 100644
--- a/HashingTool/ViewModel/UserControl/ReportXMLFile.cs
+++ b/HashingTool/ViewModel/UserControl/ReportXMLFile.cs
@@ -34,6 +34,8 @@ using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Linq;
 using System.Xml;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCore.InputData.FileIO.XML.Declaration;
 using TUGraz.VectoHashing;
 
 namespace HashingTool.ViewModel.UserControl
@@ -130,37 +132,19 @@ namespace HashingTool.ViewModel.UserControl
 		// readout all required fields from the report xml: c14n, digest method, digest value of job, VIN, ...
 		protected virtual void ReadReportData()
 		{
-			var jobDigest = "";
-			var jobDigestMethod = "";
+			var digestData = new DigestData("", new string[]{}, "", "");
 			var vin = "";
-			var jobc14NMethod = new string[] { };
-
+			
 			if (_xmlFile.Document != null && _xmlFile.Document.DocumentElement != null) {
-				var digestValueNode =
-					_xmlFile.Document.SelectSingleNode("//*[local-name()='InputDataSignature']//*[local-name()='DigestValue']");
-				if (digestValueNode != null) {
-					jobDigest = digestValueNode.InnerText;
-				}
-				var digestMethodNode =
-					_xmlFile.Document.SelectSingleNode(
-						"//*[local-name()='InputDataSignature']//*[local-name()='DigestMethod']/@Algorithm");
-				if (digestMethodNode != null) {
-					jobDigestMethod = digestMethodNode.InnerText;
-				}
-
-				var c14NtMethodNodes =
-					_xmlFile.Document.SelectNodes("//*[local-name()='InputDataSignature']//*[local-name()='Transform']/@Algorithm");
-				if (c14NtMethodNodes != null) {
-					jobc14NMethod = (from XmlNode node in c14NtMethodNodes select node.InnerText).ToArray();
-				}
+				digestData = new DigestData(_xmlFile.Document.SelectSingleNode("//*[local-name()='InputDataSignature']"));
 				var vinNode = _xmlFile.Document.SelectSingleNode("//*[local-name()='VIN']");
 				if (vinNode != null) {
 					vin = vinNode.InnerText;
 				}
 			}
-			JobCanonicalizationMethodRead = jobc14NMethod;
-			JobDigestMethodRead = jobDigestMethod;
-			JobDigestValueRead = jobDigest;
+			JobCanonicalizationMethodRead = digestData.CanonicalizationMethods;
+			JobDigestMethodRead = digestData.DigestMethod;
+			JobDigestValueRead = digestData.DigestValue;
 			ReportVIN = vin;
 			RaisePropertyChanged(GeneralUpdate);
 		}
diff --git a/HashingTool/ViewModel/UserControl/VectoJobFile.cs b/HashingTool/ViewModel/UserControl/VectoJobFile.cs
index 1ce4e843ff..87a584106a 100644
--- a/HashingTool/ViewModel/UserControl/VectoJobFile.cs
+++ b/HashingTool/ViewModel/UserControl/VectoJobFile.cs
@@ -35,6 +35,7 @@ using System.ComponentModel;
 using System.Linq;
 using System.Xml;
 using HashingTool.Helper;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCommon.Resources;
 using TUGraz.VectoHashing;
 
diff --git a/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs b/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs
index b6f2334a41..b23738e40f 100644
--- a/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs
+++ b/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs
@@ -38,6 +38,7 @@ using System.Windows;
 using System.Windows.Input;
 using HashingTool.Helper;
 using HashingTool.ViewModel.UserControl;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoHashing;
 
 namespace HashingTool.ViewModel
diff --git a/VECTO/GUI/MainForm.vb b/VECTO/GUI/MainForm.vb
index 0568209c72..eccee56f13 100644
--- a/VECTO/GUI/MainForm.vb
+++ b/VECTO/GUI/MainForm.vb
@@ -57,1984 +57,2024 @@ Imports TUGraz.VectoCore.Utils
 ''' </summary>
 ''' <remarks></remarks>
 
-Public Class MainForm
-	Private _jobListView As FileListView
-	Private _cycleListView As FileListView
+    Public Class MainForm
+    Private _jobListView As FileListView
+    Private _cycleListView As FileListView
 
-	Private _lastModeName As String
-	Private _conMenTarget As ListView
-	Private _conMenTarJob As Boolean
+    Private _lastModeName As String
+    Private _conMenTarget As ListView
+    Private _conMenTarJob As Boolean
 
-	Private _guIlocked As Boolean
+    Private _guIlocked As Boolean
 
-	Private _checkLock As Boolean
-	Private _genChecked As Integer
-	Private _genCheckAllLock As Boolean
+    Private _checkLock As Boolean
+    Private _genChecked As Integer
+    Private _genCheckAllLock As Boolean
 
-	Private _cbDeclLock As Boolean = False
+    Private _cbDeclLock As Boolean = False
 
 #Region "SLEEP Control - Prevent sleep while VECTO is running"
 
-	Private Declare Function SetThreadExecutionState Lib "kernel32" (esFlags As Long) As Long
+    Private Declare Function SetThreadExecutionState Lib "kernel32"(esFlags As Long) As Long
 
-	Private Shared Sub AllowSleepOff()
+    Private Shared Sub AllowSleepOff()
 #If Not PLATFORM = "x86" Then
-		SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS Or EXECUTION_STATE.ES_SYSTEM_REQUIRED)
+        SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS Or EXECUTION_STATE.ES_SYSTEM_REQUIRED)
 #End If
-	End Sub
+    End Sub
 
-	Private Shared Sub AllowSleepOn()
+    Private Shared Sub AllowSleepOn()
 #If Not PLATFORM = "x86" Then
-		SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
+        SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS)
 #End If
-	End Sub
+    End Sub
 
-	Private Enum EXECUTION_STATE As Integer
-		''' Informs the system that the state being set should remain in effect until the next call that uses ES_CONTINUOUS and one of the other state flags is cleared.
-		ES_CONTINUOUS = &H80000000
-		''' Forces the display to be on by resetting the display idle timer.
-		ES_DISPLAY_REQUIRED = &H2
-		''' Forces the system to be in the working state by resetting the system idle timer.
-		ES_SYSTEM_REQUIRED = &H1
-	End Enum
+    Private Enum EXECUTION_STATE As Integer
+        ''' Informs the system that the state being set should remain in effect until the next call that uses ES_CONTINUOUS and one of the other state flags is cleared.
+        ES_CONTINUOUS = &H80000000
+        ''' Forces the display to be on by resetting the display idle timer.
+        ES_DISPLAY_REQUIRED = &H2
+        ''' Forces the system to be in the working state by resetting the system idle timer.
+        ES_SYSTEM_REQUIRED = &H1
+    End Enum
 
 #End Region
 
 #Region "FileBrowser Init/Close"
 
-	Private Sub FB_Initialize()
-		FileBrowserFolderHistoryIninialized = False
-		Try
-			COREvers = VectoSimulationCore.VersionNumber()
-		Catch ex As Exception
-			LogFile.WriteToLog(MessageType.Err, ex.StackTrace)
-		End Try
-
-
-		FolderFileBrowser = New FileBrowser("WorkDir", True)
-		TextFileBrowser = New FileBrowser("FileLists")
-		JobfileFileBrowser = New FileBrowser("vecto")
-		VehicleFileBrowser = New FileBrowser("vveh")
-		VehicleXMLFileBrowser = New FileBrowser("vveh_xml")
-		FuelConsumptionMapFileBrowser = New FileBrowser("vmap")
-		DrivingCycleFileBrowser = New FileBrowser("vdri")
-		FullLoadCurveFileBrowser = New FileBrowser("vfld")
-		EngineFileBrowser = New FileBrowser("veng")
-		GearboxFileBrowser = New FileBrowser("vgbx")
-		DriverAccelerationFileBrowser = New FileBrowser("vacc")
-		AuxFileBrowser = New FileBrowser("vaux")
-		GearboxShiftPolygonFileBrowser = New FileBrowser("vgbs")
-		RetarderLossMapFileBrowser = New FileBrowser("vrlm")
-		TransmissionLossMapFileBrowser = New FileBrowser("vtlm")
-		PtoLossMapFileBrowser = New FileBrowser("vptol")
-		PTODrivingCycleFileBrowser = New FileBrowser("vptoc")
-		TorqueConverterFileBrowser = New FileBrowser("vtcc")
-		TorqueConverterShiftPolygonFileBrowser = New FileBrowser("vgbs")
-		CrossWindCorrectionFileBrowser = New FileBrowser("vcdx")
-		DriverDecisionFactorVelocityDropFileBrowser = New FileBrowser("DfVelocityDrop")
-		DriverDecisionFactorTargetSpeedFileBrowser = New FileBrowser("DfTargetSpeed")
-		DriverDecisionFactorVelocityDropFileBrowser.Extensions = New String() {"csv"}
-		DriverDecisionFactorTargetSpeedFileBrowser.Extensions = New String() {"csv"}
-
-		ModalResultsFileBrowser = New FileBrowser("vmod")
-
-
-		'-------------------------------------------------------
-		TextFileBrowser.Extensions = New String() {"txt"}
-		JobfileFileBrowser.Extensions = New String() {"vecto"}
-		VehicleFileBrowser.Extensions = New String() {"vveh"}
-		VehicleXMLFileBrowser.Extensions = New String() {"xml"}
-		FuelConsumptionMapFileBrowser.Extensions = New String() {"vmap"}
-		DrivingCycleFileBrowser.Extensions = New String() {"vdri"}
-		FullLoadCurveFileBrowser.Extensions = New String() {"vfld"}
-		EngineFileBrowser.Extensions = New String() {"veng"}
-		GearboxFileBrowser.Extensions = New String() {"vgbx"}
-		DriverAccelerationFileBrowser.Extensions = New String() {"vacc"}
-		AuxFileBrowser.Extensions = New String() {"vaux"}
-		GearboxShiftPolygonFileBrowser.Extensions = New String() {"vgbs"}
-		RetarderLossMapFileBrowser.Extensions = New String() {"vrlm"}
-		TransmissionLossMapFileBrowser.Extensions = New String() {"vtlm"}
-		PtoLossMapFileBrowser.Extensions = New String() {"vptol"}
-		PTODrivingCycleFileBrowser.Extensions = New String() {"vptoc"}
-		TorqueConverterFileBrowser.Extensions = New String() {"vtcc"}
-		TorqueConverterShiftPolygonFileBrowser.Extensions = New String() {"vgbs"}
-		CrossWindCorrectionFileBrowser.Extensions = New String() {"vcdv", "vcdb"}
-
-		ModalResultsFileBrowser.Extensions = New String() {"vmod"}
-	End Sub
-
-	Private Sub FB_Close()
-		FolderFileBrowser.Close()
-		TextFileBrowser.Close()
-		JobfileFileBrowser.Close()
-		VehicleFileBrowser.Close()
-		VehicleXMLFileBrowser.Close()
-		FuelConsumptionMapFileBrowser.Close()
-		DrivingCycleFileBrowser.Close()
-		FullLoadCurveFileBrowser.Close()
-		EngineFileBrowser.Close()
-		GearboxFileBrowser.Close()
-		DriverAccelerationFileBrowser.Close()
-		AuxFileBrowser.Close()
-		GearboxShiftPolygonFileBrowser.Close()
-		RetarderLossMapFileBrowser.Close()
-		TransmissionLossMapFileBrowser.Close()
-		PtoLossMapFileBrowser.Close()
-		PTODrivingCycleFileBrowser.Close()
-		TorqueConverterFileBrowser.Close()
-		TorqueConverterShiftPolygonFileBrowser.Close()
-		CrossWindCorrectionFileBrowser.Close()
-		ModalResultsFileBrowser.Close()
-	End Sub
+    Private Sub FB_Initialize()
+        FileBrowserFolderHistoryIninialized = False
+        Try
+            COREvers = VectoSimulationCore.VersionNumber()
+        Catch ex As Exception
+            LogFile.WriteToLog(MessageType.Err, ex.StackTrace)
+        End Try
+
+
+        FolderFileBrowser = New FileBrowser("WorkDir", True)
+        TextFileBrowser = New FileBrowser("FileLists")
+        JobfileFileBrowser = New FileBrowser("vecto")
+        VehicleFileBrowser = New FileBrowser("vveh")
+        VehicleXMLFileBrowser = New FileBrowser("vveh_xml")
+        FuelConsumptionMapFileBrowser = New FileBrowser("vmap")
+        DrivingCycleFileBrowser = New FileBrowser("vdri")
+        FullLoadCurveFileBrowser = New FileBrowser("vfld")
+        EngineFileBrowser = New FileBrowser("veng")
+        GearboxFileBrowser = New FileBrowser("vgbx")
+        DriverAccelerationFileBrowser = New FileBrowser("vacc")
+        AuxFileBrowser = New FileBrowser("vaux")
+        GearboxShiftPolygonFileBrowser = New FileBrowser("vgbs")
+        RetarderLossMapFileBrowser = New FileBrowser("vrlm")
+        TransmissionLossMapFileBrowser = New FileBrowser("vtlm")
+        PtoLossMapFileBrowser = New FileBrowser("vptol")
+        PTODrivingCycleFileBrowser = New FileBrowser("vptoc")
+        TorqueConverterFileBrowser = New FileBrowser("vtcc")
+        TorqueConverterShiftPolygonFileBrowser = New FileBrowser("vgbs")
+        CrossWindCorrectionFileBrowser = New FileBrowser("vcdx")
+        DriverDecisionFactorVelocityDropFileBrowser = New FileBrowser("DfVelocityDrop")
+        DriverDecisionFactorTargetSpeedFileBrowser = New FileBrowser("DfTargetSpeed")
+        DriverDecisionFactorVelocityDropFileBrowser.Extensions = New String() {"csv"}
+        DriverDecisionFactorTargetSpeedFileBrowser.Extensions = New String() {"csv"}
+
+        ModalResultsFileBrowser = New FileBrowser("vmod")
+
+
+        '-------------------------------------------------------
+        TextFileBrowser.Extensions = New String() {"txt"}
+        JobfileFileBrowser.Extensions = New String() {"vecto"}
+        VehicleFileBrowser.Extensions = New String() {"vveh"}
+        VehicleXMLFileBrowser.Extensions = New String() {"xml"}
+        FuelConsumptionMapFileBrowser.Extensions = New String() {"vmap"}
+        DrivingCycleFileBrowser.Extensions = New String() {"vdri"}
+        FullLoadCurveFileBrowser.Extensions = New String() {"vfld"}
+        EngineFileBrowser.Extensions = New String() {"veng"}
+        GearboxFileBrowser.Extensions = New String() {"vgbx"}
+        DriverAccelerationFileBrowser.Extensions = New String() {"vacc"}
+        AuxFileBrowser.Extensions = New String() {"vaux"}
+        GearboxShiftPolygonFileBrowser.Extensions = New String() {"vgbs"}
+        RetarderLossMapFileBrowser.Extensions = New String() {"vrlm"}
+        TransmissionLossMapFileBrowser.Extensions = New String() {"vtlm"}
+        PtoLossMapFileBrowser.Extensions = New String() {"vptol"}
+        PTODrivingCycleFileBrowser.Extensions = New String() {"vptoc"}
+        TorqueConverterFileBrowser.Extensions = New String() {"vtcc"}
+        TorqueConverterShiftPolygonFileBrowser.Extensions = New String() {"vgbs"}
+        CrossWindCorrectionFileBrowser.Extensions = New String() {"vcdv", "vcdb"}
+
+        ModalResultsFileBrowser.Extensions = New String() {"vmod"}
+    End Sub
+
+    Private Sub FB_Close()
+        FolderFileBrowser.Close()
+        TextFileBrowser.Close()
+        JobfileFileBrowser.Close()
+        VehicleFileBrowser.Close()
+        VehicleXMLFileBrowser.Close()
+        FuelConsumptionMapFileBrowser.Close()
+        DrivingCycleFileBrowser.Close()
+        FullLoadCurveFileBrowser.Close()
+        EngineFileBrowser.Close()
+        GearboxFileBrowser.Close()
+        DriverAccelerationFileBrowser.Close()
+        AuxFileBrowser.Close()
+        GearboxShiftPolygonFileBrowser.Close()
+        RetarderLossMapFileBrowser.Close()
+        TransmissionLossMapFileBrowser.Close()
+        PtoLossMapFileBrowser.Close()
+        PTODrivingCycleFileBrowser.Close()
+        TorqueConverterFileBrowser.Close()
+        TorqueConverterShiftPolygonFileBrowser.Close()
+        CrossWindCorrectionFileBrowser.Close()
+        ModalResultsFileBrowser.Close()
+    End Sub
 
 #End Region
 
-	'Lock certain GUI elements while VECTO is running
-	Private Sub LockGUI(lock As Boolean)
-		_guIlocked = lock
+    'Lock certain GUI elements while VECTO is running
+    Private Sub LockGUI(lock As Boolean)
+        _guIlocked = lock
 
-		PanelOptAllg.Enabled = Not lock
+        PanelOptAllg.Enabled = Not lock
 
-		BtGENup.Enabled = Not lock
-		BtGENdown.Enabled = Not lock
-		ButtonGENadd.Enabled = Not lock
-		ButtonGENremove.Enabled = Not lock
-		LvGEN.LabelEdit = Not lock
-		ChBoxAllGEN.Enabled = Not lock
+        BtGENup.Enabled = Not lock
+        BtGENdown.Enabled = Not lock
+        ButtonGENadd.Enabled = Not lock
+        ButtonGENremove.Enabled = Not lock
+        LvGEN.LabelEdit = Not lock
+        ChBoxAllGEN.Enabled = Not lock
 
-		btStartV3.Enabled = Not lock
-	End Sub
+        btStartV3.Enabled = Not lock
+    End Sub
 
 
 #Region "Form Init/Close"
 
-	'Initialise
-	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
-		Dim x As Integer
+    'Initialise
+    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
+        Dim x As Integer
 
-		_guIlocked = False
-		_checkLock = False
-		_genCheckAllLock = False
-		_genChecked = 0
+        _guIlocked = False
+        _checkLock = False
+        _genCheckAllLock = False
+        _genChecked = 0
 
 
-		'Load Tabs properly (otherwise problem with ListViews)
-		For x = 0 To TabControl1.TabCount - 1
-			TabControl1.TabPages(x).Show()
-		Next
+        'Load Tabs properly (otherwise problem with ListViews)
+        For x = 0 To TabControl1.TabCount - 1
+            TabControl1.TabPages(x).Show()
+        Next
 
-		_lastModeName = ""
+        _lastModeName = ""
 
-		FB_Initialize()
+        FB_Initialize()
 
-		Text = "VECTO " & VECTOvers & " / VectoCore " & COREvers
+        Text = "VECTO " & VECTOvers & " / VectoCore " & COREvers
 
 
-		'FileLists
-		_jobListView = New FileListView(MyConfPath & "joblist.txt")
-		_jobListView.LVbox = LvGEN
-		_cycleListView = New FileListView(MyConfPath & "cyclelist.txt")
+        'FileLists
+        _jobListView = New FileListView(MyConfPath & "joblist.txt")
+        _jobListView.LVbox = LvGEN
+        _cycleListView = New FileListView(MyConfPath & "cyclelist.txt")
 
-		_jobListView.LoadList()
+        _jobListView.LoadList()
 
-		LoadOptions()
+        LoadOptions()
 
-		'Resize columns ... after Loading the @file-lists
-		LvGEN.Columns(1).Width = -2
-		LvMsg.Columns(2).Width = -2
+        'Resize columns ... after Loading the @file-lists
+        LvGEN.Columns(1).Width = - 2
+        LvMsg.Columns(2).Width = - 2
 
-		'Initialize BackgroundWorker
+        'Initialize BackgroundWorker
 
-		VectoWorkerV3 = New BackgroundWorker()
-		AddHandler VectoWorkerV3.DoWork, AddressOf VectoWorkerV3_OnDoWork
-		AddHandler VectoWorkerV3.ProgressChanged, AddressOf VectoWorkerV3_OnProgressChanged
-		AddHandler VectoWorkerV3.RunWorkerCompleted, AddressOf VectoWorkerV3_OnRunWorkerCompleted
+        VectoWorkerV3 = New BackgroundWorker()
+        AddHandler VectoWorkerV3.DoWork, AddressOf VectoWorkerV3_OnDoWork
+        AddHandler VectoWorkerV3.ProgressChanged, AddressOf VectoWorkerV3_OnProgressChanged
+        AddHandler VectoWorkerV3.RunWorkerCompleted, AddressOf VectoWorkerV3_OnRunWorkerCompleted
 
-		VectoWorkerV3.WorkerReportsProgress = True
-		VectoWorkerV3.WorkerSupportsCancellation = True
+        VectoWorkerV3.WorkerReportsProgress = True
+        VectoWorkerV3.WorkerSupportsCancellation = True
 
-		'Set mode (Batch/Standard)
-		ModeUpdate()
+        'Set mode (Batch/Standard)
+        ModeUpdate()
 
-		DeclOnOff()
-	End Sub
+        DeclOnOff()
+    End Sub
 
-	' ReSharper disable once UnusedMember.Global -- used via Logging Framework!
-	Public Shared Sub LogMethod(level As String, message As String)
-		If VectoWorkerV3.IsBusy AndAlso Not VectoWorkerV3.CancellationPending Then
-			If level = "Warn" Then
-				VectoWorkerV3.ReportProgress(100, New VectoProgress With {.Target = "ListBoxWarning", .Message = message})
-			ElseIf level = "Error" Or level = "Fatal" Then
-				VectoWorkerV3.ReportProgress(100, New VectoProgress With {.Target = "ListBoxError", .Message = message})
-			End If
-		End If
-	End Sub
+    ' ReSharper disable once UnusedMember.Global -- used via Logging Framework!
+    Public Shared Sub LogMethod(level As String, message As String)
+        If VectoWorkerV3.IsBusy AndAlso Not VectoWorkerV3.CancellationPending Then
+            If level = "Warn" Then
+                VectoWorkerV3.ReportProgress(100,
+                                             New VectoProgress With {.Target = "ListBoxWarning", .Message = message})
+            ElseIf level = "Error" Or level = "Fatal" Then
+                VectoWorkerV3.ReportProgress(100, New VectoProgress With {.Target = "ListBoxError", .Message = message})
+            End If
+        End If
+    End Sub
 
-	'Declaration mode GUI settings
-	Private Sub DeclOnOff()
+    'Declaration mode GUI settings
+    Private Sub DeclOnOff()
 
-		If Cfg.DeclMode Then
-			Text = "VECTO " & COREvers & " - Declaration Mode"
-			Cfg.DeclInit()
-		Else
-			Text = "VECTO " & COREvers
-		End If
+        If Cfg.DeclMode Then
+            Text = "VECTO " & COREvers & " - Declaration Mode"
+            Cfg.DeclInit()
+        Else
+            Text = "VECTO " & COREvers
+        End If
 
-		If Cfg.DeclMode Then
-			_lastModeName = "Declaration"
-		Else
-			_lastModeName = "Engineering"
-		End If
+        If Cfg.DeclMode Then
+            _lastModeName = "Declaration"
+        Else
+            _lastModeName = "Engineering"
+        End If
 
-		Status(_lastModeName & " Mode")
+        Status(_lastModeName & " Mode")
 
-		LoadOptions()
+        LoadOptions()
 
-		LbDecl.Visible = Cfg.DeclMode
-	End Sub
+        LbDecl.Visible = Cfg.DeclMode
+    End Sub
 
-	'Shown Event (Form-Load finished) ... here StartUp Forms are loaded (DEV, GEN/ADV- Editor ..)
-	Private Sub F01_MAINForm_Shown(sender As Object, e As EventArgs) Handles Me.Shown
-		Dim fwelcome As WelcomeDialog
+    'Shown Event (Form-Load finished) ... here StartUp Forms are loaded (DEV, GEN/ADV- Editor ..)
+    Private Sub F01_MAINForm_Shown(sender As Object, e As EventArgs) Handles Me.Shown
+        Dim fwelcome As WelcomeDialog
 
-		If Cfg.FirstRun Then
-			Cfg.FirstRun = False
-			fwelcome = New WelcomeDialog
-			fwelcome.ShowDialog()
-		End If
-	End Sub
+        If Cfg.FirstRun Then
+            Cfg.FirstRun = False
+            fwelcome = New WelcomeDialog
+            fwelcome.ShowDialog()
+        End If
+    End Sub
 
-	'Open file
+    'Open file
 
-	'Close
-	Private Sub F01_MAINForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
+    'Close
+    Private Sub F01_MAINForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
 
-		'Save File-Lists
-		SaveFileLists()
+        'Save File-Lists
+        SaveFileLists()
 
-		'Close log
-		LogFile.CloseLog()
+        'Close log
+        LogFile.CloseLog()
 
-		'Config save
-		SetOptions()
-		Cfg.Save()
+        'Config save
+        SetOptions()
+        Cfg.Save()
 
-		'File browser instances close
-		FB_Close()
-	End Sub
+        'File browser instances close
+        FB_Close()
+    End Sub
 
 #End Region
 
-	'Open file - Job, vehicle, engine, gearbox or signature file
-	Public Sub OpenVectoFile(file As String)
-
-		If Not IO.File.Exists(file) Then
-
-			GUIMsg(MessageType.Err, "File not found! (" & file & ")")
-			MsgBox("File not found! (" & file & ")", MsgBoxStyle.Critical)
-
-		Else
-
-			Select Case UCase(GetExtension(file))
-				Case ".VGBX"
-					If Not GearboxForm.Visible Then
-						GearboxForm.Show()
-					Else
-						GearboxForm.JobDir = ""
-						If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal
-						GearboxForm.BringToFront()
-					End If
-					Try
-						GearboxForm.OpenGbx(file, VehicleCategory.RigidTruck)
-					Catch ex As Exception
-						MsgBox("Failed to open Gearbox File: " + ex.Message)
-					End Try
-				Case ".VVEH"
-					If Not VehicleForm.Visible Then
-						VehicleForm.Show()
-					Else
-						VehicleForm.JobDir = ""
-						If VehicleForm.WindowState = FormWindowState.Minimized Then VehicleForm.WindowState = FormWindowState.Normal
-						VehicleForm.BringToFront()
-					End If
-					Try
-						VehicleForm.OpenVehicle(file)
-					Catch ex As Exception
-						MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vehicle File")
-					End Try
-				Case ".VENG"
-					If Not EngineForm.Visible Then
-						EngineForm.Show()
-					Else
-						EngineForm.JobDir = ""
-						If EngineForm.WindowState = FormWindowState.Minimized Then EngineForm.WindowState = FormWindowState.Normal
-						EngineForm.BringToFront()
-					End If
-					Try
-						EngineForm.OpenEngineFile(file)
-					Catch ex As Exception
-						MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Engine File")
-					End Try
-				Case ".VECTO"
-					OpenVECTOeditor(file)
-				Case Else
-					MsgBox("Type '" & GetExtension(file) & "' unknown!", MsgBoxStyle.Critical)
-			End Select
-
-		End If
-	End Sub
+    'Open file - Job, vehicle, engine, gearbox or signature file
+    Public Sub OpenVectoFile(file As String)
+
+        If Not IO.File.Exists(file) Then
+
+            GUIMsg(MessageType.Err, "File not found! (" & file & ")")
+            MsgBox("File not found! (" & file & ")", MsgBoxStyle.Critical)
+
+        Else
+
+            Select Case UCase(GetExtension(file))
+                Case ".VGBX"
+                    If Not GearboxForm.Visible Then
+                        GearboxForm.Show()
+                    Else
+                        GearboxForm.JobDir = ""
+                        If GearboxForm.WindowState = FormWindowState.Minimized Then _
+                            GearboxForm.WindowState = FormWindowState.Normal
+                        GearboxForm.BringToFront()
+                    End If
+                    Try
+                        GearboxForm.OpenGbx(file, VehicleCategory.RigidTruck)
+                    Catch ex As Exception
+                        MsgBox("Failed to open Gearbox File: " + ex.Message)
+                    End Try
+                Case ".VVEH"
+                    If Not VehicleForm.Visible Then
+                        VehicleForm.Show()
+                    Else
+                        VehicleForm.JobDir = ""
+                        If VehicleForm.WindowState = FormWindowState.Minimized Then _
+                            VehicleForm.WindowState = FormWindowState.Normal
+                        VehicleForm.BringToFront()
+                    End If
+                    Try
+                        VehicleForm.OpenVehicle(file)
+                    Catch ex As Exception
+                        MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vehicle File")
+                    End Try
+                Case ".VENG"
+                    If Not EngineForm.Visible Then
+                        EngineForm.Show()
+                    Else
+                        EngineForm.JobDir = ""
+                        If EngineForm.WindowState = FormWindowState.Minimized Then _
+                            EngineForm.WindowState = FormWindowState.Normal
+                        EngineForm.BringToFront()
+                    End If
+                    Try
+                        EngineForm.OpenEngineFile(file)
+                    Catch ex As Exception
+                        MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Engine File")
+                    End Try
+                Case ".VECTO"
+                    OpenVECTOeditor(file)
+                Case Else
+                    MsgBox("Type '" & GetExtension(file) & "' unknown!", MsgBoxStyle.Critical)
+            End Select
+
+        End If
+    End Sub
 
 
 #Region "Events"
 
-	Private Sub ButtonGENremove_Click(sender As Object, e As EventArgs) _
-		Handles ButtonGENremove.Click
-		RemoveJobFile()
-	End Sub
-
-	Private Sub ButtonGENadd_Click(sender As Object, e As EventArgs) _
-		Handles ButtonGENadd.Click
-		AddJobFile()
-	End Sub
-
-	Private Sub ListViewGEN_KeyDown(sender As Object, e As KeyEventArgs) _
-		Handles LvGEN.KeyDown
-		Select Case e.KeyCode
-			Case Keys.Delete, Keys.Back
-				If Not _guIlocked Then RemoveJobFile()
-			Case Keys.Enter
-				OpenJobFile()
-		End Select
-	End Sub
-
-	Private Sub ListViewGEN_DoubleClick(sender As Object, e As EventArgs) Handles LvGEN.DoubleClick
-		If LvGEN.SelectedItems.Count > 0 Then
-			LvGEN.SelectedItems(0).Checked = Not LvGEN.SelectedItems(0).Checked
-			OpenJobFile()
-		End If
-	End Sub
-
-	Private Sub LvGEN_ItemChecked(sender As Object, e As ItemCheckedEventArgs) _
-		Handles LvGEN.ItemChecked
-
-		If e.Item.Checked Then
-			_genChecked += 1
-		Else
-			_genChecked -= 1
-		End If
-
-		If _checkLock Then Exit Sub
-		UpdateJobTabText()
-	End Sub
-
-	Private Sub ChBoxAllGEN_CheckedChanged(sender As Object, e As EventArgs) _
-		Handles ChBoxAllGEN.CheckedChanged
-
-		If _genCheckAllLock And ChBoxAllGEN.CheckState = CheckState.Indeterminate Then Exit Sub
-
-		CheckAllGen(ChBoxAllGEN.Checked)
-	End Sub
-
-	Private Sub CheckAllGen(check As Boolean)
-		Dim x As ListViewItem
-
-		_checkLock = True
-		LvGEN.BeginUpdate()
-
-		For Each x In LvGEN.Items
-			x.Checked = check
-		Next
-
-		LvGEN.EndUpdate()
-		_checkLock = False
-
-		_genChecked = LvGEN.CheckedItems.Count
-		UpdateJobTabText()
-	End Sub
-
-	Private Sub ListGEN_DragEnter(sender As Object, e As DragEventArgs) _
-		Handles LvGEN.DragEnter
-		If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then
-			e.Effect = DragDropEffects.Copy
-		End If
-	End Sub
-
-	Private Sub ListGEN_DragDrop(sender As Object, e As DragEventArgs) _
-		Handles LvGEN.DragDrop
-		Dim f As String()
-		f = CType(e.Data.GetData(DataFormats.FileDrop), String())
-		AddToJobListView(f)
-	End Sub
-
-	Private Sub BtGENup_Click(sender As Object, e As EventArgs) Handles BtGENup.Click
-		MoveItem(LvGEN, True)
-	End Sub
-
-	Private Sub BtGENdown_Click(sender As Object, e As EventArgs) Handles BtGENdown.Click
-		MoveItem(LvGEN, False)
-	End Sub
+    Private Sub ButtonGENremove_Click(sender As Object, e As EventArgs) _
+        Handles ButtonGENremove.Click
+        RemoveJobFile()
+    End Sub
+
+    Private Sub ButtonGENadd_Click(sender As Object, e As EventArgs) _
+        Handles ButtonGENadd.Click
+        AddJobFile()
+    End Sub
+
+    Private Sub ListViewGEN_KeyDown(sender As Object, e As KeyEventArgs) _
+        Handles LvGEN.KeyDown
+        Select Case e.KeyCode
+            Case Keys.Delete, Keys.Back
+                If Not _guIlocked Then RemoveJobFile()
+            Case Keys.Enter
+                OpenJobFile()
+        End Select
+    End Sub
+
+    Private Sub ListViewGEN_DoubleClick(sender As Object, e As EventArgs) Handles LvGEN.DoubleClick
+        If LvGEN.SelectedItems.Count > 0 Then
+            LvGEN.SelectedItems(0).Checked = Not LvGEN.SelectedItems(0).Checked
+            OpenJobFile()
+        End If
+    End Sub
+
+    Private Sub LvGEN_ItemChecked(sender As Object, e As ItemCheckedEventArgs) _
+        Handles LvGEN.ItemChecked
+
+        If e.Item.Checked Then
+            _genChecked += 1
+        Else
+            _genChecked -= 1
+        End If
+
+        If _checkLock Then Exit Sub
+        UpdateJobTabText()
+    End Sub
+
+    Private Sub ChBoxAllGEN_CheckedChanged(sender As Object, e As EventArgs) _
+        Handles ChBoxAllGEN.CheckedChanged
+
+        If _genCheckAllLock And ChBoxAllGEN.CheckState = CheckState.Indeterminate Then Exit Sub
+
+        CheckAllGen(ChBoxAllGEN.Checked)
+    End Sub
+
+    Private Sub CheckAllGen(check As Boolean)
+        Dim x As ListViewItem
+
+        _checkLock = True
+        LvGEN.BeginUpdate()
+
+        For Each x In LvGEN.Items
+            x.Checked = check
+        Next
+
+        LvGEN.EndUpdate()
+        _checkLock = False
+
+        _genChecked = LvGEN.CheckedItems.Count
+        UpdateJobTabText()
+    End Sub
+
+    Private Sub ListGEN_DragEnter(sender As Object, e As DragEventArgs) _
+        Handles LvGEN.DragEnter
+        If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then
+            e.Effect = DragDropEffects.Copy
+        End If
+    End Sub
+
+    Private Sub ListGEN_DragDrop(sender As Object, e As DragEventArgs) _
+        Handles LvGEN.DragDrop
+        Dim f As String()
+        f = CType(e.Data.GetData(DataFormats.FileDrop), String())
+        AddToJobListView(f)
+    End Sub
+
+    Private Sub BtGENup_Click(sender As Object, e As EventArgs) Handles BtGENup.Click
+        MoveItem(LvGEN, True)
+    End Sub
+
+    Private Sub BtGENdown_Click(sender As Object, e As EventArgs) Handles BtGENdown.Click
+        MoveItem(LvGEN, False)
+    End Sub
 
 #End Region
 
-	'Remove selected file(s) from job list
-	Private Sub RemoveJobFile()
-		Dim lastindx As Integer
-		Dim selIx() As Integer
-		Dim i As Integer
-
-		If LvGEN.SelectedItems.Count < 1 Then
-			If LvGEN.Items.Count = 1 Then
-				LvGEN.Items(0).Selected = True
-			Else
-				Exit Sub
-			End If
-		End If
-
-		LvGEN.BeginUpdate()
-		_checkLock = True
-
-		ReDim selIx(LvGEN.SelectedItems.Count - 1)
-		LvGEN.SelectedIndices.CopyTo(selIx, 0)
-
-		lastindx = LvGEN.SelectedIndices(LvGEN.SelectedItems.Count - 1)
-
-		For i = UBound(selIx) To 0 Step -1
-			LvGEN.Items.RemoveAt(selIx(i))
-		Next
-
-		If lastindx < LvGEN.Items.Count Then
-			LvGEN.Items(lastindx).Selected = True
-		Else
-			If LvGEN.Items.Count > 0 Then LvGEN.Items(LvGEN.Items.Count - 1).Selected = True
-		End If
-
-		LvGEN.EndUpdate()
-		_checkLock = False
-
-		_genChecked = LvGEN.CheckedItems.Count
-		UpdateJobTabText()
-	End Sub
-
-	'Browse for job file(s) and add to job list with AddToJobListView
-	Private Sub AddJobFile()
-		Dim x As String()
-		Dim chck As Boolean = False
-
-		x = New String() {""}
-
-		Dim extensions As String = "vecto"
-		Dim inputDataExtensions As String() = New String() {"xml"}
-		If (inputDataExtensions.Any()) Then extensions = String.Join(",", extensions, String.Join(",", inputDataExtensions))
-
-		'STANDARD/BATCH
-		If JobfileFileBrowser.OpenDialog("", True, extensions) Then
-			chck = True
-			x = JobfileFileBrowser.Files
-		End If
-
-		If chck Then AddToJobListView(x)
-	End Sub
-
-	'Open file in list
-	Private Sub OpenJobFile()
-		Dim f As String
-
-		If LvGEN.SelectedItems.Count < 1 Then
-			If LvGEN.Items.Count = 1 Then
-				LvGEN.Items(0).Selected = True
-			Else
-				Exit Sub
-			End If
-		End If
-
-		f = LvGEN.SelectedItems(0).SubItems(0).Text
-		f = FileRepl(f)
-		If Path.GetExtension(f) <> VectoCore.Configuration.Constants.FileExtensions.VectoJobFile Then
-			MsgBox("Job File " + f + " can not be opened in Job Editor. Try importing the file.")
-			Exit Sub
-		End If
-		If Not File.Exists(f) Then
-			MsgBox(f & " not found!")
-		Else
-			OpenVECTOeditor(f)
-		End If
-	End Sub
-
-	'Add File to job listview (multiple files)
-	Private Sub AddToJobListView(path As String(), Optional ByVal txt As String = " ")
-		Dim pDim As Integer
-		Dim p As Integer
-		Dim f As Integer
-		Dim fList As String()
-		Dim fListDim As Integer = -1
-		Dim listViewItem As ListViewItem
-
-		'If VECTO runs: Cancel operation (because Mode-change during calculation is not very clever)
-		If VectoWorkerV3.IsBusy Then Exit Sub
-
-		pDim = UBound(path)
-		ReDim fList(0)	   'um Nullverweisausnahme-Warnung zu verhindern
-
-		'******************************************* Begin Update '*******************************************
-		LvGEN.BeginUpdate()
-		_checkLock = True
-
-		LvGEN.SelectedIndices.Clear()
-
-		If pDim = 0 Then
-			fListDim = LvGEN.Items.Count - 1
-			ReDim fList(fListDim)
-			For f = 0 To fListDim
-				fList(f) = FileRepl(LvGEN.Items(f).SubItems(0).Text)
-			Next
-		End If
-
-		For p = 0 To pDim
-
-			If pDim = 0 Then
-
-				For f = 0 To fListDim
-
-					'If file already exists in the list: Do not append (only when a single file)
-					If UCase(path(p)) = UCase(fList(f)) Then
-
-						'Status reset
-						LvGEN.Items(f).SubItems(1).Text = txt
-						LvGEN.Items(f).BackColor = Color.FromKnownColor(KnownColor.Window)
-						LvGEN.Items(f).ForeColor = Color.FromKnownColor(KnownColor.WindowText)
-
-						'Element auswählen und anhaken |@@| Element selection and hook
-						LvGEN.Items(f).Selected = True
-						LvGEN.Items(f).Checked = True
-						LvGEN.Items(f).EnsureVisible()
-
-						GoTo lbFound
-					End If
-				Next
-
-			End If
-
-			'Otherwise: Add File (without WorkDir)
-			listViewItem = New ListViewItem(path(p))	'fFileWD(Path(p)))
-			listViewItem.SubItems.Add(" ")
-			listViewItem.Checked = True
-			listViewItem.Selected = True
-			LvGEN.Items.Add(listViewItem)
-			listViewItem.EnsureVisible()
-lbFound:
-		Next
-
-		LvGEN.EndUpdate()
-		_checkLock = False
-		'******************************************* End Update '*******************************************
-
-		'Number update
-		_genChecked = LvGEN.CheckedItems.Count
-		UpdateJobTabText()
-	End Sub
-
-	'Add File to job listview (single file)
-	Public Sub AddToJobListView(path As String, Optional ByVal txt As String = " ")
-		Dim p(0) As String
-		p(0) = path
-		AddToJobListView(p, txt)
-	End Sub
-
-	'Update job files counter in tab titel
-	Private Sub UpdateJobTabText()
-		Dim count As Integer = LvGEN.Items.Count
-
-		TabPageGEN.Text = String.Format("Job Files ( {0} / {1} )", _genChecked, count)
-
-		_genCheckAllLock = True
-
-		If _genChecked = 0 Then
-			ChBoxAllGEN.CheckState = CheckState.Unchecked
-		ElseIf _genChecked = count Then
-			ChBoxAllGEN.CheckState = CheckState.Checked
-		Else
-			ChBoxAllGEN.CheckState = CheckState.Indeterminate
-		End If
-
-		_genCheckAllLock = False
-	End Sub
+    'Remove selected file(s) from job list
+    Private Sub RemoveJobFile()
+        Dim lastindx As Integer
+        Dim selIx() As Integer
+        Dim i As Integer
+
+        If LvGEN.SelectedItems.Count < 1 Then
+            If LvGEN.Items.Count = 1 Then
+                LvGEN.Items(0).Selected = True
+            Else
+                Exit Sub
+            End If
+        End If
+
+        LvGEN.BeginUpdate()
+        _checkLock = True
+
+        ReDim selIx(LvGEN.SelectedItems.Count - 1)
+        LvGEN.SelectedIndices.CopyTo(selIx, 0)
+
+        lastindx = LvGEN.SelectedIndices(LvGEN.SelectedItems.Count - 1)
+
+        For i = UBound(selIx) To 0 Step - 1
+            LvGEN.Items.RemoveAt(selIx(i))
+        Next
+
+        If lastindx < LvGEN.Items.Count Then
+            LvGEN.Items(lastindx).Selected = True
+        Else
+            If LvGEN.Items.Count > 0 Then LvGEN.Items(LvGEN.Items.Count - 1).Selected = True
+        End If
+
+        LvGEN.EndUpdate()
+        _checkLock = False
+
+        _genChecked = LvGEN.CheckedItems.Count
+        UpdateJobTabText()
+    End Sub
+
+    'Browse for job file(s) and add to job list with AddToJobListView
+    Private Sub AddJobFile()
+        Dim x As String()
+        Dim chck As Boolean = False
+
+        x = New String() {""}
+
+        Dim extensions As String = "vecto"
+        Dim inputDataExtensions As String() = New String() {"xml"}
+        If (inputDataExtensions.Any()) Then _
+            extensions = String.Join(",", extensions, String.Join(",", inputDataExtensions))
+
+        'STANDARD/BATCH
+        If JobfileFileBrowser.OpenDialog("", True, extensions) Then
+            chck = True
+            x = JobfileFileBrowser.Files
+        End If
+
+        If chck Then AddToJobListView(x)
+    End Sub
+
+    'Open file in list
+    Private Sub OpenJobFile()
+        Dim f As String
+
+        If LvGEN.SelectedItems.Count < 1 Then
+            If LvGEN.Items.Count = 1 Then
+                LvGEN.Items(0).Selected = True
+            Else
+                Exit Sub
+            End If
+        End If
+
+        f = LvGEN.SelectedItems(0).SubItems(0).Text
+        f = FileRepl(f)
+        If Path.GetExtension(f) <> VectoCore.Configuration.Constants.FileExtensions.VectoJobFile Then
+            MsgBox("Job File " + f + " can not be opened in Job Editor. Try importing the file.")
+            Exit Sub
+        End If
+        If Not File.Exists(f) Then
+            MsgBox(f & " not found!")
+        Else
+            OpenVECTOeditor(f)
+        End If
+    End Sub
+
+    'Add File to job listview (multiple files)
+    Private Sub AddToJobListView(path As String(), Optional ByVal txt As String = " ")
+        Dim pDim As Integer
+        Dim p As Integer
+        Dim f As Integer
+        Dim fList As String()
+        Dim fListDim As Integer = - 1
+        Dim listViewItem As ListViewItem
+
+        'If VECTO runs: Cancel operation (because Mode-change during calculation is not very clever)
+        If VectoWorkerV3.IsBusy Then Exit Sub
+
+        pDim = UBound(path)
+        ReDim fList(0)	   'um Nullverweisausnahme-Warnung zu verhindern
+
+        '******************************************* Begin Update '*******************************************
+        LvGEN.BeginUpdate()
+        _checkLock = True
+
+        LvGEN.SelectedIndices.Clear()
+
+        If pDim = 0 Then
+            fListDim = LvGEN.Items.Count - 1
+            ReDim fList(fListDim)
+            For f = 0 To fListDim
+                fList(f) = FileRepl(LvGEN.Items(f).SubItems(0).Text)
+            Next
+        End If
+
+        For p = 0 To pDim
+
+            If pDim = 0 Then
+
+                For f = 0 To fListDim
+
+                    'If file already exists in the list: Do not append (only when a single file)
+                    If UCase(path(p)) = UCase(fList(f)) Then
+
+                        'Status reset
+                        LvGEN.Items(f).SubItems(1).Text = txt
+                        LvGEN.Items(f).BackColor = Color.FromKnownColor(KnownColor.Window)
+                        LvGEN.Items(f).ForeColor = Color.FromKnownColor(KnownColor.WindowText)
+
+                        'Element auswählen und anhaken |@@| Element selection and hook
+                        LvGEN.Items(f).Selected = True
+                        LvGEN.Items(f).Checked = True
+                        LvGEN.Items(f).EnsureVisible()
+
+                        GoTo lbFound
+                    End If
+                Next
+
+            End If
+
+            'Otherwise: Add File (without WorkDir)
+            listViewItem = New ListViewItem(path(p))	'fFileWD(Path(p)))
+            listViewItem.SubItems.Add(" ")
+            listViewItem.Checked = True
+            listViewItem.Selected = True
+            LvGEN.Items.Add(listViewItem)
+            listViewItem.EnsureVisible()
+            lbFound:
+        Next
+
+        LvGEN.EndUpdate()
+        _checkLock = False
+        '******************************************* End Update '*******************************************
+
+        'Number update
+        _genChecked = LvGEN.CheckedItems.Count
+        UpdateJobTabText()
+    End Sub
+
+    'Add File to job listview (single file)
+    Public Sub AddToJobListView(path As String, Optional ByVal txt As String = " ")
+        Dim p(0) As String
+        p(0) = path
+        AddToJobListView(p, txt)
+    End Sub
+
+    'Update job files counter in tab titel
+    Private Sub UpdateJobTabText()
+        Dim count As Integer = LvGEN.Items.Count
+
+        TabPageGEN.Text = String.Format("Job Files ( {0} / {1} )", _genChecked, count)
+
+        _genCheckAllLock = True
+
+        If _genChecked = 0 Then
+            ChBoxAllGEN.CheckState = CheckState.Unchecked
+        ElseIf _genChecked = count Then
+            ChBoxAllGEN.CheckState = CheckState.Checked
+        Else
+            ChBoxAllGEN.CheckState = CheckState.Indeterminate
+        End If
+
+        _genCheckAllLock = False
+    End Sub
 
 
 #Region "Toolstrip"
 
-	'New Job file
-	Private Sub ToolStripBtNew_Click(sender As Object, e As EventArgs) Handles ToolStripBtNew.Click
-		OpenVECTOeditor("<New>")
-	End Sub
-
-	'Open input file
-	Private Sub ToolStripBtOpen_Click(sender As Object, e As EventArgs) Handles ToolStripBtOpen.Click
-
-		If JobfileFileBrowser.OpenDialog("", False, "vecto,vveh,vgbx,veng") Then
-			OpenVectoFile(JobfileFileBrowser.Files(0))
-		End If
-	End Sub
-
-	Private Sub GENEditorToolStripMenuItem1_Click(sender As Object, e As EventArgs) _
-		Handles GENEditorToolStripMenuItem1.Click
-		OpenVECTOeditor("<New>")
-	End Sub
-
-	Private Sub VEHEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles VEHEditorToolStripMenuItem.Click
-		If Not VehicleForm.Visible Then
-			VehicleForm.Show()
-		Else
-			If VehicleForm.WindowState = FormWindowState.Minimized Then VehicleForm.WindowState = FormWindowState.Normal
-			VehicleForm.BringToFront()
-		End If
-	End Sub
-
-	Private Sub EngineEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles EngineEditorToolStripMenuItem.Click
-		If Not EngineForm.Visible Then
-			EngineForm.Show()
-		Else
-			If EngineForm.WindowState = FormWindowState.Minimized Then EngineForm.WindowState = FormWindowState.Normal
-			EngineForm.BringToFront()
-		End If
-	End Sub
-
-	Private Sub GearboxEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles GearboxEditorToolStripMenuItem.Click
-		If Not GearboxForm.Visible Then
-			GearboxForm.Show()
-		Else
-			If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal
-			GearboxForm.BringToFront()
-		End If
-	End Sub
-
-	Private Sub GraphToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles GraphToolStripMenuItem.Click
-		Dim graphForm As New GraphForm
-		graphForm.Show()
-	End Sub
-
-	Private Sub OpenLogToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles OpenLogToolStripMenuItem.Click
-		Process.Start(MyAppPath & "log.txt")
-	End Sub
-
-	Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles SettingsToolStripMenuItem.Click
-		Settings.ShowDialog()
-	End Sub
-
-	Private Sub UserManualToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles UserManualToolStripMenuItem.Click
-		If File.Exists(MyAppPath & "User Manual\help.html") Then
-			Dim defaultBrowserPath As String = BrowserUtils.GetDefaultBrowserPath()
-			Process.Start(defaultBrowserPath, String.Format("""file://{0}{1}""", MyAppPath, "User Manual\help.html"))
-		Else
-			MsgBox("User Manual not found!", MsgBoxStyle.Critical)
-		End If
-	End Sub
-
-	Private Sub UpdateNotesToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles UpdateNotesToolStripMenuItem.Click
-		If File.Exists(MyAppPath & "User Manual\Release Notes.pdf") Then
-			Process.Start(MyAppPath & "User Manual\Release Notes.pdf")
-		Else
-			MsgBox("Release Notes not found!", MsgBoxStyle.Critical)
-		End If
-	End Sub
-
-	Private Sub ReportBugViaCITnetToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles ReportBugViaCITnetToolStripMenuItem.Click
-		JiraDialog.ShowDialog()
-	End Sub
-
-	Private Sub AboutVECTOToolStripMenuItem1_Click(sender As Object, e As EventArgs) _
-		Handles AboutVECTOToolStripMenuItem1.Click
-		AboutBox.ShowDialog()
-	End Sub
+    'New Job file
+    Private Sub ToolStripBtNew_Click(sender As Object, e As EventArgs) Handles ToolStripBtNew.Click
+        OpenVECTOeditor("<New>")
+    End Sub
+
+    'Open input file
+    Private Sub ToolStripBtOpen_Click(sender As Object, e As EventArgs) Handles ToolStripBtOpen.Click
+
+        If JobfileFileBrowser.OpenDialog("", False, "vecto,vveh,vgbx,veng") Then
+            OpenVectoFile(JobfileFileBrowser.Files(0))
+        End If
+    End Sub
+
+    Private Sub GENEditorToolStripMenuItem1_Click(sender As Object, e As EventArgs) _
+        Handles GENEditorToolStripMenuItem1.Click
+        OpenVECTOeditor("<New>")
+    End Sub
+
+    Private Sub VEHEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles VEHEditorToolStripMenuItem.Click
+        If Not VehicleForm.Visible Then
+            VehicleForm.Show()
+        Else
+            If VehicleForm.WindowState = FormWindowState.Minimized Then VehicleForm.WindowState = FormWindowState.Normal
+            VehicleForm.BringToFront()
+        End If
+    End Sub
+
+    Private Sub EngineEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles EngineEditorToolStripMenuItem.Click
+        If Not EngineForm.Visible Then
+            EngineForm.Show()
+        Else
+            If EngineForm.WindowState = FormWindowState.Minimized Then EngineForm.WindowState = FormWindowState.Normal
+            EngineForm.BringToFront()
+        End If
+    End Sub
+
+    Private Sub GearboxEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles GearboxEditorToolStripMenuItem.Click
+        If Not GearboxForm.Visible Then
+            GearboxForm.Show()
+        Else
+            If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal
+            GearboxForm.BringToFront()
+        End If
+    End Sub
+
+    Private Sub GraphToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles GraphToolStripMenuItem.Click
+        Dim graphForm As New GraphForm
+        graphForm.Show()
+    End Sub
+
+    Private Sub OpenLogToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles OpenLogToolStripMenuItem.Click
+        Process.Start(MyAppPath & "log.txt")
+    End Sub
+
+    Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles SettingsToolStripMenuItem.Click
+        Settings.ShowDialog()
+    End Sub
+
+    Private Sub UserManualToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles UserManualToolStripMenuItem.Click
+        If File.Exists(MyAppPath & "User Manual\help.html") Then
+            Dim defaultBrowserPath As String = BrowserUtils.GetDefaultBrowserPath()
+            Process.Start(defaultBrowserPath, String.Format("""file://{0}{1}""", MyAppPath, "User Manual\help.html"))
+        Else
+            MsgBox("User Manual not found!", MsgBoxStyle.Critical)
+        End If
+    End Sub
+
+    Private Sub UpdateNotesToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles UpdateNotesToolStripMenuItem.Click
+        If File.Exists(MyAppPath & "User Manual\Release Notes.pdf") Then
+            Process.Start(MyAppPath & "User Manual\Release Notes.pdf")
+        Else
+            MsgBox("Release Notes not found!", MsgBoxStyle.Critical)
+        End If
+    End Sub
+
+    Private Sub ReportBugViaCITnetToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles ReportBugViaCITnetToolStripMenuItem.Click
+        JiraDialog.ShowDialog()
+    End Sub
+
+    Private Sub AboutVECTOToolStripMenuItem1_Click(sender As Object, e As EventArgs) _
+        Handles AboutVECTOToolStripMenuItem1.Click
+        AboutBox.ShowDialog()
+    End Sub
 
 
 #End Region
 
-	'Move job/cycle file up or down in list view
-	Private Sub MoveItem(ByRef listView As ListView, moveUp As Boolean)
-		Dim x As Integer
-		Dim y As Integer
-		Dim y1 As Integer
-		Dim items() As String
-		Dim check() As Boolean
-		Dim index() As Integer
-		Dim listViewItem As ListViewItem
-
-		If _guIlocked Then Exit Sub
-
-		'Cache Selected Items
-		y1 = listView.SelectedItems.Count - 1
-		ReDim items(y1)
-		ReDim check(y1)
-		ReDim index(y1)
-		y = 0
-		For Each x In listView.SelectedIndices
-			items(y) = listView.Items(x).SubItems(0).Text
-			check(y) = listView.Items(x).Checked
-			If moveUp Then
-				If x = 0 Then Exit Sub
-				index(y) = x - 1
-			Else
-				If x = listView.Items.Count - 1 Then Exit Sub
-				index(y) = x + 1
-			End If
-			y += 1
-		Next
-
-		listView.BeginUpdate()
-
-		'Delete Selected Items
-		For Each listViewItem In listView.SelectedItems
-			listViewItem.Remove()
-		Next
-
-		'Items select and Insert
-		For y = 0 To y1
-			If Not check(y) Then _genChecked += 1
-			listViewItem = listView.Items.Insert(index(y), items(y))
-			listViewItem.SubItems.Add(" ")
-			listViewItem.Checked = check(y)
-			listView.SelectedIndices.Add(index(y))
-		Next
-
-		listView.EndUpdate()
-	End Sub
+    'Move job/cycle file up or down in list view
+    Private Sub MoveItem(ByRef listView As ListView, moveUp As Boolean)
+        Dim x As Integer
+        Dim y As Integer
+        Dim y1 As Integer
+        Dim items() As String
+        Dim check() As Boolean
+        Dim index() As Integer
+        Dim listViewItem As ListViewItem
+
+        If _guIlocked Then Exit Sub
+
+        'Cache Selected Items
+        y1 = listView.SelectedItems.Count - 1
+        ReDim items(y1)
+        ReDim check(y1)
+        ReDim index(y1)
+        y = 0
+        For Each x In listView.SelectedIndices
+            items(y) = listView.Items(x).SubItems(0).Text
+            check(y) = listView.Items(x).Checked
+            If moveUp Then
+                If x = 0 Then Exit Sub
+                index(y) = x - 1
+            Else
+                If x = listView.Items.Count - 1 Then Exit Sub
+                index(y) = x + 1
+            End If
+            y += 1
+        Next
+
+        listView.BeginUpdate()
+
+        'Delete Selected Items
+        For Each listViewItem In listView.SelectedItems
+            listViewItem.Remove()
+        Next
+
+        'Items select and Insert
+        For y = 0 To y1
+            If Not check(y) Then _genChecked += 1
+            listViewItem = listView.Items.Insert(index(y), items(y))
+            listViewItem.SubItems.Add(" ")
+            listViewItem.Checked = check(y)
+            listView.SelectedIndices.Add(index(y))
+        Next
+
+        listView.EndUpdate()
+    End Sub
 
 
 #Region "job/cycle file List - Context Menu"
 
-	'Save List
-	Private Sub SaveListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles SaveListToolStripMenuItem.Click
-		If TextFileBrowser.SaveDialog("") Then
-			If _conMenTarJob Then
-				_jobListView.SaveList(TextFileBrowser.Files(0))
-			Else
-				_cycleListView.SaveList(TextFileBrowser.Files(0))
-			End If
-		End If
-	End Sub
+    'Save List
+    Private Sub SaveListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles SaveListToolStripMenuItem.Click
+        If TextFileBrowser.SaveDialog("") Then
+            If _conMenTarJob Then
+                _jobListView.SaveList(TextFileBrowser.Files(0))
+            Else
+                _cycleListView.SaveList(TextFileBrowser.Files(0))
+            End If
+        End If
+    End Sub
 
-	'Load List
-	Private Sub LoadListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles LoadListToolStripMenuItem.Click
+    'Load List
+    Private Sub LoadListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles LoadListToolStripMenuItem.Click
 
-		If _guIlocked Then Exit Sub
+        If _guIlocked Then Exit Sub
 
-		If TextFileBrowser.OpenDialog("") Then
+        If TextFileBrowser.OpenDialog("") Then
 
-			If _conMenTarJob Then 'GEN
-				_jobListView.LoadList(TextFileBrowser.Files(0))
-				_genChecked = LvGEN.CheckedItems.Count
-				UpdateJobTabText()
-			Else 'DRI
-				'Mode toggle 
-				_cycleListView.LoadList(TextFileBrowser.Files(0))
-			End If
+            If _conMenTarJob Then 'GEN
+                _jobListView.LoadList(TextFileBrowser.Files(0))
+                _genChecked = LvGEN.CheckedItems.Count
+                UpdateJobTabText()
+            Else 'DRI
+                'Mode toggle 
+                _cycleListView.LoadList(TextFileBrowser.Files(0))
+            End If
 
-		End If
-	End Sub
+        End If
+    End Sub
 
-	'Load Default List
-	Private Sub LoadDefaultListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles LoadDefaultListToolStripMenuItem.Click
+    'Load Default List
+    Private Sub LoadDefaultListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles LoadDefaultListToolStripMenuItem.Click
 
-		If _guIlocked Then Exit Sub
+        If _guIlocked Then Exit Sub
 
-		If _conMenTarJob Then
+        If _conMenTarJob Then
 
-			_jobListView.LoadList()
+            _jobListView.LoadList()
 
-			_genChecked = LvGEN.CheckedItems.Count
-			UpdateJobTabText()
-		Else
-			_cycleListView.LoadList()
+            _genChecked = LvGEN.CheckedItems.Count
+            UpdateJobTabText()
+        Else
+            _cycleListView.LoadList()
 
-		End If
-	End Sub
+        End If
+    End Sub
 
-	'Clear List
-	Private Sub ClearListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles ClearListToolStripMenuItem.Click
+    'Clear List
+    Private Sub ClearListToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles ClearListToolStripMenuItem.Click
 
-		If _guIlocked Then Exit Sub
+        If _guIlocked Then Exit Sub
 
-		_conMenTarget.Items.Clear()
-		If _conMenTarJob Then
-			_genChecked = LvGEN.CheckedItems.Count
-			UpdateJobTabText()
-		End If
-	End Sub
+        _conMenTarget.Items.Clear()
+        If _conMenTarJob Then
+            _genChecked = LvGEN.CheckedItems.Count
+            UpdateJobTabText()
+        End If
+    End Sub
 
 #End Region
 
-	'VECTO Start button - Calls VECTO_Launcher or aborts calculation
-
-	Private Sub btStartV3_Click(sender As Object, e As EventArgs) Handles btStartV3.Click
-		If Not VectoWorkerV3.IsBusy Then
-			'Save Lists for Crash
-			SaveFileLists()
-
-			LvGEN.SelectedItems.Clear()
-
-			If LvGEN.CheckedItems.Count = 0 Then
-				GUIMsg(MessageType.Err, "No job file selected!")
-				Exit Sub
-			End If
-
-			Status("Launching VECTO ...")
-			JobFileList.Clear()
-			JobFileList.AddRange(
-				From listViewItem As ListViewItem In LvGEN.CheckedItems.Cast(Of ListViewItem)()
-									Select fFileRepl = FileRepl(listViewItem.SubItems(0).Text))
-
-			SetOptions()
-			Cfg.Save()
-			ClearMsg()
-
-			LockGUI(True)
-			btStartV3.Enabled = True
-			btStartV3.Text = "STOP"
-			btStartV3.Image = My.Resources.Stop_icon
-
-			ToolStripProgBarOverall.Value = 0
-			ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous
-			ToolStripProgBarOverall.Visible = True
-
-			VectoWorkerV3.RunWorkerAsync()
-		Else
-			btStartV3.Enabled = False
-			btStartV3.Text = "Aborting..."
-			btStartV3.Image = My.Resources.Play_icon_gray
-			VectoWorkerV3.CancelAsync()
-		End If
-	End Sub
-
-
-	Private Sub VectoWorkerV3_OnDoWork(theSender As Object, e As DoWorkEventArgs)
-		Dim sender As BackgroundWorker = TryCast(theSender, BackgroundWorker)
-		If sender Is Nothing Then Exit Sub
-
-		AllowSleepOff()
-
-		Dim sumFileWriter As FileOutputWriter = New FileOutputWriter(JobFileList(0))
-		Dim sumWriter As SummaryDataContainer = New SummaryDataContainer(sumFileWriter)
-		Dim jobContainer As JobContainer = New JobContainer(sumWriter)
-
-		Dim mode As ExecutionMode
-		If Cfg.DeclMode Then
-			mode = ExecutionMode.Declaration
-		Else
-			mode = ExecutionMode.Engineering
-			Physics.AirDensity = Cfg.AirDensity.SI(Of KilogramPerCubicMeter)()
-		End If
-
-		'dictionary of run-identifiers to fileWriters (used for output directory of modfile)
-		Dim fileWriters As Dictionary(Of Integer, FileOutputWriter) = New Dictionary(Of Integer, FileOutputWriter)
-
-		'list of finished runs
-		Dim finishedRuns As List(Of Integer) = New List(Of Integer)
-		For Each jobFile As String In JobFileList
-			Try
-				sender.ReportProgress(0,
-									New VectoProgress With {.Target = "ListBox", .Message = "Reading File " + jobFile, .Link = jobFile})
-
-				Dim extension As String = Path.GetExtension(jobFile)
-				Dim input As IInputDataProvider = Nothing
-				Select Case extension
-					Case VectoCore.Configuration.Constants.FileExtensions.VectoJobFile
-						input = JSONInputDataFactory.ReadJsonJob(jobFile)
-					Case ".xml"
-						Dim xDocument As XDocument = xDocument.Load(jobFile)
-						Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName)
-						Select Case rootNode
-							Case XMLNames.VectoInputEngineering
-								input = New XMLEngineeringInputDataProvider(jobFile, True)
-							Case XMLNames.VectoInputDeclaration
-								input = New XMLDeclarationInputDataProvider(XmlReader.Create(jobFile), True)
-						End Select
-				End Select
-
-				If input Is Nothing Then
-					sender.ReportProgress(0,
-										New VectoProgress With {.Target = "ListBoxError", .Message = "No Input Provider for job: " + jobFile})
-					Continue For
-				End If
-
-				Dim fileWriter As FileOutputWriter = New FileOutputWriter(jobFile)
-
-				Dim runsFactory As SimulatorFactory = New SimulatorFactory(mode, input, fileWriter)
-				runsFactory.WriteModalResults = Cfg.ModOut
-				runsFactory.ModalResults1Hz = Cfg.Mod1Hz
-				runsFactory.Validate = cbValidateRunData.Checked
-				runsFactory.ActualModalData = cbActVmod.Checked
-
-				For Each runId As Integer In jobContainer.AddRuns(runsFactory)
-					fileWriters.Add(runId, fileWriter)
-				Next
-
-
-				sender.ReportProgress(0,
-									New VectoProgress With {.Target = "ListBox", .Message = "Finished Reading Data for job: " + jobFile})
-
-			Catch ex As Exception
-				MsgBox(String.Format("ERROR running job {0}: {1}", jobFile, ex.Message), MsgBoxStyle.Critical)
-				sender.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError", .Message = ex.Message})
-				Return
-			End Try
-		Next
-
-		'print detected cycles
-		For Each cycle As JobContainer.CycleTypeDescription In jobContainer.GetCycleTypes()
-			sender.ReportProgress(0,
-								New VectoProgress _
-									With {.Target = "ListBox", .Message = String.Format("Detected Cycle {0}: {1}", cycle.Name, cycle.CycleType)})
-		Next
-
-		sender.ReportProgress(0, New VectoProgress With {.Target = "ListBox",
-								.Message = _
-								String.Format("Starting Simulation ({0} Jobs, {1} Runs)", JobFileList.Count, jobContainer.GetProgress().Count)})
-
-		jobContainer.Execute(True)
-
-		Dim start As DateTime = DateTime.Now()
-
-		While Not jobContainer.AllCompleted
-			'cancel the job if thread is interrupted (button "Stop" clicked)
-			If sender.CancellationPending Then
-				jobContainer.Cancel()
-				Return
-			End If
-
-			Dim progress As Dictionary(Of Integer, JobContainer.ProgressEntry) = jobContainer.GetProgress()
-			Dim sumProgress As Double = progress.Sum(Function(pair) pair.Value.Progress)
-			Dim duration As Double = (DateTime.Now() - start).TotalSeconds
-
-			sender.ReportProgress(Convert.ToInt32((sumProgress * 100.0) / progress.Count),
-								New VectoProgress With {.Target = "Status",
-									.Message = _
-									String.Format("Duration: {0:0}s, Current Progress: {1:P} ({2})", duration, sumProgress / progress.Count,
-												String.Join(", ", progress.Select(Function(pair) String.Format("{0,4:P}", pair.Value.Progress))))})
-
-			Dim justFinished As Dictionary(Of Integer, JobContainer.ProgressEntry) =
-					progress.Where(Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)).ToDictionary(
-						Function(pair) pair.Key, Function(pair) pair.Value)
-			PrintRuns(justFinished, fileWriters)
-			finishedRuns.AddRange(justFinished.Select(Function(pair) pair.Key))
-			Thread.Sleep(100)
-		End While
-
-		Dim remainingRuns As Dictionary(Of Integer, JobContainer.ProgressEntry) =
-				jobContainer.GetProgress().Where(Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)).
-				ToDictionary(Function(pair) pair.Key, Function(pair) pair.Value)
-		PrintRuns(remainingRuns, fileWriters)
-
-		finishedRuns.Clear()
-		fileWriters.Clear()
-
-		For Each progressEntry As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In jobContainer.GetProgress()
-			sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
-									.Message = String.Format("{0,-60} {1,8:P} {2,10:F2}s - {3}",
-															String.Format("{0} {1} {2}", progressEntry.Value.RunName, progressEntry.Value.CycleName,
-																		progressEntry.Value.RunSuffix),
-															progressEntry.Value.Progress, progressEntry.Value.ExecTime / 1000.0,
-															IIf(progressEntry.Value.Success, "Success", "Aborted"))})
-			If (Not progressEntry.Value.Success) Then
-				sender.ReportProgress(100,
-									New VectoProgress With {.Target = "ListBox", .Message = progressEntry.Value.Error.Message})
-			End If
-
-		Next
-
-		For Each job As String In JobFileList
-			Dim report As String = New FileOutputWriter(job).XMLFullReportName
-			If File.Exists(report) Then
-				sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
-										.Message = String.Format("XML Manufacturer Report for '{0}' written to {1}", Path.GetFileName(job), report),
-										.Link = "<XML>" + report})
-			End If
-			report = New FileOutputWriter(job).XMLCustomerReportName
-			If File.Exists(report) Then
-				sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
-										.Message = String.Format("XML Customer Report for '{0}' written to {1}", Path.GetFileName(job), report),
-										.Link = "<XML>" + report})
-			End If
-		Next
-
-		If File.Exists(sumFileWriter.SumFileName) Then
-			sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
-									.Message = String.Format("Sum File written to {0}", sumFileWriter.SumFileName),
-									.Link = sumFileWriter.SumFileName})
-		End If
-
-		sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
-								.Message = String.Format("Simulation Finished in {0:0}s", (DateTime.Now() - start).TotalSeconds)})
-	End Sub
-
-
-	Private Shared Sub PrintRuns(progress As Dictionary(Of Integer, JobContainer.ProgressEntry),
-								fileWriters As Dictionary(Of Integer, FileOutputWriter))
-		For Each p As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In progress
-			Dim modFilename As String = fileWriters(p.Key).GetModDataFileName(p.Value.RunName, p.Value.CycleName,
-																			p.Value.RunSuffix + If(Cfg.Mod1Hz, "_1Hz", ""))
-
-			Dim runName As String = String.Format("{0} {1} {2}", p.Value.RunName, p.Value.CycleName, p.Value.RunSuffix)
-
-			If Not p.Value.Error Is Nothing Then
-				VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError",
-												.Message = String.Format("Finished Run {0} with ERROR: {1}", runName, p.Value.Error.Message),
-												.Link = modFilename})
-			Else
-				VectoWorkerV3.ReportProgress(0,
-											New VectoProgress _
-												With {.Target = "ListBox", .Message = String.Format("Finished Run {0} successfully.", runName)})
-			End If
-
-			If (File.Exists(modFilename)) Then
-				VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBox",
-												.Message = String.Format("Run {0}: Modal Results written to {1}", runName, modFilename), .Link = modFilename
-												})
-			End If
-		Next
-	End Sub
-
-	Private Sub VectoWorkerV3_OnProgressChanged(sender As Object, e As ProgressChangedEventArgs)
-		Dim progress As VectoProgress = TryCast(e.UserState, VectoProgress)
-		If progress Is Nothing Then Exit Sub
-
-		Select Case progress.Target
-			Case "ListBox"
-				If progress.Link Is Nothing Then
-					MsgToForm(MessageType.Normal, progress.Message, "", "")
-				Else
-					MsgToForm(MessageType.Normal, progress.Message, "", progress.Link)
-				End If
-			Case "ListBoxWarning"
-				MsgToForm(MessageType.Warn, progress.Message, "", "")
-				Return
-			Case "ListBoxError"
-				MsgToForm(MessageType.Err, progress.Message, "", "")
-				Return
-			Case "Status"
-				Status(progress.Message)
-		End Select
-
-		ToolStripProgBarOverall.Value = e.ProgressPercentage
-	End Sub
-
-	Private Sub VectoWorkerV3_OnRunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
-
-		'Progbar reset
-		ToolStripProgBarOverall.Visible = False
-		ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous
-		ToolStripProgBarOverall.Value = 0
-		ProgSecStop()
-
-		LvGEN.SelectedIndices.Clear()
-
-		'ShutDown when Unexpected Error
-		If e.Error IsNot Nothing Then
-			MsgBox("An Unexpected Error occurred!" & ChrW(10) & ChrW(10) &
-					e.Error.Message.ToString, MsgBoxStyle.Critical, "Unexpected Error")
-			LogFile.WriteToLog(MessageType.Err, ">>>Unexpected Error:" & e.Error.ToString())
-		End If
-
-		'Options enable / GUI reset
-		LockGUI(False)
-		btStartV3.Text = "START"
-		btStartV3.Image = My.Resources.Play_icon
-		Status(_lastModeName & " Mode")
-
-		'SLEEP reactivate
-		AllowSleepOn()
-	End Sub
-
-
-	Private Sub ModeUpdate()
-
-		'Save lists
-		_jobListView.SaveList()
-
-		'GUI changes according to current mode
-
-		If Cfg.DeclMode Then
-			_lastModeName = "Declaration"
-		Else
-			_lastModeName = "Engineering"
-		End If
-
-		'Update job counter
-		_genChecked = LvGEN.CheckedItems.Count
-		UpdateJobTabText()
-
-		'Status label
-		Status(_lastModeName & " Mode")
-	End Sub
-
-	'Class for ListView control - Job and cycle lists
-	Private Class FileListView
-		Private ReadOnly _filePath As String
-		Private _loadedDefault As Boolean
-		Public LVbox As ListView
-
-		Public Sub New(path As String)
-			_filePath = path
-			_loadedDefault = False
-		End Sub
-
-		Public Sub SaveList(Optional ByVal path As String = "")
-			Dim x As Integer
-			If path = "" Then
-				If Not _loadedDefault Then Exit Sub
-				path = _filePath
-			End If
-			Dim file As StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(path, False, Encoding.UTF8)
-			For x = 1 To LVbox.Items.Count
-				file.WriteLine(String.Join("?", LVbox.Items(x - 1).SubItems(0).Text, Math.Abs(CInt(LVbox.Items(x - 1).Checked))))
-			Next
-			file.Close()
-		End Sub
-
-		Public Sub LoadList(Optional ByVal path As String = "")
-			'Dim line As String()
-			Dim noCheck As Boolean
-			'Dim file As CsvFile
-			Dim listViewItem As ListViewItem
-
-			If path = "" Then
-				path = _filePath
-				_loadedDefault = True
-			End If
-
-			'file = New CsvFile
-
-			If Not File.Exists(path) Then
-				If Not _loadedDefault Then GUIMsg(MessageType.Err, "Cannot open file (" & path & ")!")
-				Exit Sub
-			End If
-
-			MainForm._checkLock = True
-			LVbox.BeginUpdate()
-
-			LVbox.Items.Clear()
-
-			noCheck = False
-			Dim reader As TextFieldParser = New TextFieldParser(path, Encoding.Default)
-			reader.TextFieldType = FieldType.Delimited
-			reader.Delimiters = New String() {"?"}
-
-			Do While Not reader.EndOfData
-				Dim line As String() = reader.ReadFields()
-				If Strings.Left(Trim(line(0)), 1) = "#" Then Continue Do
-
-				listViewItem = New ListViewItem(line(0))
-				listViewItem.SubItems.Add(" ")
-
-				If noCheck Then
-					listViewItem.Checked = True
-				Else
-					If UBound(line) < 1 Then
-						noCheck = True
-						listViewItem.Checked = True
-					Else
-						If IsNumeric(line(1)) Then
-							listViewItem.Checked = CBool(line(1))
-						Else
-							listViewItem.Checked = True
-						End If
-					End If
-				End If
-				LVbox.Items.Add(listViewItem)
-			Loop
-
-			reader.Close()
-
-			LVbox.EndUpdate()
-			MainForm._checkLock = False
-
-			If LVbox.Items.Count > 0 Then LVbox.Items(LVbox.Items.Count - 1).EnsureVisible()
-		End Sub
-	End Class
-
-
-	'Open Job Editor and open file (or new file)
-	Friend Sub OpenVECTOeditor(x As String)
-
-		If x = "<New>" Then
-			ShowVectoJobForm()
-			VectoJobForm.VectoNew()
-		ElseIf x = "<VTP>" Then
-			ShowVectoEPTPJobForm()
-			VectoVTPJobForm.VectoNew()
-		Else
-			Try
-				Dim engJob As IVTPEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x), IVTPEngineeringInputDataProvider)
-			    Dim declJob As IVTPDeclarationInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x), IVTPDeclarationInputDataProvider)
-				If engJob Is Nothing AndAlso declJob is Nothing Then
-					ShowVectoJobForm()
-					VectoJobForm.VECTOload2Form(x)
-				Else
-					ShowVectoEPTPJobForm()
-					VectoVTPJobForm.VECTOload2Form(x)
-				End If
-			Catch ex As Exception
-				MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vecto Job File")
-			End Try
-		End If
-
-		VectoJobForm.Activate()
-	End Sub
-
-	Private Sub ShowVectoJobForm()
-		If Not VectoJobForm.Visible Then
-			VectoJobForm.Show()
-		Else
-			If VectoJobForm.WindowState = FormWindowState.Minimized Then VectoJobForm.WindowState = FormWindowState.Normal
-			VectoJobForm.BringToFront()
-		End If
-	End Sub
-
-	Private Sub ShowVectoEPTPJobForm()
-		If Not VectoVTPJobForm.Visible Then
-			VectoVTPJobForm.Show()
-		Else
-			If VectoVTPJobForm.WindowState = FormWindowState.Minimized Then _
-				VectoVTPJobForm.WindowState = FormWindowState.Normal
-			VectoVTPJobForm.BringToFront()
-		End If
-	End Sub
-
-	'Save job and cycle file lists
-	Private Sub SaveFileLists()
-		_jobListView.SaveList()
-		'If Cfg.BatchMode Then CycleListView.SaveList()
-	End Sub
+    'VECTO Start button - Calls VECTO_Launcher or aborts calculation
+
+    Private Sub btStartV3_Click(sender As Object, e As EventArgs) Handles btStartV3.Click
+        If Not VectoWorkerV3.IsBusy Then
+            'Save Lists for Crash
+            SaveFileLists()
+
+            LvGEN.SelectedItems.Clear()
+
+            If LvGEN.CheckedItems.Count = 0 Then
+                GUIMsg(MessageType.Err, "No job file selected!")
+                Exit Sub
+            End If
+
+            Status("Launching VECTO ...")
+            JobFileList.Clear()
+            JobFileList.AddRange(
+                From listViewItem As ListViewItem In LvGEN.CheckedItems.Cast (Of ListViewItem)()
+                                    Select fFileRepl = FileRepl(listViewItem.SubItems(0).Text))
+
+            SetOptions()
+            Cfg.Save()
+            ClearMsg()
+
+            LockGUI(True)
+            btStartV3.Enabled = True
+            btStartV3.Text = "STOP"
+            btStartV3.Image = My.Resources.Stop_icon
+
+            ToolStripProgBarOverall.Value = 0
+            ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous
+            ToolStripProgBarOverall.Visible = True
+
+            VectoWorkerV3.RunWorkerAsync()
+        Else
+            btStartV3.Enabled = False
+            btStartV3.Text = "Aborting..."
+            btStartV3.Image = My.Resources.Play_icon_gray
+            VectoWorkerV3.CancelAsync()
+        End If
+    End Sub
+
+
+    Private Sub VectoWorkerV3_OnDoWork(theSender As Object, e As DoWorkEventArgs)
+        Dim sender As BackgroundWorker = TryCast(theSender, BackgroundWorker)
+        If sender Is Nothing Then Exit Sub
+
+        AllowSleepOff()
+
+        Dim sumFileWriter As FileOutputWriter = New FileOutputWriter(JobFileList(0))
+        Dim sumWriter As SummaryDataContainer = New SummaryDataContainer(sumFileWriter)
+        Dim jobContainer As JobContainer = New JobContainer(sumWriter)
+
+        Dim mode As ExecutionMode
+        If Cfg.DeclMode Then
+            mode = ExecutionMode.Declaration
+        Else
+            mode = ExecutionMode.Engineering
+            Physics.AirDensity = Cfg.AirDensity.SI (Of KilogramPerCubicMeter)()
+        End If
+
+        'dictionary of run-identifiers to fileWriters (used for output directory of modfile)
+        Dim fileWriters As Dictionary(Of Integer, FileOutputWriter) = New Dictionary(Of Integer, FileOutputWriter)
+
+        'list of finished runs
+        Dim finishedRuns As List(Of Integer) = New List(Of Integer)
+        For Each jobFile As String In JobFileList
+            Try
+                sender.ReportProgress(0,
+                                      New VectoProgress _
+                                         With {.Target = "ListBox", .Message = "Reading File " + jobFile,
+                                         .Link = jobFile})
+
+                Dim extension As String = Path.GetExtension(jobFile)
+                Dim input As IInputDataProvider = Nothing
+                Select Case extension
+                    Case VectoCore.Configuration.Constants.FileExtensions.VectoJobFile
+                        input = JSONInputDataFactory.ReadJsonJob(jobFile)
+                    Case ".xml"
+                        Dim xDocument As XDocument = xDocument.Load(jobFile)
+                        Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName)
+                        Select Case rootNode
+                            Case XMLNames.VectoInputEngineering
+                                input = New XMLEngineeringInputDataProvider(jobFile, True)
+                            Case XMLNames.VectoInputDeclaration
+                                input = New XMLDeclarationInputDataProvider(XmlReader.Create(jobFile), True)
+                        End Select
+                End Select
+
+                If input Is Nothing Then
+                    sender.ReportProgress(0,
+                                          New VectoProgress _
+                                             With {.Target = "ListBoxError",
+                                             .Message = "No Input Provider for job: " + jobFile})
+                    Continue For
+                End If
+
+                Dim fileWriter As FileOutputWriter = New FileOutputWriter(jobFile)
+
+                Dim runsFactory As SimulatorFactory = New SimulatorFactory(mode, input, fileWriter)
+                runsFactory.WriteModalResults = Cfg.ModOut
+                runsFactory.ModalResults1Hz = Cfg.Mod1Hz
+                runsFactory.Validate = cbValidateRunData.Checked
+                runsFactory.ActualModalData = cbActVmod.Checked
+
+                For Each runId As Integer In jobContainer.AddRuns(runsFactory)
+                    fileWriters.Add(runId, fileWriter)
+                Next
+
+
+                sender.ReportProgress(0,
+                                      New VectoProgress _
+                                         With {.Target = "ListBox",
+                                         .Message = "Finished Reading Data for job: " + jobFile})
+
+            Catch ex As Exception
+                MsgBox(String.Format("ERROR running job {0}: {1}", jobFile, ex.Message), MsgBoxStyle.Critical)
+                sender.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError", .Message = ex.Message})
+                Return
+            End Try
+        Next
+
+        'print detected cycles
+        For Each cycle As JobContainer.CycleTypeDescription In jobContainer.GetCycleTypes()
+            sender.ReportProgress(0,
+                                  New VectoProgress _
+                                     With {.Target = "ListBox",
+                                     .Message = String.Format("Detected Cycle {0}: {1}", cycle.Name, cycle.CycleType)})
+        Next
+
+        sender.ReportProgress(0, New VectoProgress With {.Target = "ListBox",
+                                 .Message = _
+                                 String.Format("Starting Simulation ({0} Jobs, {1} Runs)", JobFileList.Count,
+                                               jobContainer.GetProgress().Count)})
+
+        jobContainer.Execute(True)
+
+        Dim start As DateTime = DateTime.Now()
+
+        While Not jobContainer.AllCompleted
+            'cancel the job if thread is interrupted (button "Stop" clicked)
+            If sender.CancellationPending Then
+                jobContainer.Cancel()
+                Return
+            End If
+
+            Dim progress As Dictionary(Of Integer, JobContainer.ProgressEntry) = jobContainer.GetProgress()
+            Dim sumProgress As Double = progress.Sum(Function(pair) pair.Value.Progress)
+            Dim duration As Double = (DateTime.Now() - start).TotalSeconds
+
+            sender.ReportProgress(Convert.ToInt32((sumProgress*100.0)/progress.Count),
+                                  New VectoProgress With {.Target = "Status",
+                                     .Message = _
+                                     String.Format("Duration: {0:0}s, Current Progress: {1:P} ({2})", duration,
+                                                   sumProgress/progress.Count,
+                                                   String.Join(", ",
+                                                               progress.Select(
+                                                                   Function(pair) _
+                                                                                  String.Format("{0,4:P}",
+                                                                                                pair.Value.Progress))))})
+
+            Dim justFinished As Dictionary(Of Integer, JobContainer.ProgressEntry) =
+                    progress.Where(Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)).
+                    ToDictionary(
+                        Function(pair) pair.Key, Function(pair) pair.Value)
+            PrintRuns(justFinished, fileWriters)
+            finishedRuns.AddRange(justFinished.Select(Function(pair) pair.Key))
+            Thread.Sleep(100)
+        End While
+
+        Dim remainingRuns As Dictionary(Of Integer, JobContainer.ProgressEntry) =
+                jobContainer.GetProgress().Where(
+                    Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)).
+                ToDictionary(Function(pair) pair.Key, Function(pair) pair.Value)
+        PrintRuns(remainingRuns, fileWriters)
+
+        finishedRuns.Clear()
+        fileWriters.Clear()
+
+        For Each progressEntry As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In jobContainer.GetProgress()
+            sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
+                                     .Message = String.Format("{0,-60} {1,8:P} {2,10:F2}s - {3}",
+                                                              String.Format("{0} {1} {2}", progressEntry.Value.RunName,
+                                                                            progressEntry.Value.CycleName,
+                                                                            progressEntry.Value.RunSuffix),
+                                                              progressEntry.Value.Progress,
+                                                              progressEntry.Value.ExecTime/1000.0,
+                                                              IIf(progressEntry.Value.Success, "Success", "Aborted"))})
+            If (Not progressEntry.Value.Success) Then
+                sender.ReportProgress(100,
+                                      New VectoProgress _
+                                         With {.Target = "ListBox", .Message = progressEntry.Value.Error.Message})
+            End If
+
+        Next
+
+        For Each job As String In JobFileList
+            dim w as FileOutputWriter = new FileOutputWriter(job)
+            For Each entry as KeyValuePair(Of string, string) In _
+                new Dictionary(Of string, string) _
+                    from {{w.XMLFullReportName, "XML Manufacturer Report"}, {w.XMLCustomerReportName, "Customer Report"},
+                        {w.XMLVTPReportName, "VTP Report"}}
+                If File.Exists(entry.Key) Then
+                    sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
+                                             .Message =
+                                             String.Format("{2} for '{0}' written to {1}", Path.GetFileName(job),
+                                                           entry.Key, entry.Value),
+                                             .Link = "<XML>" + entry.Key})
+                End If
+            Next
+        Next
+
+        If File.Exists(sumFileWriter.SumFileName) Then
+            sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
+                                     .Message = String.Format("Sum File written to {0}", sumFileWriter.SumFileName),
+                                     .Link = sumFileWriter.SumFileName})
+        End If
+
+        sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox",
+                                 .Message =
+                                 String.Format("Simulation Finished in {0:0}s", (DateTime.Now() - start).TotalSeconds)})
+    End Sub
+
+
+    Private Shared Sub PrintRuns(progress As Dictionary(Of Integer, JobContainer.ProgressEntry),
+                                 fileWriters As Dictionary(Of Integer, FileOutputWriter))
+        For Each p As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In progress
+            Dim modFilename As String = fileWriters(p.Key).GetModDataFileName(p.Value.RunName, p.Value.CycleName,
+                                                                              p.Value.RunSuffix +
+                                                                              If(Cfg.Mod1Hz, "_1Hz", ""))
+
+            Dim runName As String = String.Format("{0} {1} {2}", p.Value.RunName, p.Value.CycleName, p.Value.RunSuffix)
+
+            If Not p.Value.Error Is Nothing Then
+                VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError",
+                                                .Message =
+                                                String.Format("Finished Run {0} with ERROR: {1}", runName,
+                                                              p.Value.Error.Message),
+                                                .Link = modFilename})
+            Else
+                VectoWorkerV3.ReportProgress(0,
+                                             New VectoProgress _
+                                                With {.Target = "ListBox",
+                                                .Message = String.Format("Finished Run {0} successfully.", runName)})
+            End If
+
+            If (File.Exists(modFilename)) Then
+                VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBox",
+                                                .Message =
+                                                String.Format("Run {0}: Modal Results written to {1}", runName,
+                                                              modFilename), .Link = modFilename
+                                                })
+            End If
+        Next
+    End Sub
+
+    Private Sub VectoWorkerV3_OnProgressChanged(sender As Object, e As ProgressChangedEventArgs)
+        Dim progress As VectoProgress = TryCast(e.UserState, VectoProgress)
+        If progress Is Nothing Then Exit Sub
+
+        Select Case progress.Target
+            Case "ListBox"
+                If progress.Link Is Nothing Then
+                    MsgToForm(MessageType.Normal, progress.Message, "", "")
+                Else
+                    MsgToForm(MessageType.Normal, progress.Message, "", progress.Link)
+                End If
+            Case "ListBoxWarning"
+                MsgToForm(MessageType.Warn, progress.Message, "", "")
+                Return
+            Case "ListBoxError"
+                MsgToForm(MessageType.Err, progress.Message, "", "")
+                Return
+            Case "Status"
+                Status(progress.Message)
+        End Select
+
+        ToolStripProgBarOverall.Value = e.ProgressPercentage
+    End Sub
+
+    Private Sub VectoWorkerV3_OnRunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
+
+        'Progbar reset
+        ToolStripProgBarOverall.Visible = False
+        ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous
+        ToolStripProgBarOverall.Value = 0
+        ProgSecStop()
+
+        LvGEN.SelectedIndices.Clear()
+
+        'ShutDown when Unexpected Error
+        If e.Error IsNot Nothing Then
+            MsgBox("An Unexpected Error occurred!" & ChrW(10) & ChrW(10) &
+                   e.Error.Message.ToString, MsgBoxStyle.Critical, "Unexpected Error")
+            LogFile.WriteToLog(MessageType.Err, ">>>Unexpected Error:" & e.Error.ToString())
+        End If
+
+        'Options enable / GUI reset
+        LockGUI(False)
+        btStartV3.Text = "START"
+        btStartV3.Image = My.Resources.Play_icon
+        Status(_lastModeName & " Mode")
+
+        'SLEEP reactivate
+        AllowSleepOn()
+    End Sub
+
+
+    Private Sub ModeUpdate()
+
+        'Save lists
+        _jobListView.SaveList()
+
+        'GUI changes according to current mode
+
+        If Cfg.DeclMode Then
+            _lastModeName = "Declaration"
+        Else
+            _lastModeName = "Engineering"
+        End If
+
+        'Update job counter
+        _genChecked = LvGEN.CheckedItems.Count
+        UpdateJobTabText()
+
+        'Status label
+        Status(_lastModeName & " Mode")
+    End Sub
+
+    'Class for ListView control - Job and cycle lists
+    Private Class FileListView
+        Private ReadOnly _filePath As String
+        Private _loadedDefault As Boolean
+        Public LVbox As ListView
+
+        Public Sub New(path As String)
+            _filePath = path
+            _loadedDefault = False
+        End Sub
+
+        Public Sub SaveList(Optional ByVal path As String = "")
+            Dim x As Integer
+            If path = "" Then
+                If Not _loadedDefault Then Exit Sub
+                path = _filePath
+            End If
+            Dim file As StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(path, False, Encoding.UTF8)
+            For x = 1 To LVbox.Items.Count
+                file.WriteLine(String.Join("?", LVbox.Items(x - 1).SubItems(0).Text,
+                                           Math.Abs(CInt(LVbox.Items(x - 1).Checked))))
+            Next
+            file.Close()
+        End Sub
+
+        Public Sub LoadList(Optional ByVal path As String = "")
+            'Dim line As String()
+            Dim noCheck As Boolean
+            'Dim file As CsvFile
+            Dim listViewItem As ListViewItem
+
+            If path = "" Then
+                path = _filePath
+                _loadedDefault = True
+            End If
+
+            'file = New CsvFile
+
+            If Not File.Exists(path) Then
+                If Not _loadedDefault Then GUIMsg(MessageType.Err, "Cannot open file (" & path & ")!")
+                Exit Sub
+            End If
+
+            MainForm._checkLock = True
+            LVbox.BeginUpdate()
+
+            LVbox.Items.Clear()
+
+            noCheck = False
+            Dim reader As TextFieldParser = New TextFieldParser(path, Encoding.Default)
+            reader.TextFieldType = FieldType.Delimited
+            reader.Delimiters = New String() {"?"}
+
+            Do While Not reader.EndOfData
+                Dim line As String() = reader.ReadFields()
+                If Strings.Left(Trim(line(0)), 1) = "#" Then Continue Do
+
+                listViewItem = New ListViewItem(line(0))
+                listViewItem.SubItems.Add(" ")
+
+                If noCheck Then
+                    listViewItem.Checked = True
+                Else
+                    If UBound(line) < 1 Then
+                        noCheck = True
+                        listViewItem.Checked = True
+                    Else
+                        If IsNumeric(line(1)) Then
+                            listViewItem.Checked = CBool(line(1))
+                        Else
+                            listViewItem.Checked = True
+                        End If
+                    End If
+                End If
+                LVbox.Items.Add(listViewItem)
+            Loop
+
+            reader.Close()
+
+            LVbox.EndUpdate()
+            MainForm._checkLock = False
+
+            If LVbox.Items.Count > 0 Then LVbox.Items(LVbox.Items.Count - 1).EnsureVisible()
+        End Sub
+    End Class
+
+
+    'Open Job Editor and open file (or new file)
+    Friend Sub OpenVECTOeditor(x As String)
+
+        If x = "<New>" Then
+            ShowVectoJobForm()
+            VectoJobForm.VectoNew()
+        ElseIf x = "<VTP>" Then
+            ShowVectoEPTPJobForm()
+            VectoVTPJobForm.VectoNew()
+        Else
+            Try
+                Dim engJob As IVTPEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x),
+                                                                         IVTPEngineeringInputDataProvider)
+                Dim declJob As IVTPDeclarationInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x),
+                                                                          IVTPDeclarationInputDataProvider)
+                If engJob Is Nothing AndAlso declJob is Nothing Then
+                    ShowVectoJobForm()
+                    VectoJobForm.VECTOload2Form(x)
+                Else
+                    ShowVectoEPTPJobForm()
+                    VectoVTPJobForm.VECTOload2Form(x)
+                End If
+            Catch ex As Exception
+                MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vecto Job File")
+            End Try
+        End If
+
+        VectoJobForm.Activate()
+    End Sub
+
+    Private Sub ShowVectoJobForm()
+        If Not VectoJobForm.Visible Then
+            VectoJobForm.Show()
+        Else
+            If VectoJobForm.WindowState = FormWindowState.Minimized Then _
+                VectoJobForm.WindowState = FormWindowState.Normal
+            VectoJobForm.BringToFront()
+        End If
+    End Sub
+
+    Private Sub ShowVectoEPTPJobForm()
+        If Not VectoVTPJobForm.Visible Then
+            VectoVTPJobForm.Show()
+        Else
+            If VectoVTPJobForm.WindowState = FormWindowState.Minimized Then _
+                VectoVTPJobForm.WindowState = FormWindowState.Normal
+            VectoVTPJobForm.BringToFront()
+        End If
+    End Sub
+
+    'Save job and cycle file lists
+    Private Sub SaveFileLists()
+        _jobListView.SaveList()
+        'If Cfg.BatchMode Then CycleListView.SaveList()
+    End Sub
 
 
 #Region "Progressbar controls"
 
-	'Initialise progress bar (Start of next job in calculation)
+    'Initialise progress bar (Start of next job in calculation)
 
-	'Stop - Hide progress bar
-	Private Sub ProgSecStop()
-		TmProgSec.Stop()
-		ToolStripProgBarJob.Visible = False
-		ToolStripProgBarJob.Value = 0
-	End Sub
+    'Stop - Hide progress bar
+    Private Sub ProgSecStop()
+        TmProgSec.Stop()
+        ToolStripProgBarJob.Visible = False
+        ToolStripProgBarJob.Value = 0
+    End Sub
 
-	'Timer to update progress bar regularly
-	Private Sub TmProgSec_Tick(sender As Object, e As EventArgs) Handles TmProgSec.Tick
-		If _guItest.TestActive Then
-			Call _guItest.TestTick()
-			Exit Sub
-		Else
-			If Not ProgBarCtrl.ProgLock Then ProgSecUpdate()
-		End If
-	End Sub
+    'Timer to update progress bar regularly
+    Private Sub TmProgSec_Tick(sender As Object, e As EventArgs) Handles TmProgSec.Tick
+        If _guItest.TestActive Then
+            Call _guItest.TestTick()
+            Exit Sub
+        Else
+            If Not ProgBarCtrl.ProgLock Then ProgSecUpdate()
+        End If
+    End Sub
 
-	'Update progress bar (timer controlled)
-	Private Sub ProgSecUpdate()
+    'Update progress bar (timer controlled)
+    Private Sub ProgSecUpdate()
 
-		With ProgBarCtrl
+        With ProgBarCtrl
 
-			If .ProgJobInt > 0 AndAlso ToolStripProgBarJob.Style = ProgressBarStyle.Marquee Then
-				ToolStripProgBarJob.Style = ProgressBarStyle.Continuous
-			End If
+            If .ProgJobInt > 0 AndAlso ToolStripProgBarJob.Style = ProgressBarStyle.Marquee Then
+                ToolStripProgBarJob.Style = ProgressBarStyle.Continuous
+            End If
 
-			If .ProgJobInt < 0 Then
-				.ProgJobInt = 0
-			ElseIf .ProgJobInt > 100 Then
-				.ProgJobInt = 100
-			End If
+            If .ProgJobInt < 0 Then
+                .ProgJobInt = 0
+            ElseIf .ProgJobInt > 100 Then
+                .ProgJobInt = 100
+            End If
 
-			ToolStripProgBarJob.Value = .ProgJobInt
+            ToolStripProgBarJob.Value = .ProgJobInt
 
-			If .ProgOverallStartInt > -1 Then
-				ToolStripProgBarOverall.Value =
-					CInt(.ProgOverallStartInt + (.PgroOverallEndInt - .ProgOverallStartInt) * .ProgJobInt / 100)
-			End If
+            If .ProgOverallStartInt > - 1 Then
+                ToolStripProgBarOverall.Value =
+                    CInt(.ProgOverallStartInt + (.PgroOverallEndInt - .ProgOverallStartInt)*.ProgJobInt/100)
+            End If
 
-		End With
-	End Sub
+        End With
+    End Sub
 
 
 #End Region
 
 #Region "Options Tab"
 
-	'Load options from config class
-	Public Sub LoadOptions()
-		ChBoxModOut.Checked = Cfg.ModOut
-		ChBoxMod1Hz.Checked = Cfg.Mod1Hz
+    'Load options from config class
+    Public Sub LoadOptions()
+        ChBoxModOut.Checked = Cfg.ModOut
+        ChBoxMod1Hz.Checked = Cfg.Mod1Hz
 
-		RbDecl.Checked = Cfg.DeclMode
+        RbDecl.Checked = Cfg.DeclMode
         cbValidateRunData.Checked = cfg.ValidateRunData
-	End Sub
+    End Sub
 
-	'Update config class from options in GUI, e.g. before running calculations 
-	Private Sub SetOptions()
-		Cfg.ModOut = ChBoxModOut.Checked
-		Cfg.Mod1Hz = ChBoxMod1Hz.Checked
+    'Update config class from options in GUI, e.g. before running calculations 
+    Private Sub SetOptions()
+        Cfg.ModOut = ChBoxModOut.Checked
+        Cfg.Mod1Hz = ChBoxMod1Hz.Checked
         Cfg.ValidateRunData = cbValidateRunData.Checked
-	End Sub
+    End Sub
 
 #End Region
 
 
-	'Add message to message list
-	Public Sub MsgToForm(id As MessageType, msg As String, source As String, link As String)
-
-		If (InvokeRequired) Then
-			'Me.Invoke(New MsgToFormDelegate(AddressOf MSGtoForm), ID, Msg, Source, Link)
-			Exit Sub
-		End If
-		Dim lv0 As ListViewItem
-
-		lv0 = New ListViewItem
-		lv0.Text = msg
-		lv0.SubItems.Add(Now.ToString("HH:mm:ss.ff"))
-		lv0.SubItems.Add(source)
-
-		If LvMsg.Items.Count > 9999 Then LvMsg.Items.RemoveAt(0)
-
-		LogFile.WriteToLog(id, msg & vbTab & source)
-
-		Select Case id
-
-			Case MessageType.Err
-
-				lv0.BackColor = Color.Red
-				lv0.ForeColor = Color.White
-
-			Case MessageType.Warn
-
-				lv0.BackColor = Color.Khaki				 'FromArgb(218, 125, 0) 'DarkOrange
-				lv0.ForeColor = Color.Black
-
-			Case Else
-
-				If id = MessageType.NewJob Then
-					lv0.BackColor = Color.LightGray
-					lv0.ForeColor = Color.DarkBlue
-				End If
-
-		End Select
-
-		If link <> "" Then
-			If Not id = MessageType.Err Then lv0.ForeColor = Color.Blue
-			lv0.SubItems(0).Font = New Font(LvMsg.Font, FontStyle.Underline)
-			lv0.Tag = link
-		End If
-
-
-		LvMsg.Items.Add(lv0)
-
-		lv0.EnsureVisible()
-	End Sub
-
-
-	'Open link in message list
-	Private Sub LvMsg_MouseClick(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseClick
-		Dim txt As String
-		If LvMsg.SelectedIndices.Count > 0 Then
-			If Not LvMsg.SelectedItems(0).Tag Is Nothing Then
-				If _
-					Len(CStr(LvMsg.SelectedItems(0).Tag)) > 4 AndAlso
-					Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 4) = "<UM>" Then
-					txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<UM>", MyAppPath & "User Manual")
-					txt = txt.Replace(" ", "%20")
-					txt = txt.Replace("\", "/")
-					txt = "file:///" & txt
-					Try
-						Process.Start(txt)
-					Catch ex As Exception
-						MsgBox("Cannot open link! (-_-;)")
-					End Try
-				ElseIf _
-					Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso
-					Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<GUI>" Then
-					txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<GUI>", "")
-					OpenVectoFile(txt)
-				ElseIf _
-					Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso
-					Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<RUN>" Then
-					txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<RUN>", "")
-					Try
-						Process.Start(txt)
-					Catch ex As Exception
-						GUIMsg(MessageType.Err, "Could not run '" & txt & "'!")
-					End Try
-				ElseIf _
-					Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso
-					Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<XML>" Then
-					txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<XML>", "")
-					OpenFiles(txt)
-				Else
-					OpenFiles(CStr(LvMsg.SelectedItems(0).Tag))
-				End If
-			End If
-		End If
-	End Sub
-
-	'Link-cursor (Hand) for links
-	Private Sub LvMsg_MouseMove(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseMove
-		Dim lv0 As ListViewItem
-		lv0 = LvMsg.GetItemAt(e.Location.X, e.Location.Y)
-		If lv0 Is Nothing OrElse lv0.Tag Is Nothing Then
-			LvMsg.Cursor = Cursors.Arrow
-		Else
-			LvMsg.Cursor = Cursors.Hand
-		End If
-		If _mouseDownOnListView Then
-			Try
-				LvMsg.HitTest(e.Location).Item.Selected = True
-			Catch
-			End Try
-		End If
-	End Sub
+    'Add message to message list
+    Public Sub MsgToForm(id As MessageType, msg As String, source As String, link As String)
+
+        If (InvokeRequired) Then
+            'Me.Invoke(New MsgToFormDelegate(AddressOf MSGtoForm), ID, Msg, Source, Link)
+            Exit Sub
+        End If
+        Dim lv0 As ListViewItem
+
+        lv0 = New ListViewItem
+        lv0.Text = msg
+        lv0.SubItems.Add(Now.ToString("HH:mm:ss.ff"))
+        lv0.SubItems.Add(source)
+
+        If LvMsg.Items.Count > 9999 Then LvMsg.Items.RemoveAt(0)
+
+        LogFile.WriteToLog(id, msg & vbTab & source)
+
+        Select Case id
+
+            Case MessageType.Err
+
+                lv0.BackColor = Color.Red
+                lv0.ForeColor = Color.White
+
+            Case MessageType.Warn
+
+                lv0.BackColor = Color.Khaki				 'FromArgb(218, 125, 0) 'DarkOrange
+                lv0.ForeColor = Color.Black
+
+            Case Else
+
+                If id = MessageType.NewJob Then
+                    lv0.BackColor = Color.LightGray
+                    lv0.ForeColor = Color.DarkBlue
+                End If
+
+        End Select
+
+        If link <> "" Then
+            If Not id = MessageType.Err Then lv0.ForeColor = Color.Blue
+            lv0.SubItems(0).Font = New Font(LvMsg.Font, FontStyle.Underline)
+            lv0.Tag = link
+        End If
+
+
+        LvMsg.Items.Add(lv0)
+
+        lv0.EnsureVisible()
+    End Sub
+
+
+    'Open link in message list
+    Private Sub LvMsg_MouseClick(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseClick
+        Dim txt As String
+        If LvMsg.SelectedIndices.Count > 0 Then
+            If Not LvMsg.SelectedItems(0).Tag Is Nothing Then
+                If _
+                    Len(CStr(LvMsg.SelectedItems(0).Tag)) > 4 AndAlso
+                    Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 4) = "<UM>" Then
+                    txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<UM>", MyAppPath & "User Manual")
+                    txt = txt.Replace(" ", "%20")
+                    txt = txt.Replace("\", "/")
+                    txt = "file:///" & txt
+                    Try
+                        Process.Start(txt)
+                    Catch ex As Exception
+                        MsgBox("Cannot open link! (-_-;)")
+                    End Try
+                ElseIf _
+                    Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso
+                    Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<GUI>" Then
+                    txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<GUI>", "")
+                    OpenVectoFile(txt)
+                ElseIf _
+                    Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso
+                    Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<RUN>" Then
+                    txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<RUN>", "")
+                    Try
+                        Process.Start(txt)
+                    Catch ex As Exception
+                        GUIMsg(MessageType.Err, "Could not run '" & txt & "'!")
+                    End Try
+                ElseIf _
+                    Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso
+                    Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<XML>" Then
+                    txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<XML>", "")
+                    OpenFiles(txt)
+                Else
+                    OpenFiles(CStr(LvMsg.SelectedItems(0).Tag))
+                End If
+            End If
+        End If
+    End Sub
+
+    'Link-cursor (Hand) for links
+    Private Sub LvMsg_MouseMove(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseMove
+        Dim lv0 As ListViewItem
+        lv0 = LvMsg.GetItemAt(e.Location.X, e.Location.Y)
+        If lv0 Is Nothing OrElse lv0.Tag Is Nothing Then
+            LvMsg.Cursor = Cursors.Arrow
+        Else
+            LvMsg.Cursor = Cursors.Hand
+        End If
+        If _mouseDownOnListView Then
+            Try
+                LvMsg.HitTest(e.Location).Item.Selected = True
+            Catch
+            End Try
+        End If
+    End Sub
 
 #Region "Open File Context Menu"
 
-	Private _contextMenuFiles As String()
+    Private _contextMenuFiles As String()
 
-	'Initialise and open context menu
-	Private Sub OpenFiles(ParamArray files() As String)
+    'Initialise and open context menu
+    Private Sub OpenFiles(ParamArray files() As String)
 
-		If files.Length = 0 Then Exit Sub
+        If files.Length = 0 Then Exit Sub
 
-		_contextMenuFiles = files
+        _contextMenuFiles = files
 
-		OpenInGraphWindowToolStripMenuItem.Enabled = (UCase(GetExtension(_contextMenuFiles(0))) = ".VMOD")
+        OpenInGraphWindowToolStripMenuItem.Enabled = (UCase(GetExtension(_contextMenuFiles(0))) = ".VMOD")
 
-		OpenWithToolStripMenuItem.Text = "Open with " & Cfg.OpenCmdName
+        OpenWithToolStripMenuItem.Text = "Open with " & Cfg.OpenCmdName
 
-		CmOpenFile.Show(Cursor.Position)
-	End Sub
+        CmOpenFile.Show(Cursor.Position)
+    End Sub
 
-	'Open with tool defined in Settings
-	Private Sub OpenWithToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles OpenWithToolStripMenuItem.Click
-		If Not FileOpenAlt(_contextMenuFiles(0)) Then MsgBox("Failed to open file!")
-	End Sub
+    'Open with tool defined in Settings
+    Private Sub OpenWithToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles OpenWithToolStripMenuItem.Click
+        If Not FileOpenAlt(_contextMenuFiles(0)) Then MsgBox("Failed to open file!")
+    End Sub
 
-	Private Sub OpenInGraphWindowToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles OpenInGraphWindowToolStripMenuItem.Click
-		Dim graphForm As New GraphForm
-		graphForm.Show()
-		graphForm.LoadNewFile(_contextMenuFiles(0))
-	End Sub
+    Private Sub OpenInGraphWindowToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles OpenInGraphWindowToolStripMenuItem.Click
+        Dim graphForm As New GraphForm
+        graphForm.Show()
+        graphForm.LoadNewFile(_contextMenuFiles(0))
+    End Sub
 
-	'Show in folder
-	Private Sub ShowInFolderToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles ShowInFolderToolStripMenuItem.Click
-		If File.Exists(_contextMenuFiles(0)) Then
-			Try
-				Process.Start("explorer", "/select,""" & _contextMenuFiles(0) & "")
-			Catch ex As Exception
-				MsgBox("Failed to open file!")
-			End Try
-		Else
-			MsgBox("File not found!")
-		End If
-	End Sub
+    'Show in folder
+    Private Sub ShowInFolderToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles ShowInFolderToolStripMenuItem.Click
+        If File.Exists(_contextMenuFiles(0)) Then
+            Try
+                Process.Start("explorer", "/select,""" & _contextMenuFiles(0) & "")
+            Catch ex As Exception
+                MsgBox("Failed to open file!")
+            End Try
+        Else
+            MsgBox("File not found!")
+        End If
+    End Sub
 
 #End Region
 
-	'Change Declaraion Mode
-	Private Sub RbDecl_CheckedChanged(sender As Object, e As EventArgs) Handles RbDecl.CheckedChanged
-		If _cbDeclLock Then Exit Sub
+    'Change Declaraion Mode
+    Private Sub RbDecl_CheckedChanged(sender As Object, e As EventArgs) Handles RbDecl.CheckedChanged
+        If _cbDeclLock Then Exit Sub
 
-		If VectoJobForm.Visible Or VehicleForm.Visible Or GearboxForm.Visible Or EngineForm.Visible Then
-			_cbDeclLock = True
-			RbDecl.Checked = Not RbDecl.Checked
-			_cbDeclLock = False
-			MsgBox("Please close all dialog windows (e.g. Job Editor) before changing mode!")
-		Else
-			Cfg.DeclMode = RbDecl.Checked
-			RbDev.Checked = Not RbDecl.Checked
-			DeclOnOff()
-		End If
-	End Sub
+        If VectoJobForm.Visible Or VehicleForm.Visible Or GearboxForm.Visible Or EngineForm.Visible Then
+            _cbDeclLock = True
+            RbDecl.Checked = Not RbDecl.Checked
+            _cbDeclLock = False
+            MsgBox("Please close all dialog windows (e.g. Job Editor) before changing mode!")
+        Else
+            Cfg.DeclMode = RbDecl.Checked
+            RbDev.Checked = Not RbDecl.Checked
+            DeclOnOff()
+        End If
+    End Sub
 
 
 #Region "GUI Tests"
 
-	Private ReadOnly _guItest As New GUItest(Me)
-	Private _mouseDownOnListView As Boolean
-
-	Private Class GUItest
-		Private Const RowLim As Integer = 9
-		Private Const ColLim As Integer = 45
-		Public TestActive As Boolean = False
-		Private _testAborted As Boolean
-		Private _xCtrl As Integer
-		Private _xPanel As Integer
-		Private _scr As Integer
-		Private _pRbAlt As Boolean
-		Private ReadOnly _ctrls(RowLim + 1) As Integer
-		Private ReadOnly _pnls(RowLim + 1) As Integer
-		Private _ctrlC As Integer
-		Private _ctrlCl As Integer
-		Private _pnDir As Integer
-		Private _pnDirC As Integer
-		Private _pnDirCl As Integer
-		Private _pnDirRnd As Integer
-		Private _ctrlRnd As Integer
-		Private _diffC As Integer
-		Private _diffLvl As Integer
-		Private _bInit As Integer
-		Private ReadOnly _mainForm As MainForm
-		Private ReadOnly _keyCode As List(Of Integer)
-
-		Private Sub TestRun()
-
-			Dim z As Integer
-
-			_xPanel = ColLim - 10
-			_xCtrl = ColLim - 10
-			_pRbAlt = False
-			_scr = 0
-			_pnDir = 0
-			_pnDirCl = 10
-			_pnDirC = 0	' StrDirCL
-			_ctrlCl = 5
-			_ctrlC = _ctrlCl
-			_pnDirRnd = 5
-			_ctrlRnd = 8
-			_diffC = 0
-			_diffLvl = 1
-			_bInit = 0
-			_testAborted = False
-			Randomize()
-
-
-			_mainForm.LvMsg.Items.Clear()
-			_mainForm.ToolStripLbStatus.Text = "Score: 0000             Press <Esc> to Quit"
-
-			For z = 1 To RowLim - 6
-				_pRbAlt = Not _pRbAlt
-				If Not _pRbAlt Then
-					_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|       |*")
-				Else
-					_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   |   |*")
-				End If
-			Next
-
-			_pRbAlt = False
-
-			_mainForm.LvMsg.Items.Add("  VECTO Interactive Mode" & Space(ColLim - 35) & "*|       |*")
-			_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   |   |*")
-			_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|       |*")
-			_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   |   |*")
-			_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|       |*")
-			_mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   ∆   |*")
-
-			For z = 1 To RowLim + 1
-				_pnls(z) = ColLim - 10
-				_ctrls(z) = 0
-			Next
-
-			_mainForm.TmProgSec.Interval = 200
-
-			_mainForm.LvMsg.Focus()
-
-			_mainForm.TmProgSec.Start()
-		End Sub
-
-		Public Sub TestStop()
-			_mainForm.TmProgSec.Stop()
-			TestActive = False
-			_mainForm.LvMsg.Items.Clear()
-			_ctrlC = 0
-			_mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode"
-		End Sub
-
-		Public Sub TestTick()
-
-			If _bInit = 24 Then GoTo LbRace
-			_bInit += 1
-
-			Select Case _bInit
-				Case 10
-					_mainForm.LvMsg.Items.RemoveAt(RowLim - 6)
-					_mainForm.LvMsg.Items.RemoveAt(RowLim - 5)
-					_mainForm.LvMsg.Items.Insert(RowLim - 6, Space(ColLim - 11) & "*|       |*")
-					_mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & "  3      " & Space(10) & "*|       |*")
-				Case 14
-					_mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
-					_mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & "  2      " & Space(10) & "*|       |*")
-				Case 18
-					_mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
-					_mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & "  1      " & Space(10) & "*|       |*")
-				Case 22
-					_mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
-					_mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & " Go!     " & Space(10) & "*|       |*")
-				Case 24
-					_mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
-					_mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & "         " & Space(10) & "*|       |*")
-			End Select
-			Exit Sub
-LbRace:
-
-			_pRbAlt = Not _pRbAlt
-
-			_mainForm.LvMsg.BeginUpdate()
-
-			Lists()
-
-			Align()
-
-			SetCtrl()
-
-			SetPanel()
-
-			_mainForm.LvMsg.Items.RemoveAt(RowLim)
-
-			UpdateCtrl()
-
-			_mainForm.LvMsg.EndUpdate()
-
-			If Math.Abs(_xCtrl - _pnls(2)) > 4 Then
-				Abort()
-				Exit Sub
-			ElseIf _ctrls(2) <> 0 Then
-				If _xCtrl = _pnls(2) + _ctrls(2) - 4 Then
-					Abort()
-					Exit Sub
-				End If
-				_scr += 5 * _diffLvl
-			End If
-
-			_scr += _diffLvl
-			_diffC += 1
-
-			'Erhöhe Schwierigkeitsgrad
-			If _diffC = (_diffLvl + 3) * 4 Then
-				_diffC = 0
-				_diffLvl += 1
-				If _diffLvl > 2 And _diffLvl < 7 Then _mainForm.TmProgSec.Interval = 300 - (_diffLvl) * 30
-				_scr += 100
-				Select Case _diffLvl
-					Case 3
-						_pnDirCl = 3
-						_ctrlCl = 4
-						_ctrlRnd = 6
-					Case 5
-						_pnDirCl = 2
-						_pnDirRnd = 4
-					Case 8
-						_ctrlCl = 2
-					Case 10
-						_ctrlRnd = 4
-						_pnDirRnd = 3
-				End Select
-			End If
-		End Sub
-
-		Public Sub TestKey(key As Integer)
-
-			If TestActive Then
-				Select Case key
-					Case Keys.Left
-						_xCtrl -= 1
-						UpdateCtrl()
-					Case Keys.Right
-						_xCtrl += 1
-						UpdateCtrl()
-					Case Keys.Escape
-						TestStop()
-				End Select
-			Else
-
-				If _keyCode(_ctrlC) = key Then
-					_ctrlC += 1
-					If _ctrlC = _keyCode.Count Then
-						TestActive = True
-						TestRun()
-					End If
-				Else
-					_ctrlC = 0
-				End If
-
-			End If
-		End Sub
-
-		Private Sub Abort()
-
-			Dim s As String, s1 As String
-
-			If _testAborted Then Exit Sub
-
-			_testAborted = True
-
-			_mainForm.TmProgSec.Stop()
-
-			_mainForm.LvMsg.BeginUpdate()
-
-			s = _mainForm.LvMsg.Items(0).Text
-			_mainForm.LvMsg.Items.RemoveAt(0)
-			_mainForm.LvMsg.Items.Insert(0, "You crashed!" & Microsoft.VisualBasic.Right(s, Len(s) - 12))
-
-			s = _mainForm.LvMsg.Items(1).Text
-			s1 = "Score: " & _scr & " "
-			_mainForm.LvMsg.Items.RemoveAt(1)
-			_mainForm.LvMsg.Items.Insert(1, s1 & Microsoft.VisualBasic.Right(s, Len(s) - Len(s1)))
-
-			_mainForm.LvMsg.EndUpdate()
-
-			LogFile.WriteToLog(MessageType.Normal, "*** Race Score: " & _scr.ToString("0000") & " ***")
-
-			_ctrlC = 0
-			TestActive = False
-
-			_mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode"
-		End Sub
-
-		Private Sub SetCtrl()
-			Dim x As Integer
-			If _scr < 10 Then Exit Sub
-			_ctrls(RowLim + 1) = 0
-			_ctrlC += 1
-			If _ctrlC < _ctrlCl Then Exit Sub
-			Select Case CInt(Int((_ctrlRnd * Rnd()) + 1))
-				Case 1, 2
-					_ctrlC = 0
-					x = CInt(Int((7 * Rnd()) + 1))
-					_ctrls(RowLim + 1) = x
-			End Select
-		End Sub
-
-		Private Sub UpdateCtrl()
-			Dim s As String
-			If _bInit < 21 Then
-				_xCtrl = ColLim - 10
-				Exit Sub
-			End If
-			If Math.Abs(_xCtrl - _pnls(1)) > 5 Then
-				Abort()
-				Exit Sub
-			End If
-			s = Replace(_mainForm.LvMsg.Items(RowLim - 1).Text.ToString, "∆", " ") & "   "
-			s = Microsoft.VisualBasic.Left(s, ColLim + 15)
-			's = s.Remove(0, 20)
-			's = "Press <Esc> to Quit " & s
-			If Mid(s, _xCtrl + 5, 1) = "X" Then
-				Abort()
-				Exit Sub
-			End If
-			s = s.Remove(_xCtrl + 4, 1)
-			's = Trim(s.Insert(xCar + 4, "∆")) & Space(ColLim + 5 - Streets(2)) & "Pts: " & Pts & " Lv: " & DiffLvl
-			s = Space(_pnls(2) - 1) & Trim(s.Insert(_xCtrl + 4, "∆"))
-			_mainForm.LvMsg.Items.RemoveAt(RowLim - 1)
-			_mainForm.LvMsg.Items.Insert(RowLim - 1, s)
-			_mainForm.ToolStripLbStatus.Text = "Score: " & _scr.ToString("0000") & "             Press <Esc> to Quit"
-		End Sub
-
-		Private Sub SetPanel()
-			Dim s As String
-			s = "*|   |   |*"
-			If _pRbAlt Then
-				s = s.Remove(5, 1)
-				s = s.Insert(5, " ")
-			End If
-			If _ctrls(RowLim + 1) <> 0 Then
-				s = s.Remove(_ctrls(RowLim + 1) + 1, 1)
-				s = s.Insert(_ctrls(RowLim + 1) + 1, "X")
-			End If
-			Select Case _xPanel - _pnls(RowLim)
-				Case -1
-					s = Replace(s, "|", "\")
-				Case 1
-					s = Replace(s, "|", "/")
-			End Select
-			_mainForm.LvMsg.Items.Insert(0, Space(_xPanel - 1) & s)
-		End Sub
-
-		Private Sub Align()
-			_pnDirC += 1
-			If _pnDirC < _pnDirCl Then GoTo Lb1
-			_pnDirC = 0
-			Select Case CInt(Int((_pnDirRnd * Rnd()) + 1))
-				Case 1
-					_pnDir = 1
-				Case 2
-					_pnDir = -1
-				Case Else
-					_pnDir = 0
-			End Select
-Lb1:
-			_xPanel += _pnDir
-			If _xPanel > ColLim Then
-				_xPanel = ColLim
-			ElseIf _xPanel < 22 Then
-				_xPanel = 22
-			End If
-			_pnls(RowLim + 1) = _xPanel
-		End Sub
-
-		Private Sub Lists()
-			Dim x As Integer
-			For x = 2 To RowLim + 1
-				_ctrls(x - 1) = _ctrls(x)
-				_pnls(x - 1) = _pnls(x)
-			Next
-		End Sub
-
-		Public Sub New(form As MainForm)
-			_mainForm = form
-			_keyCode = New List(Of Integer)
-			_keyCode.Add(Keys.Up)
-			_keyCode.Add(Keys.Up)
-			_keyCode.Add(Keys.Down)
-			_keyCode.Add(Keys.Down)
-			_keyCode.Add(Keys.Left)
-			_keyCode.Add(Keys.Right)
-			_keyCode.Add(Keys.Left)
-			_keyCode.Add(Keys.Right)
-			_keyCode.Add(Keys.B)
-			_keyCode.Add(Keys.A)
-			_ctrlC = 0
-		End Sub
-	End Class
-
-	Private Sub LvMsg_KeyDown(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyDown
-		_guItest.TestKey(e.KeyValue)
-		If _guItest.TestActive Then e.SuppressKeyPress = True
-	End Sub
-
-	Private Sub LvMsg_LostFocus(sender As Object, e As EventArgs) Handles LvMsg.LostFocus
-		If _guItest.TestActive Then _guItest.TestStop()
-	End Sub
+    Private ReadOnly _guItest As New GUItest(Me)
+    Private _mouseDownOnListView As Boolean
+
+    Private Class GUItest
+        Private Const RowLim As Integer = 9
+        Private Const ColLim As Integer = 45
+        Public TestActive As Boolean = False
+        Private _testAborted As Boolean
+        Private _xCtrl As Integer
+        Private _xPanel As Integer
+        Private _scr As Integer
+        Private _pRbAlt As Boolean
+        Private ReadOnly _ctrls(RowLim + 1) As Integer
+        Private ReadOnly _pnls(RowLim + 1) As Integer
+        Private _ctrlC As Integer
+        Private _ctrlCl As Integer
+        Private _pnDir As Integer
+        Private _pnDirC As Integer
+        Private _pnDirCl As Integer
+        Private _pnDirRnd As Integer
+        Private _ctrlRnd As Integer
+        Private _diffC As Integer
+        Private _diffLvl As Integer
+        Private _bInit As Integer
+        Private ReadOnly _mainForm As MainForm
+        Private ReadOnly _keyCode As List(Of Integer)
+
+        Private Sub TestRun()
+
+            Dim z As Integer
+
+            _xPanel = ColLim - 10
+            _xCtrl = ColLim - 10
+            _pRbAlt = False
+            _scr = 0
+            _pnDir = 0
+            _pnDirCl = 10
+            _pnDirC = 0	' StrDirCL
+            _ctrlCl = 5
+            _ctrlC = _ctrlCl
+            _pnDirRnd = 5
+            _ctrlRnd = 8
+            _diffC = 0
+            _diffLvl = 1
+            _bInit = 0
+            _testAborted = False
+            Randomize()
+
+
+            _mainForm.LvMsg.Items.Clear()
+            _mainForm.ToolStripLbStatus.Text = "Score: 0000             Press <Esc> to Quit"
+
+            For z = 1 To RowLim - 6
+                _pRbAlt = Not _pRbAlt
+                If Not _pRbAlt Then
+                    _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|       |*")
+                Else
+                    _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   |   |*")
+                End If
+            Next
+
+            _pRbAlt = False
+
+            _mainForm.LvMsg.Items.Add("  VECTO Interactive Mode" & Space(ColLim - 35) & "*|       |*")
+            _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   |   |*")
+            _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|       |*")
+            _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   |   |*")
+            _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|       |*")
+            _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*|   ∆   |*")
+
+            For z = 1 To RowLim + 1
+                _pnls(z) = ColLim - 10
+                _ctrls(z) = 0
+            Next
+
+            _mainForm.TmProgSec.Interval = 200
+
+            _mainForm.LvMsg.Focus()
+
+            _mainForm.TmProgSec.Start()
+        End Sub
+
+        Public Sub TestStop()
+            _mainForm.TmProgSec.Stop()
+            TestActive = False
+            _mainForm.LvMsg.Items.Clear()
+            _ctrlC = 0
+            _mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode"
+        End Sub
+
+        Public Sub TestTick()
+
+            If _bInit = 24 Then GoTo LbRace
+            _bInit += 1
+
+            Select Case _bInit
+                Case 10
+                    _mainForm.LvMsg.Items.RemoveAt(RowLim - 6)
+                    _mainForm.LvMsg.Items.RemoveAt(RowLim - 5)
+                    _mainForm.LvMsg.Items.Insert(RowLim - 6, Space(ColLim - 11) & "*|       |*")
+                    _mainForm.LvMsg.Items.Insert(RowLim - 4,
+                                                 Space(ColLim - 30) & "  3      " & Space(10) & "*|       |*")
+                Case 14
+                    _mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
+                    _mainForm.LvMsg.Items.Insert(RowLim - 4,
+                                                 Space(ColLim - 30) & "  2      " & Space(10) & "*|       |*")
+                Case 18
+                    _mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
+                    _mainForm.LvMsg.Items.Insert(RowLim - 4,
+                                                 Space(ColLim - 30) & "  1      " & Space(10) & "*|       |*")
+                Case 22
+                    _mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
+                    _mainForm.LvMsg.Items.Insert(RowLim - 4,
+                                                 Space(ColLim - 30) & " Go!     " & Space(10) & "*|       |*")
+                Case 24
+                    _mainForm.LvMsg.Items.RemoveAt(RowLim - 4)
+                    _mainForm.LvMsg.Items.Insert(RowLim - 4,
+                                                 Space(ColLim - 30) & "         " & Space(10) & "*|       |*")
+            End Select
+            Exit Sub
+            LbRace:
+
+            _pRbAlt = Not _pRbAlt
+
+            _mainForm.LvMsg.BeginUpdate()
+
+            Lists()
+
+            Align()
+
+            SetCtrl()
+
+            SetPanel()
+
+            _mainForm.LvMsg.Items.RemoveAt(RowLim)
+
+            UpdateCtrl()
+
+            _mainForm.LvMsg.EndUpdate()
+
+            If Math.Abs(_xCtrl - _pnls(2)) > 4 Then
+                Abort()
+                Exit Sub
+            ElseIf _ctrls(2) <> 0 Then
+                If _xCtrl = _pnls(2) + _ctrls(2) - 4 Then
+                    Abort()
+                    Exit Sub
+                End If
+                _scr += 5*_diffLvl
+            End If
+
+            _scr += _diffLvl
+            _diffC += 1
+
+            'Erhöhe Schwierigkeitsgrad
+            If _diffC = (_diffLvl + 3)*4 Then
+                _diffC = 0
+                _diffLvl += 1
+                If _diffLvl > 2 And _diffLvl < 7 Then _mainForm.TmProgSec.Interval = 300 - (_diffLvl)*30
+                _scr += 100
+                Select Case _diffLvl
+                    Case 3
+                        _pnDirCl = 3
+                        _ctrlCl = 4
+                        _ctrlRnd = 6
+                    Case 5
+                        _pnDirCl = 2
+                        _pnDirRnd = 4
+                    Case 8
+                        _ctrlCl = 2
+                    Case 10
+                        _ctrlRnd = 4
+                        _pnDirRnd = 3
+                End Select
+            End If
+        End Sub
+
+        Public Sub TestKey(key As Integer)
+
+            If TestActive Then
+                Select Case key
+                    Case Keys.Left
+                        _xCtrl -= 1
+                        UpdateCtrl()
+                    Case Keys.Right
+                        _xCtrl += 1
+                        UpdateCtrl()
+                    Case Keys.Escape
+                        TestStop()
+                End Select
+            Else
+
+                If _keyCode(_ctrlC) = key Then
+                    _ctrlC += 1
+                    If _ctrlC = _keyCode.Count Then
+                        TestActive = True
+                        TestRun()
+                    End If
+                Else
+                    _ctrlC = 0
+                End If
+
+            End If
+        End Sub
+
+        Private Sub Abort()
+
+            Dim s As String, s1 As String
+
+            If _testAborted Then Exit Sub
+
+            _testAborted = True
+
+            _mainForm.TmProgSec.Stop()
+
+            _mainForm.LvMsg.BeginUpdate()
+
+            s = _mainForm.LvMsg.Items(0).Text
+            _mainForm.LvMsg.Items.RemoveAt(0)
+            _mainForm.LvMsg.Items.Insert(0, "You crashed!" & Microsoft.VisualBasic.Right(s, Len(s) - 12))
+
+            s = _mainForm.LvMsg.Items(1).Text
+            s1 = "Score: " & _scr & " "
+            _mainForm.LvMsg.Items.RemoveAt(1)
+            _mainForm.LvMsg.Items.Insert(1, s1 & Microsoft.VisualBasic.Right(s, Len(s) - Len(s1)))
+
+            _mainForm.LvMsg.EndUpdate()
+
+            LogFile.WriteToLog(MessageType.Normal, "*** Race Score: " & _scr.ToString("0000") & " ***")
+
+            _ctrlC = 0
+            TestActive = False
+
+            _mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode"
+        End Sub
+
+        Private Sub SetCtrl()
+            Dim x As Integer
+            If _scr < 10 Then Exit Sub
+            _ctrls(RowLim + 1) = 0
+            _ctrlC += 1
+            If _ctrlC < _ctrlCl Then Exit Sub
+            Select Case CInt(Int((_ctrlRnd*Rnd()) + 1))
+                Case 1, 2
+                    _ctrlC = 0
+                    x = CInt(Int((7*Rnd()) + 1))
+                    _ctrls(RowLim + 1) = x
+            End Select
+        End Sub
+
+        Private Sub UpdateCtrl()
+            Dim s As String
+            If _bInit < 21 Then
+                _xCtrl = ColLim - 10
+                Exit Sub
+            End If
+            If Math.Abs(_xCtrl - _pnls(1)) > 5 Then
+                Abort()
+                Exit Sub
+            End If
+            s = Replace(_mainForm.LvMsg.Items(RowLim - 1).Text.ToString, "∆", " ") & "   "
+            s = Microsoft.VisualBasic.Left(s, ColLim + 15)
+            's = s.Remove(0, 20)
+            's = "Press <Esc> to Quit " & s
+            If Mid(s, _xCtrl + 5, 1) = "X" Then
+                Abort()
+                Exit Sub
+            End If
+            s = s.Remove(_xCtrl + 4, 1)
+            's = Trim(s.Insert(xCar + 4, "∆")) & Space(ColLim + 5 - Streets(2)) & "Pts: " & Pts & " Lv: " & DiffLvl
+            s = Space(_pnls(2) - 1) & Trim(s.Insert(_xCtrl + 4, "∆"))
+            _mainForm.LvMsg.Items.RemoveAt(RowLim - 1)
+            _mainForm.LvMsg.Items.Insert(RowLim - 1, s)
+            _mainForm.ToolStripLbStatus.Text = "Score: " & _scr.ToString("0000") & "             Press <Esc> to Quit"
+        End Sub
+
+        Private Sub SetPanel()
+            Dim s As String
+            s = "*|   |   |*"
+            If _pRbAlt Then
+                s = s.Remove(5, 1)
+                s = s.Insert(5, " ")
+            End If
+            If _ctrls(RowLim + 1) <> 0 Then
+                s = s.Remove(_ctrls(RowLim + 1) + 1, 1)
+                s = s.Insert(_ctrls(RowLim + 1) + 1, "X")
+            End If
+            Select Case _xPanel - _pnls(RowLim)
+                Case - 1
+                    s = Replace(s, "|", "\")
+                Case 1
+                    s = Replace(s, "|", "/")
+            End Select
+            _mainForm.LvMsg.Items.Insert(0, Space(_xPanel - 1) & s)
+        End Sub
+
+        Private Sub Align()
+            _pnDirC += 1
+            If _pnDirC < _pnDirCl Then GoTo Lb1
+            _pnDirC = 0
+            Select Case CInt(Int((_pnDirRnd*Rnd()) + 1))
+                Case 1
+                    _pnDir = 1
+                Case 2
+                    _pnDir = - 1
+                Case Else
+                    _pnDir = 0
+            End Select
+            Lb1:
+            _xPanel += _pnDir
+            If _xPanel > ColLim Then
+                _xPanel = ColLim
+            ElseIf _xPanel < 22 Then
+                _xPanel = 22
+            End If
+            _pnls(RowLim + 1) = _xPanel
+        End Sub
+
+        Private Sub Lists()
+            Dim x As Integer
+            For x = 2 To RowLim + 1
+                _ctrls(x - 1) = _ctrls(x)
+                _pnls(x - 1) = _pnls(x)
+            Next
+        End Sub
+
+        Public Sub New(form As MainForm)
+            _mainForm = form
+            _keyCode = New List(Of Integer)
+            _keyCode.Add(Keys.Up)
+            _keyCode.Add(Keys.Up)
+            _keyCode.Add(Keys.Down)
+            _keyCode.Add(Keys.Down)
+            _keyCode.Add(Keys.Left)
+            _keyCode.Add(Keys.Right)
+            _keyCode.Add(Keys.Left)
+            _keyCode.Add(Keys.Right)
+            _keyCode.Add(Keys.B)
+            _keyCode.Add(Keys.A)
+            _ctrlC = 0
+        End Sub
+    End Class
+
+    Private Sub LvMsg_KeyDown(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyDown
+        _guItest.TestKey(e.KeyValue)
+        If _guItest.TestActive Then e.SuppressKeyPress = True
+    End Sub
+
+    Private Sub LvMsg_LostFocus(sender As Object, e As EventArgs) Handles LvMsg.LostFocus
+        If _guItest.TestActive Then _guItest.TestStop()
+    End Sub
 
 #End Region
 
-	Private Sub LvMsg_KeyUp(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyUp
-		If (e.Control And e.KeyCode = Keys.C) Then
-			Dim builder As StringBuilder = New StringBuilder()
-			For Each selectedItem As ListViewItem In LvMsg.SelectedItems
-				builder.AppendLine(String.Join(", ",
-												selectedItem.SubItems.Cast(Of ListViewItem.ListViewSubItem).Select(
-													Function(item) item.Text)))
-			Next
-			Clipboard.SetText(builder.ToString())
-		End If
-	End Sub
-
-	Private Sub LvMsg_MouseDown(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseDown
-		_mouseDownOnListView = True
-	End Sub
-
-	Private Sub LvMsg_MouseUp(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseUp
-		_mouseDownOnListView = False
-	End Sub
-
-	Private Sub RbDev_CheckedChanged(sender As Object, e As EventArgs) Handles RbDev.CheckedChanged
-	End Sub
-
-
-	Private Class VectoProgress
-		Public Target As String
-		Public Message As String
-		Public Link As String
-	End Class
-
-	Private Sub btnExportXML_Click(sender As Object, e As EventArgs) Handles btnExportXML.Click
-
-		If LvGEN.SelectedItems.Count < 1 Then
-			If LvGEN.Items.Count = 1 Then
-				LvGEN.Items(0).Selected = True
-			Else
-				Exit Sub
-			End If
-		End If
-
-		Dim f As String = LvGEN.SelectedItems(0).SubItems(0).Text
-		f = FileRepl(f)
-		If Not File.Exists(f) Then
-			MsgBox(f & " not found!")
-			Return
-		End If
-		Try
-			Dim input As IInputDataProvider = Nothing
-			Dim extension As String = Path.GetExtension(f)
-			Select Case extension
-				Case ".vecto"
-					input = JSONInputDataFactory.ReadJsonJob(f)
-				Case ".xml"
-					Dim xDocument As XDocument = xDocument.Load(f)
-					Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName)
-					Select Case rootNode
-						Case XMLNames.VectoInputEngineering
-							input = New XMLEngineeringInputDataProvider(f, True)
-						Case XMLNames.VectoInputDeclaration
-							input = New XMLDeclarationInputDataProvider(XmlReader.Create(f), True)
-					End Select
-			End Select
-
-			If input Is Nothing Then Throw New VectoException("No InputDataProvider for file {0} found!", f)
-
-			XMLExportJobDialog.Initialize(input)
-			XMLExportJobDialog.ShowDialog()
-		Catch ex As Exception
-			MsgBox("Exporting job failed: " + ex.Message)
-		End Try
-	End Sub
-
-	Private Sub LvGEN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LvGEN.SelectedIndexChanged
-		btnExportXML.Enabled = (LvGEN.SelectedItems.Count = 1)
-	End Sub
-
-	Private Sub btnImportXML_Click(sender As Object, e As EventArgs) Handles btnImportXML.Click
-		'Try
-		'	Dim jobFile As String = PluginRegistry.Instance.GetImportPlugin("TUG.IVT.Vecto.XMLImport").ImportJob()
-		'	AddToJobListView(jobFile)
-		'Catch ex As Exception
-		'	MsgBox("Importing job failed: " + ex.Message)
-		'End Try
-	End Sub
-
-	Private Sub LvGEN_MouseClick(sender As Object, e As MouseEventArgs) Handles LvGEN.MouseClick
-		If e.Button = MouseButtons.Right Then
-			_conMenTarget = LvGEN
-			_conMenTarJob = True
-
-			'Locked functions show/hide
-			LoadListToolStripMenuItem.Enabled = Not _guIlocked
-			LoadDefaultListToolStripMenuItem.Enabled = Not _guIlocked
-			ClearListToolStripMenuItem.Enabled = Not _guIlocked
-
-			ConMenFilelist.Show(MousePosition)
-		End If
-	End Sub
-
-	Private Sub ShowInFolderMenuItem_Click(sender As Object, e As EventArgs) Handles ShowInFolderMenuItem.Click
-
-		For Each item As ListViewItem In LvGEN.SelectedItems
-			Dim fileName As String = FileRepl(item.SubItems(0).Text)
-			If File.Exists(fileName) Then
-				Try
-					Process.Start("explorer", "/select,""" & fileName & "")
-				Catch ex As Exception
-					MsgBox("Failed to open file!")
-				End Try
-			Else
-				MsgBox("File not found: " & fileName)
-			End If
-		Next
-	End Sub
-
-	Private Sub EPTPJobEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
-		Handles EPTPJobEditorToolStripMenuItem.Click
-		OpenVECTOeditor("<VTP>")
-	End Sub
+    Private Sub LvMsg_KeyUp(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyUp
+        If (e.Control And e.KeyCode = Keys.C) Then
+            Dim builder As StringBuilder = New StringBuilder()
+            For Each selectedItem As ListViewItem In LvMsg.SelectedItems
+                builder.AppendLine(String.Join(", ",
+                                               selectedItem.SubItems.Cast (Of ListViewItem.ListViewSubItem).Select(
+                                                   Function(item) item.Text)))
+            Next
+            Clipboard.SetText(builder.ToString())
+        End If
+    End Sub
+
+    Private Sub LvMsg_MouseDown(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseDown
+        _mouseDownOnListView = True
+    End Sub
+
+    Private Sub LvMsg_MouseUp(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseUp
+        _mouseDownOnListView = False
+    End Sub
+
+    Private Sub RbDev_CheckedChanged(sender As Object, e As EventArgs) Handles RbDev.CheckedChanged
+    End Sub
+
+
+    Private Class VectoProgress
+        Public Target As String
+        Public Message As String
+        Public Link As String
+    End Class
+
+    Private Sub btnExportXML_Click(sender As Object, e As EventArgs) Handles btnExportXML.Click
+
+        If LvGEN.SelectedItems.Count < 1 Then
+            If LvGEN.Items.Count = 1 Then
+                LvGEN.Items(0).Selected = True
+            Else
+                Exit Sub
+            End If
+        End If
+
+        Dim f As String = LvGEN.SelectedItems(0).SubItems(0).Text
+        f = FileRepl(f)
+        If Not File.Exists(f) Then
+            MsgBox(f & " not found!")
+            Return
+        End If
+        Try
+            Dim input As IInputDataProvider = Nothing
+            Dim extension As String = Path.GetExtension(f)
+            Select Case extension
+                Case ".vecto"
+                    input = JSONInputDataFactory.ReadJsonJob(f)
+                Case ".xml"
+                    Dim xDocument As XDocument = xDocument.Load(f)
+                    Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName)
+                    Select Case rootNode
+                        Case XMLNames.VectoInputEngineering
+                            input = New XMLEngineeringInputDataProvider(f, True)
+                        Case XMLNames.VectoInputDeclaration
+                            input = New XMLDeclarationInputDataProvider(XmlReader.Create(f), True)
+                    End Select
+            End Select
+
+            If input Is Nothing Then Throw New VectoException("No InputDataProvider for file {0} found!", f)
+
+            XMLExportJobDialog.Initialize(input)
+            XMLExportJobDialog.ShowDialog()
+        Catch ex As Exception
+            MsgBox("Exporting job failed: " + ex.Message)
+        End Try
+    End Sub
+
+    Private Sub LvGEN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LvGEN.SelectedIndexChanged
+        btnExportXML.Enabled = (LvGEN.SelectedItems.Count = 1)
+    End Sub
+
+    Private Sub btnImportXML_Click(sender As Object, e As EventArgs) Handles btnImportXML.Click
+        'Try
+        '	Dim jobFile As String = PluginRegistry.Instance.GetImportPlugin("TUG.IVT.Vecto.XMLImport").ImportJob()
+        '	AddToJobListView(jobFile)
+        'Catch ex As Exception
+        '	MsgBox("Importing job failed: " + ex.Message)
+        'End Try
+    End Sub
+
+    Private Sub LvGEN_MouseClick(sender As Object, e As MouseEventArgs) Handles LvGEN.MouseClick
+        If e.Button = MouseButtons.Right Then
+            _conMenTarget = LvGEN
+            _conMenTarJob = True
+
+            'Locked functions show/hide
+            LoadListToolStripMenuItem.Enabled = Not _guIlocked
+            LoadDefaultListToolStripMenuItem.Enabled = Not _guIlocked
+            ClearListToolStripMenuItem.Enabled = Not _guIlocked
+
+            ConMenFilelist.Show(MousePosition)
+        End If
+    End Sub
+
+    Private Sub ShowInFolderMenuItem_Click(sender As Object, e As EventArgs) Handles ShowInFolderMenuItem.Click
+
+        For Each item As ListViewItem In LvGEN.SelectedItems
+            Dim fileName As String = FileRepl(item.SubItems(0).Text)
+            If File.Exists(fileName) Then
+                Try
+                    Process.Start("explorer", "/select,""" & fileName & "")
+                Catch ex As Exception
+                    MsgBox("Failed to open file!")
+                End Try
+            Else
+                MsgBox("File not found: " & fileName)
+            End If
+        Next
+    End Sub
+
+    Private Sub EPTPJobEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _
+        Handles EPTPJobEditorToolStripMenuItem.Click
+        OpenVECTOeditor("<VTP>")
+    End Sub
 End Class
 
 
diff --git a/VECTO/Input Files/Engine.vb b/VECTO/Input Files/Engine.vb
index 8844e6825d..2231cd359a 100644
--- a/VECTO/Input Files/Engine.vb	
+++ b/VECTO/Input Files/Engine.vb	
@@ -313,9 +313,9 @@ Public Class Engine
 		End Get
 	End Property
 
-	Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue
+	Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue
 		Get
-			Return ""
+			Return Nothing
 		End Get
 	End Property
 
diff --git a/VECTO/Input Files/Gearbox.vb b/VECTO/Input Files/Gearbox.vb
index 7e71142719..b579746241 100644
--- a/VECTO/Input Files/Gearbox.vb	
+++ b/VECTO/Input Files/Gearbox.vb	
@@ -331,9 +331,9 @@ Public Class Gearbox
 		End Get
 	End Property
 
-	Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue
+	Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue
 		Get
-			Return ""
+			Return Nothing
 		End Get
 	End Property
 
diff --git a/VECTO/Input Files/VectoEPTPJob.vb b/VECTO/Input Files/VectoEPTPJob.vb
index f0e35fd2d4..21751d63aa 100644
--- a/VECTO/Input Files/VectoEPTPJob.vb	
+++ b/VECTO/Input Files/VectoEPTPJob.vb	
@@ -14,6 +14,7 @@ Imports TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 Imports TUGraz.VectoCore.InputData.Impl
 Imports TUGraz.VectoCore.Models.Declaration
 Imports TUGraz.VectoCore.Utils
+Imports TUGraz.VectoHashing
 
 <CustomValidation(GetType(VectoVTPJob), "ValidateJob")>
 Public Class VectoVTPJob
@@ -115,6 +116,11 @@ Public Class VectoVTPJob
         End Get
     End Property
 
+    Public ReadOnly Property IVTPDeclarationJobInputData_ManufacturerReportInputData As IManufacturerReport Implements IVTPDeclarationJobInputData.ManufacturerReportInputData
+
+    Public ReadOnly Property VectoJobHash As IVectoHash Implements IVTPDeclarationJobInputData.VectoJobHash
+    Public ReadOnly Property VectoManufacturerReportHash As IVectoHash Implements IVTPDeclarationJobInputData.VectoManufacturerReportHash
+
     Public ReadOnly Property Cycles As IList(Of ICycleData) Implements IVTPEngineeringJobInputData.Cycles
         Get
             Dim retVal As ICycleData() = New ICycleData(CycleFiles.Count - 1) {}
@@ -174,6 +180,7 @@ Public Class VectoVTPJob
         End Get
     End Property
 
+   
     Public ReadOnly Property IVTPDeclarationInputDataProvider_JobInputData As IVTPDeclarationJobInputData _
         Implements IVTPDeclarationInputDataProvider.JobInputData
         get
diff --git a/VECTO/Input Files/Vehicle.vb b/VECTO/Input Files/Vehicle.vb
index 73b06f1558..49bc8665e1 100644
--- a/VECTO/Input Files/Vehicle.vb	
+++ b/VECTO/Input Files/Vehicle.vb	
@@ -300,9 +300,9 @@ Public Class Vehicle
 		End Get
 	End Property
 
-	Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue
+	Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue
 		Get
-			Return ""
+			Return Nothing
 		End Get
 	End Property
 
diff --git a/VectoCommon/VectoHashing/IVectoHash.cs b/VectoCommon/VectoCommon/Hashing/IVectoHash.cs
similarity index 98%
rename from VectoCommon/VectoHashing/IVectoHash.cs
rename to VectoCommon/VectoCommon/Hashing/IVectoHash.cs
index e41eb4599a..96a9b21bb4 100644
--- a/VectoCommon/VectoHashing/IVectoHash.cs
+++ b/VectoCommon/VectoCommon/Hashing/IVectoHash.cs
@@ -1,166 +1,167 @@
-/*
-* 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.Collections.Generic;
-using System.Xml.Linq;
-
-namespace TUGraz.VectoHashing
-{
-	/// <summary>
-	/// Interface definition for hashing and verifying VECTO XML files
-	/// </summary>
-	public interface IVectoHash
-	{
-		/// <summary>
-		/// Get a list of all vecto components contained in the XML file. If a certain
-		/// component appears multiple times (e.g. tires) it is provided multiple times 
-		/// in the returned list.
-		/// to get a list with unique entries (and the number of occurences) use e.g.
-		/// GetContainigComponents().GroupBy(s => s).Select(g => new { Entry = g.Key, Count = g.Count() })
-		/// </summary>
-		/// <returns>List of components contained in the current XML document</returns>
-		IList<VectoComponents> GetContainigComponents();
-
-
-		/// <summary>
-		/// Get the digest method used to compute the digest value of the top-level Signature element
-		/// if there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaultDigestMethod)
-		/// </summary>
-		/// <returns>identifier (urn) of the digest method</returns>
-		string GetDigestMethod();
-
-
-		/// <summary>
-		/// Get the digest method of the Signature element for the given component. If a component exists 
-		/// multiple times (e.g., tires), the index specifies for which component the digest method is returned
-		/// </summary>
-		/// <param name="component">VectoComponent to get the digest method for</param>
-		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
-		/// <returns>identifier (urn) of the digest method</returns>
-		string GetDigestMethod(VectoComponents component, int index = 0);
-
-
-		/// <summary>
-		/// Get the list of canonicalization methods used to compute the digest value of the top-level Signature element
-		/// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod)
-		/// </summary>
-		/// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns>
-		IEnumerable<string> GetCanonicalizationMethods();
-
-
-		/// <summary>
-		/// Get the list of canonicalization methods used to compute the digest value of the Signature element 
-		/// for the given component. If a component exists multiple times (e.g., tires) the indes specifies for which
-		/// component the canonicalization method is returned
-		/// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod)
-		/// </summary>
-		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
-		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
-		/// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns>
-		IEnumerable<string> GetCanonicalizationMethods(VectoComponents component, int index = 0);
-
-
-		/// <summary>
-		/// Reads the hash-value of the top-level Signature element
-		/// </summary>
-		/// <returns>base64 encoded hash value</returns>
-		string ReadHash();
-
-
-		/// <summary>
-		/// Reads the hash-value of the Signature element for the given component. If a component can exist 
-		/// multiple times (i.e., tires), the index specifies for which component the hash is computed
-		/// </summary>
-		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
-		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
-		/// <returns>base64 encoded hash value</returns>
-		string ReadHash(VectoComponents component, int index = 0);
-
-
-		/// <summary>
-		/// Computes the hash-value of the top-level Data element (or vehicle)
-		/// If the canoonicalizationMethods is null the canonicalizationMethods from 
-		/// the signature element are read if available or the default canonicalization is applied
-		/// If the digestMethod is null the digestMethod from the signature element is read if 
-		/// available or the default digestMethod is used
-		/// Note: the top-level Data element is required to have an id attribute!
-		/// </summary>
-		/// <param name="canonicalizationMethods">Canonicalization methods to use. If null the default methods are applied</param>
-		/// <param name="digestMethod">Digest method to use. If null, the default digest method is used.</param>
-		/// <returns>base64 encoded hash value</returns>
-		string ComputeHash(IEnumerable<string> canonicalizationMethods = null, string digestMethod = null);
-
-
-		/// <summary>
-		/// Computes the hash-value for the given component. If a component can exist multiple times
-		/// (i.e., Tyres) the index specifies for which component the hash is computed
-		/// If the canoonicalizationMethods is null the canonicalizationMethods from 
-		/// the signature element are read if available or the default canonicalization is applied
-		/// If the digestMethod is null the digestMethod from the signature element is read if 
-		/// available or the default digestMethod is used
-		/// Note: the Data element is required to have an id attribute!
-		/// </summary>
-		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
-		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
-		/// <param name="canonicalizationMethods">list of identifiers (urn) of the canonicalization methods to apply. If null, the default canonicalization methods are used</param>
-		/// <param name="digestMethod">identifier (urn) of the digest method to use. If null, the default digest method is used</param>
-		/// <returns></returns>
-		string ComputeHash(VectoComponents component, int index = 0, IEnumerable<string> canonicalizationMethods = null,
-			string digestMethod = null);
-
-
-		/// <summary>
-		/// Validates the hash of the top-level component (or vehicle)
-		/// </summary>
-		/// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns>
-		bool ValidateHash();
-
-
-		/// <summary>
-		/// Validates the hash for the given component.
-		/// </summary>
-		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
-		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
-		/// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns>
-		bool ValidateHash(VectoComponents component, int index = 0);
-
-
-		/// <summary>
-		/// Computes the hash-value of the outer Data element and adds the according Signature element 
-		/// after the Data element.
-		/// The default CaonocalizationMethods and DigestMethod are used.
-		/// Note: the id attribute is added to the Data element automatically. if an id attribute is already
-		/// present its value is overwritten unless its lenth is more than 5 characters.
-		/// </summary>
-		/// <returns>returns the given document including the Signature element with the hash of the Data block</returns>
-		XDocument AddHash();
-	}
-}
+/*
+* 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.Collections.Generic;
+using System.Xml.Linq;
+using TUGraz.VectoCommon.Hashing;
+
+namespace TUGraz.VectoHashing
+{
+	/// <summary>
+	/// Interface definition for hashing and verifying VECTO XML files
+	/// </summary>
+	public interface IVectoHash
+	{
+		/// <summary>
+		/// Get a list of all vecto components contained in the XML file. If a certain
+		/// component appears multiple times (e.g. tires) it is provided multiple times 
+		/// in the returned list.
+		/// to get a list with unique entries (and the number of occurences) use e.g.
+		/// GetContainigComponents().GroupBy(s => s).Select(g => new { Entry = g.Key, Count = g.Count() })
+		/// </summary>
+		/// <returns>List of components contained in the current XML document</returns>
+		IList<VectoComponents> GetContainigComponents();
+
+
+		/// <summary>
+		/// Get the digest method used to compute the digest value of the top-level Signature element
+		/// if there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaultDigestMethod)
+		/// </summary>
+		/// <returns>identifier (urn) of the digest method</returns>
+		string GetDigestMethod();
+
+
+		/// <summary>
+		/// Get the digest method of the Signature element for the given component. If a component exists 
+		/// multiple times (e.g., tires), the index specifies for which component the digest method is returned
+		/// </summary>
+		/// <param name="component">VectoComponent to get the digest method for</param>
+		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
+		/// <returns>identifier (urn) of the digest method</returns>
+		string GetDigestMethod(VectoComponents component, int index = 0);
+
+
+		/// <summary>
+		/// Get the list of canonicalization methods used to compute the digest value of the top-level Signature element
+		/// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod)
+		/// </summary>
+		/// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns>
+		IEnumerable<string> GetCanonicalizationMethods();
+
+
+		/// <summary>
+		/// Get the list of canonicalization methods used to compute the digest value of the Signature element 
+		/// for the given component. If a component exists multiple times (e.g., tires) the indes specifies for which
+		/// component the canonicalization method is returned
+		/// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod)
+		/// </summary>
+		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
+		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
+		/// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns>
+		IEnumerable<string> GetCanonicalizationMethods(VectoComponents component, int index = 0);
+
+
+		/// <summary>
+		/// Reads the hash-value of the top-level Signature element
+		/// </summary>
+		/// <returns>base64 encoded hash value</returns>
+		string ReadHash();
+
+
+		/// <summary>
+		/// Reads the hash-value of the Signature element for the given component. If a component can exist 
+		/// multiple times (i.e., tires), the index specifies for which component the hash is computed
+		/// </summary>
+		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
+		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
+		/// <returns>base64 encoded hash value</returns>
+		string ReadHash(VectoComponents component, int index = 0);
+
+
+		/// <summary>
+		/// Computes the hash-value of the top-level Data element (or vehicle)
+		/// If the canoonicalizationMethods is null the canonicalizationMethods from 
+		/// the signature element are read if available or the default canonicalization is applied
+		/// If the digestMethod is null the digestMethod from the signature element is read if 
+		/// available or the default digestMethod is used
+		/// Note: the top-level Data element is required to have an id attribute!
+		/// </summary>
+		/// <param name="canonicalizationMethods">Canonicalization methods to use. If null the default methods are applied</param>
+		/// <param name="digestMethod">Digest method to use. If null, the default digest method is used.</param>
+		/// <returns>base64 encoded hash value</returns>
+		string ComputeHash(IEnumerable<string> canonicalizationMethods = null, string digestMethod = null);
+
+
+		/// <summary>
+		/// Computes the hash-value for the given component. If a component can exist multiple times
+		/// (i.e., Tyres) the index specifies for which component the hash is computed
+		/// If the canoonicalizationMethods is null the canonicalizationMethods from 
+		/// the signature element are read if available or the default canonicalization is applied
+		/// If the digestMethod is null the digestMethod from the signature element is read if 
+		/// available or the default digestMethod is used
+		/// Note: the Data element is required to have an id attribute!
+		/// </summary>
+		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
+		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
+		/// <param name="canonicalizationMethods">list of identifiers (urn) of the canonicalization methods to apply. If null, the default canonicalization methods are used</param>
+		/// <param name="digestMethod">identifier (urn) of the digest method to use. If null, the default digest method is used</param>
+		/// <returns></returns>
+		string ComputeHash(VectoComponents component, int index = 0, IEnumerable<string> canonicalizationMethods = null,
+			string digestMethod = null);
+
+
+		/// <summary>
+		/// Validates the hash of the top-level component (or vehicle)
+		/// </summary>
+		/// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns>
+		bool ValidateHash();
+
+
+		/// <summary>
+		/// Validates the hash for the given component.
+		/// </summary>
+		/// <param name="component">VectoComponent to get the canonicalization methods for</param>
+		/// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param>
+		/// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns>
+		bool ValidateHash(VectoComponents component, int index = 0);
+
+
+		/// <summary>
+		/// Computes the hash-value of the outer Data element and adds the according Signature element 
+		/// after the Data element.
+		/// The default CaonocalizationMethods and DigestMethod are used.
+		/// Note: the id attribute is added to the Data element automatically. if an id attribute is already
+		/// present its value is overwritten unless its lenth is more than 5 characters.
+		/// </summary>
+		/// <returns>returns the given document including the Signature element with the hash of the Data block</returns>
+		XDocument AddHash();
+	}
+}
diff --git a/VectoCommon/VectoHashing/VectoComponents.cs b/VectoCommon/VectoCommon/Hashing/VectoComponents.cs
similarity index 96%
rename from VectoCommon/VectoHashing/VectoComponents.cs
rename to VectoCommon/VectoCommon/Hashing/VectoComponents.cs
index 81665bc0e7..0b4d642d43 100644
--- a/VectoCommon/VectoHashing/VectoComponents.cs
+++ b/VectoCommon/VectoCommon/Hashing/VectoComponents.cs
@@ -1,112 +1,112 @@
-/*
-* 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 TUGraz.VectoCommon.Resources;
-
-namespace TUGraz.VectoHashing
-{
-	public enum VectoComponents
-	{
-		Engine,
-		Gearbox,
-		Axlegear,
-		Retarder,
-		TorqueConverter,
-		Angledrive,
-		Airdrag,
-		Tyre,
-		Vehicle,
-		VectoOutput,
-		VectoCustomerInformation
-	}
-
-	public static class VectoComponentsExtensionMethods
-	{
-		public static string XMLElementName(this VectoComponents component)
-		{
-			switch (component) {
-				case VectoComponents.Engine:
-					return XMLNames.Component_Engine;
-				case VectoComponents.Gearbox:
-					return XMLNames.Component_Gearbox;
-				case VectoComponents.Axlegear:
-					return XMLNames.Component_Axlegear;
-				case VectoComponents.Retarder:
-					return XMLNames.Component_Retarder;
-				case VectoComponents.TorqueConverter:
-					return XMLNames.Component_TorqueConverter;
-				case VectoComponents.Angledrive:
-					return XMLNames.Component_Angledrive;
-				case VectoComponents.Airdrag:
-					return XMLNames.Component_AirDrag;
-				case VectoComponents.Tyre:
-					return XMLNames.AxleWheels_Axles_Axle_Tyre;
-				case VectoComponents.Vehicle:
-					return XMLNames.Component_Vehicle;
-				case VectoComponents.VectoOutput:
-					return "VectoOutput";
-				case VectoComponents.VectoCustomerInformation:
-					return "VectoCustomerInformation";
-				default:
-					throw new ArgumentOutOfRangeException("VectoComponents", component, null);
-			}
-		}
-
-		public static string HashIdPrefix(this VectoComponents component)
-		{
-			switch (component) {
-				case VectoComponents.Engine:
-					return "ENG-";
-				case VectoComponents.Gearbox:
-					return "GBX-";
-				case VectoComponents.Axlegear:
-					return "AXL-";
-				case VectoComponents.Retarder:
-					return "RET-";
-				case VectoComponents.TorqueConverter:
-					return "TC-";
-				case VectoComponents.Angledrive:
-					return "ANGL-";
-				case VectoComponents.Airdrag:
-					return "AD-";
-				case VectoComponents.Tyre:
-					return "TYRE-";
-				case VectoComponents.VectoOutput:
-					return "RESULT-";
-				case VectoComponents.VectoCustomerInformation:
-					return "COC-";
-				default:
-					throw new ArgumentOutOfRangeException("VectoComponents", component, null);
-			}
-		}
-	}
+/*
+* 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 TUGraz.VectoCommon.Resources;
+
+namespace TUGraz.VectoCommon.Hashing
+{
+	public enum VectoComponents
+	{
+		Engine,
+		Gearbox,
+		Axlegear,
+		Retarder,
+		TorqueConverter,
+		Angledrive,
+		Airdrag,
+		Tyre,
+		Vehicle,
+		VectoOutput,
+		VectoCustomerInformation
+	}
+
+	public static class VectoComponentsExtensionMethods
+	{
+		public static string XMLElementName(this VectoComponents component)
+		{
+			switch (component) {
+				case VectoComponents.Engine:
+					return XMLNames.Component_Engine;
+				case VectoComponents.Gearbox:
+					return XMLNames.Component_Gearbox;
+				case VectoComponents.Axlegear:
+					return XMLNames.Component_Axlegear;
+				case VectoComponents.Retarder:
+					return XMLNames.Component_Retarder;
+				case VectoComponents.TorqueConverter:
+					return XMLNames.Component_TorqueConverter;
+				case VectoComponents.Angledrive:
+					return XMLNames.Component_Angledrive;
+				case VectoComponents.Airdrag:
+					return XMLNames.Component_AirDrag;
+				case VectoComponents.Tyre:
+					return XMLNames.AxleWheels_Axles_Axle_Tyre;
+				case VectoComponents.Vehicle:
+					return XMLNames.Component_Vehicle;
+				case VectoComponents.VectoOutput:
+					return "VectoOutput";
+				case VectoComponents.VectoCustomerInformation:
+					return "VectoCustomerInformation";
+				default:
+					throw new ArgumentOutOfRangeException("VectoComponents", component, null);
+			}
+		}
+
+		public static string HashIdPrefix(this VectoComponents component)
+		{
+			switch (component) {
+				case VectoComponents.Engine:
+					return "ENG-";
+				case VectoComponents.Gearbox:
+					return "GBX-";
+				case VectoComponents.Axlegear:
+					return "AXL-";
+				case VectoComponents.Retarder:
+					return "RET-";
+				case VectoComponents.TorqueConverter:
+					return "TC-";
+				case VectoComponents.Angledrive:
+					return "ANGL-";
+				case VectoComponents.Airdrag:
+					return "AD-";
+				case VectoComponents.Tyre:
+					return "TYRE-";
+				case VectoComponents.VectoOutput:
+					return "RESULT-";
+				case VectoComponents.VectoCustomerInformation:
+					return "COC-";
+				default:
+					throw new ArgumentOutOfRangeException("VectoComponents", component, null);
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs
index 9bbbb02469..740bd2adbf 100644
--- a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs
+++ b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs
@@ -62,7 +62,7 @@ namespace TUGraz.VectoCommon.InputData
 
 		string CertificationNumber { get; }
 
-		string DigestValue { get; }
+		DigestData DigestValue { get; }
 	}
 
 	public interface IVehicleDeclarationInputData : IComponentInputData
diff --git a/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs
index 530be45d71..9f7918bb28 100644
--- a/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs
+++ b/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs
@@ -30,19 +30,30 @@
 */
 
 using System.Collections.Generic;
+using System.Xml;
+using System.Xml.XPath;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoHashing;
 
 namespace TUGraz.VectoCommon.InputData
 {
 	public interface IVTPDeclarationInputDataProvider : IInputDataProvider
 	{
 		IVTPDeclarationJobInputData JobInputData { get; }
+
 	}
 
 	public interface IVTPDeclarationJobInputData
 	{
 		IVehicleDeclarationInputData Vehicle { get; }
 
+		IManufacturerReport ManufacturerReportInputData { get; }
+
+		IVectoHash VectoJobHash { get; }
+
+		IVectoHash VectoManufacturerReportHash { get; }
+
 		IList<ICycleData> Cycles { get; }
 
 		IEnumerable<double> FanPowerCoefficents { get; }
@@ -51,4 +62,63 @@ namespace TUGraz.VectoCommon.InputData
 
 		Meter FanDiameter { get; }
 	}
+
+	public interface IManufacturerReport
+	{
+		IDictionary<VectoComponents,IList<string>> ComponentDigests { get; }
+
+		DigestData JobDigest { get; }
+	}
+
+	public class DigestData
+	{
+		private const string ReferenceQueryXPath = ".//*[local-name()='Reference']/@URI";
+		private const string AlgorithmQueryXPath = ".//*[local-name()='Transform']/@Algorithm";
+		private const string DigestMethodQueryXPath = ".//*[local-name()='DigestMethod']/@Algorithm";
+		private const string DigestValueQuerXPath = ".//*[local-name()='DigestValue']";
+
+		public DigestData(string reference, string[] c14n, string digestMethod, string digestValue)
+		{
+			Reference = reference;
+			CanonicalizationMethods = c14n;
+			DigestMethod = digestMethod;
+			DigestValue = digestValue;
+		}
+
+		public DigestData(XPathNavigator navigator)
+		{
+			Reference = navigator.SelectSingleNode(ReferenceQueryXPath)?.InnerXml;
+			var nodes = navigator.Select(AlgorithmQueryXPath);
+			var c14n = new List<string>();
+			while (nodes.MoveNext()) {
+				c14n.Add(nodes.Current.InnerXml);
+			}
+			CanonicalizationMethods = c14n.ToArray();
+			DigestMethod = navigator.SelectSingleNode(DigestMethodQueryXPath)?.InnerXml;
+			DigestValue = navigator.SelectSingleNode(DigestValueQuerXPath)?.InnerXml;
+		}
+
+		public DigestData(XmlNode xmlNode)
+		{
+			Reference = xmlNode.SelectSingleNode(ReferenceQueryXPath)?.InnerXml;
+			var nodes = xmlNode.SelectNodes(AlgorithmQueryXPath);
+			var c14n = new List<string>();
+			if (nodes != null) {
+				for (var i = 0; i < nodes.Count; i++) {
+					c14n.Add(nodes[i].InnerXml);
+				}
+			}
+			CanonicalizationMethods = c14n.ToArray();
+			DigestMethod = xmlNode.SelectSingleNode(DigestMethodQueryXPath)?.InnerXml;
+			DigestValue = xmlNode.SelectSingleNode(DigestValueQuerXPath)?.InnerXml;
+		}
+
+		public string DigestValue { get; }
+
+		public string Reference { get; }
+
+		public string[] CanonicalizationMethods { get; }
+		public string DigestMethod { get; }
+
+	}
 }
diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs
index 658a9a8b32..ed8559e923 100644
--- a/VectoCommon/VectoCommon/Utils/SI.cs
+++ b/VectoCommon/VectoCommon/Utils/SI.cs
@@ -42,1720 +42,1720 @@ using TUGraz.VectoCommon.Exceptions;
 
 namespace TUGraz.VectoCommon.Utils
 {
-    /// <summary>
-    /// SI Class for Scalar Values. Converts implicitely to double and is only castable if the SI value has no units.
-    /// </summary>
-    public class Scalar : SIBase<Scalar>
-    {
-        private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 };
-
-        [DebuggerHidden]
-        private Scalar(double val) : base(val, Units) { }
-
-        public static implicit operator double(Scalar self)
-        {
-            return self.Val;
-        }
-
-        [DebuggerHidden]
-        public static Scalar operator +(Scalar si1, Scalar si2)
-        {
-            return Create(si1.Val + si2.Val);
-        }
-
-        [DebuggerHidden]
-        public static Scalar operator +(Scalar si1, double si2)
-        {
-            return Create(si1.Val + si2);
-        }
-
-        [DebuggerHidden]
-        public static Scalar operator +(double si1, Scalar si2)
-        {
-            return Create(si1 + si2.Val);
-        }
-
-        [DebuggerHidden]
-        public static Scalar operator -(Scalar si1, Scalar si2)
-        {
-            return Create(si1.Val - si2.Val);
-        }
-
-        [DebuggerHidden]
-        public static Scalar operator -(Scalar si1, double si2)
-        {
-            return Create(si1.Val - si2);
-        }
-
-        [DebuggerHidden]
-        public static Scalar operator -(double si1, Scalar si2)
-        {
-            return Create(si1 - si2.Val);
-        }
-    }
-
-    /// <summary>
-    /// SI Class for Newton [N].
-    /// </summary>
-    public class Newton : SIBase<Newton>
-    {
-        private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 };
-
-        [DebuggerHidden]
-        private Newton(double val) : base(val, Units) { }
-
-		public override string UnitString { get { return "N"; } }
+	/// <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]
-        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) { }
-
-		public override string UnitString { get { return "kg/m"; } }
+		private Scalar(double val) : base(val, Units) { }
 
-		public static KilogramPerMeterMass operator /(KilogramPerMeter kpm, Kilogram kg)
+		public static implicit operator double(Scalar self)
 		{
-			return SIBase<KilogramPerMeterMass>.Create(kpm.Val / kg.Value());
+			return self.Val;
 		}
 
-		public static KilogramPerMeterCubicMeter operator /(KilogramPerMeter kpm, CubicMeter vol)
+		[DebuggerHidden]
+		public static Scalar operator +(Scalar si1, Scalar si2)
 		{
-			return SIBase<KilogramPerMeterCubicMeter>.Create(kpm.Val / vol.Value());
+			return Create(si1.Val + si2.Val);
 		}
-	}
 
-    /// <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 };
+		[DebuggerHidden]
+		public static Scalar operator +(Scalar si1, double si2)
+		{
+			return Create(si1.Val + si2);
+		}
 
-        private LiterPerSecond(double val) : base(val, 0.001, Units) { }
+		[DebuggerHidden]
+		public static Scalar operator +(double si1, Scalar si2)
+		{
+			return Create(si1 + si2.Val);
+		}
 
-		public override string UnitString { get { return "l/s"; } }
+		[DebuggerHidden]
+		public static Scalar operator -(Scalar si1, Scalar si2)
+		{
+			return Create(si1.Val - si2.Val);
+		}
 
 		[DebuggerHidden]
-		public static Liter operator *(LiterPerSecond l, Second second)
+		public static Scalar operator -(Scalar si1, double si2)
 		{
-			return SIBase<Liter>.Create(l.Val * second.Value());
+			return Create(si1.Val - si2);
 		}
 
 		[DebuggerHidden]
-		public static Liter operator *(Second second, LiterPerSecond l)
+		public static Scalar operator -(double si1, Scalar si2)
 		{
-			return SIBase<Liter>.Create(l.Val * second.Value());
+			return Create(si1 - si2.Val);
 		}
 	}
 
-    /// <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());
-        }
+	/// <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]
-		public static SpecificFuelConsumption operator /(Kilogram kg, WattSecond ws)
+		private Newton(double val) : base(val, Units) { }
+
+		public override string UnitString { get { return "N"; } }
+
+		[DebuggerHidden]
+		public static NewtonMeter operator *(Newton newton, Meter meter)
 		{
-			return SIBase<SpecificFuelConsumption>.Create(kg.Val / ws.Value());
+			return SIBase<NewtonMeter>.Create(newton.Val * meter.Value());
 		}
 
 		[DebuggerHidden]
-        public static Newton operator *(Kilogram kg, MeterPerSquareSecond m)
-        {
-            return SIBase<Newton>.Create(kg.Val * m.Value());
-        }
+		public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond)
+		{
+			return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value());
+		}
 
-        [DebuggerHidden]
-        public static Kilogram operator *(Kilogram kg, double d)
-        {
-            return new Kilogram(kg.Val * d);
-        }
+		[DebuggerHidden]
+		public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton)
+		{
+			return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value());
+		}
+	}
 
-        [DebuggerHidden]
-        public static Kilogram operator *(double d, Kilogram kg)
-        {
-            return new Kilogram(d * kg.Val);
-        }
+	/// <summary>
+	/// SI Class for Radian [] (rad).
+	/// </summary>
+	public class Radian : SIBase<Radian>
+	{
+		private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 };
 
-        public static CubicMeter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter)
-        {
-            return SIBase<CubicMeter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value());
-        }
-    }
+		[DebuggerHidden]
+		private Radian(double val) : base(val, Units) { }
+	}
 
-    public class Liter : SIBase<Liter>
-    {
-        private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
+	/// <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]
-        //[DebuggerHidden]
-        private Liter(double val) : base(val , 0.001, Units) { }
+		[DebuggerHidden]
+		private PerSquareSecond(double val) : base(val, Units) { }
 
-		public override string UnitString { get { return "l"; } }
+		[DebuggerHidden]
+		public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second)
+		{
+			return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value());
+		}
+	}
 
-		public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter)
-        {
-            return SIBase<Kilogram>.Create(liter.AsBasicUnit * kilogramPerCubicMeter.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 };
 
-    /// <summary>
-    /// 
-    /// </summary>
-    public class NormLiter : SIBase<NormLiter>
-    {
-        private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
+		[DebuggerHidden]
+		private MeterPerSquareSecond(double val) : base(val, Units) { }
 
-        //[DebuggerHidden]
-        private NormLiter(double val) : base(val , 0.001, Units) { }
+		/// <summary>
+		/// Implements the operator *.
+		/// </summary>
+		[DebuggerHidden]
+		public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second)
+		{
+			return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value());
+		}
+	}
 
-		public override string UnitString { get { return "Nl"; } }
+	/// <summary>
+	/// SI Class for Second [s].
+	/// </summary>
+	public class Second : SIBase<Second>
+	{
+		private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 };
 
-		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 Second(double val) : base(val, Units) { }
+	}
 
-		//[DebuggerHidden]
-		private NormLiterPerSecond(double val) : base(val, 0.001, 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 };
 
-		public override string UnitString { get { return "Nl/s"; } }
+		[DebuggerHidden]
+		private Meter(double val) : base(val, Units) { }
 
-		public static NormLiter operator *(NormLiterPerSecond nips, Second s)
-        {
-            return SIBase<NormLiter>.Create(nips.Val * s.Value());
-        }
+		[DebuggerHidden]
+		public static MeterPerSecond operator /(Meter meter, Second second)
+		{
+			return SIBase<MeterPerSecond>.Create(meter.Val / second.Value());
+		}
 
-        public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val)
-        {
-            return Create(nps.Val  * val);
-        }
+		[DebuggerHidden]
+		public static MeterPerSecond operator *(Meter meter, PerSecond perSecond)
+		{
+			return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value());
+		}
 
-		public static NormLiterPerSecond operator /(NormLiterPerSecond nps, double val)
+		/// <summary>
+		/// Implements the operator /.
+		/// </summary>
+		[DebuggerHidden]
+		public static Second operator /(Meter second, MeterPerSecond meterPerSecond)
 		{
-			return Create(nps.Val / val);
+			return SIBase<Second>.Create(second.Val / meterPerSecond.Value());
 		}
 	}
 
-    /// <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 per Cubic Meter [kg/m^3].
-    /// </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) { }
-
-		public override string UnitString { get { return "kg/m^3"; } }
+	/// <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]
-        public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter)
-        {
-            return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value());
-        }
-
-    }
+		private KilogramPerMeter(double val) : base(val, Units) { }
 
-    /// <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 };
+		public override string UnitString { get { return "kg/m"; } }
 
-        [DebuggerHidden]
-        private KilogramPerWattSecond(double val) : base(val, Units) { }
+		public static KilogramPerMeterMass operator /(KilogramPerMeter kpm, Kilogram kg)
+		{
+			return SIBase<KilogramPerMeterMass>.Create(kpm.Val / kg.Value());
+		}
 
-		public override string UnitString { get { return "kg/Ws"; } }
+		public static KilogramPerMeterCubicMeter operator /(KilogramPerMeter kpm, CubicMeter vol)
+		{
+			return SIBase<KilogramPerMeterCubicMeter>.Create(kpm.Val / vol.Value());
+		}
 	}
 
-    /// <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 };
+	/// <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 };
 
-        [DebuggerHidden]
-        private WattSecond(double val) : base(val, Units) { }
+		private LiterPerSecond(double val) : base(val, 0.001, Units) { }
 
-		public override string UnitString { get { return "Ws"; } }
+		public override string UnitString { get { return "l/s"; } }
 
 		[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 };
+		public static Liter operator *(LiterPerSecond l, Second second)
+		{
+			return SIBase<Liter>.Create(l.Val * second.Value());
+		}
 
-        [DebuggerHidden]
-        private Watt(double val) : base(val, Units) { }
+		[DebuggerHidden]
+		public static Liter operator *(Second second, LiterPerSecond l)
+		{
+			return SIBase<Liter>.Create(l.Val * second.Value());
+		}
+	}
 
-		public override string UnitString { get { return "W"; } }
+	/// <summary>
+	/// SI Class for Kilogram [kg].
+	/// </summary>
+	public class Kilogram : SIBase<Kilogram>
+	{
+		private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 };
 
-		/// <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 override string UnitString { get { return "J"; } }
+		private Kilogram(double val) : base(val, Units) { }
 
-        public static implicit operator Joule(WattSecond self)
-        {
-            return Create(self.Value());
-        }
+		[DebuggerHidden]
+		public static KilogramPerSecond operator /(Kilogram kg, Second second)
+		{
+			return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value());
+		}
 
-        public static Joule operator +(Joule joule, WattSecond ws)
-        {
-            return Create(joule.Val + ws.Value());
-        }
+		//[DebuggerHidden]
+		//public static SI operator /(Kilogram kg, Joule j)
+		//{
+		//    return (kg as SI) / j;
+		//}
 
-        public static Watt operator /(Joule joule, Second s)
-        {
-            return SIBase<Watt>.Create(joule.Val / s.Value());
-        }
+		[DebuggerHidden]
+		public static Scalar operator /(Kilogram kg, Kilogram kg2)
+		{
+			return SIBase<Scalar>.Create(kg.Val / kg2.Val);
+		}
 
-        public static JoulePerMeter operator /(Joule joule, Meter meter)
-        {
-            return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value());
-        }
-    }
+		[DebuggerHidden]
+		public static KilogramPerMeter operator /(Kilogram kg, Meter m)
+		{
+			return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value());
+		}
 
-    /// <summary>
-    /// SI Class for Joule / kg.
-    /// </summary>
-    public class JoulePerKilogramm : SIBase<JoulePerKilogramm>
-    {
-        private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 };
+		[DebuggerHidden]
+		public static SpecificFuelConsumption operator /(Kilogram kg, WattSecond ws)
+		{
+			return SIBase<SpecificFuelConsumption>.Create(kg.Val / ws.Value());
+		}
 
-        private JoulePerKilogramm(double val) : base(val, Units) { }
+		[DebuggerHidden]
+		public static Newton operator *(Kilogram kg, MeterPerSquareSecond m)
+		{
+			return SIBase<Newton>.Create(kg.Val * m.Value());
+		}
 
-		public override string UnitString { get { return "J/kg"; } }
+		[DebuggerHidden]
+		public static Kilogram operator *(Kilogram kg, double d)
+		{
+			return new Kilogram(kg.Val * d);
+		}
 
-		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) { }
+		[DebuggerHidden]
+		public static Kilogram operator *(double d, Kilogram kg)
+		{
+			return new Kilogram(d * kg.Val);
+		}
 
-		public override string UnitString { get { return "J/m"; } }
+		public static CubicMeter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter)
+		{
+			return SIBase<CubicMeter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value());
+		}
 	}
 
-    /// <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) { }
-
-		public override string UnitString { get { return "Nm"; } }
+	public class Liter : SIBase<Liter>
+	{
+		private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
 
 		[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) { }
+		//[DebuggerHidden]
+		private Liter(double val) : base(val , 0.001, Units) { }
 
-		public override string UnitString { get { return "Nms"; } }
+		public override string UnitString { get { return "l"; } }
+
+		public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter)
+		{
+			return SIBase<Kilogram>.Create(liter.AsBasicUnit * kilogramPerCubicMeter.Value());
+		}
 	}
 
-    /// <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) { }
+	/// <summary>
+	/// 
+	/// </summary>
+	public class NormLiter : SIBase<NormLiter>
+	{
+		private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
 
-		public override string UnitString { get { return "V"; } }
+		//[DebuggerHidden]
+		private NormLiter(double val) : base(val , 0.001, Units) { }
 
-		public static Watt operator *(Volt volt, Ampere ampere)
-        {
-            return SIBase<Watt>.Create(volt.Val * ampere.Value());
-        }
+		public override string UnitString { get { return "Nl"; } }
 
-        public static Ampere operator /(Watt watt, Volt volt)
-        {
-            return SIBase<Ampere>.Create(watt.Value() / volt.Value());
-        }
-    }
+		public static NormLiterPerSecond operator /(NormLiter nl, Second s)
+		{
+			return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value());
+		}
+	}
 
-	public class VolumePerMeter : SIBase<VolumePerMeter>
+	/// <summary>
+	/// 
+	/// </summary>
+	public class NormLiterPerSecond : SIBase<NormLiterPerSecond>
 	{
-		private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 };
-		private VolumePerMeter(double val) : base(val, Units) { }
+		private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 };
 
-		public override string UnitString { get { return "m^3/m"; } }
+		//[DebuggerHidden]
+		private NormLiterPerSecond(double val) : base(val, 0.001, Units) { }
 
-		public static VolumePerMeterMass operator /(VolumePerMeter vpm, Kilogram kg)
+		public override string UnitString { get { return "Nl/s"; } }
+
+		public static NormLiter operator *(NormLiterPerSecond nips, Second s)
 		{
-			return SIBase<VolumePerMeterMass>.Create(vpm.Val / kg.Value());
+			return SIBase<NormLiter>.Create(nips.Val * s.Value());
 		}
 
-		public static VolumePerMeterVolume operator /(VolumePerMeter vpm, CubicMeter vol)
+		public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val)
 		{
-			return SIBase<VolumePerMeterVolume>.Create(vpm.Val / vol.Value());
+			return Create(nps.Val  * val);
 		}
 
+		public static NormLiterPerSecond operator /(NormLiterPerSecond nps, double val)
+		{
+			return Create(nps.Val / val);
+		}
 	}
 
-	public class VolumePerMeterMass : SIBase<VolumePerMeterMass>
+	/// <summary>
+	/// SI Class for Kilogram per Second [kg].
+	/// </summary>
+	public class KilogramPerSecond : SIBase<KilogramPerSecond>
 	{
-		private static readonly int[] Units = { -1, 2, 0, 0, 0, 0, 0 };
+		private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 };
 
-		private VolumePerMeterMass(double val) : base (val, Units) { }
+		[DebuggerHidden]
+		private KilogramPerSecond(double value) : base(value, Units) { }
 
-		public override string UnitString { get { return "m^3/kgm"; } }
+		[DebuggerHidden]
+		public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second)
+		{
+			return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value());
+		}
 	}
 
-	public class VolumePerMeterVolume : SIBase<VolumePerMeterVolume>
+	/// <summary>
+	/// SI Class for Square meter [m^2].
+	/// </summary>
+	public class SquareMeter : SIBase<SquareMeter>
 	{
-		private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 };
-
-		private VolumePerMeterVolume(double val) : base (val, Units) { }
+		private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 };
 
-		public override string UnitString { get { return "m^3/kgm^3"; } }
+		[DebuggerHidden]
+		private SquareMeter(double value) : base(value, Units) { }
 	}
 
-	public class KilogramPerMeterCubicMeter : SIBase<KilogramPerMeterCubicMeter>
+	/// <summary>
+	/// SI Class for cubic meter [m^3].
+	/// </summary>
+	public class CubicMeter : SIBase<CubicMeter>
 	{
-		private static readonly int[] Units = { 1, -4, 0, 0, 0, 0, 0 };
+		private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 };
 
-		private KilogramPerMeterCubicMeter(double val) : base(val, Units) { }
-
-		public override string UnitString { get { return "kg/(m m^3)"; } }
+		[DebuggerHidden]
+		private CubicMeter(double value)
+			: base(value, Units) { }
 	}
 
-
-	public class KilogramPerMeterMass : SIBase<KilogramPerMeterMass>
+	/// <summary>
+	/// SI Class for Kilogram Square Meter [kgm^2].
+	/// </summary>
+	public class KilogramSquareMeter : SIBase<KilogramSquareMeter>
 	{
-		private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 };
+		private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 };
 
-		private KilogramPerMeterMass(double val) : base(val, Units) { }
+		[DebuggerHidden]
+		private KilogramSquareMeter(double value) : base(value, Units) { }
 
-		public override string UnitString { get { return "kg/(m kg)"; } }
+		[DebuggerHidden]
+		public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond)
+		{
+			return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value());
+		}
 	}
 
-	public class SpecificFuelConsumption : SIBase<SpecificFuelConsumption>
+	/// <summary>
+	/// SI Class for Kilogram per Cubic Meter [kg/m^3].
+	/// </summary>
+	public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter>
 	{
-		private static readonly int[] Units = { 0, -2,2, 0, 0, 0, 0 };
+		private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 };
 
-		private SpecificFuelConsumption(double val) : base(val, Units) { }
-	}
+		[DebuggerHidden]
+		private KilogramPerCubicMeter(double value) : base(value, Units) { }
 
-	/// <summary>
-	/// Base Class for all special SI Classes. Not intended to be used directly.
+		public override string UnitString { get { return "kg/m^3"; } }
+
+		[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) { }
+
+		public override string UnitString { get { return "kg/Ws"; } }
+	}
+
+	/// <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) { }
+
+		public override string UnitString { get { return "Ws"; } }
+
+		[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) { }
+
+		public override string UnitString { get { return "W"; } }
+
+		/// <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 override string UnitString { get { return "J"; } }
+
+		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 Joule / kg.
+	/// </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 override string UnitString { get { return "J/kg"; } }
+
+		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) { }
+
+		public override string UnitString { get { return "J/m"; } }
+	}
+
+	/// <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) { }
+
+		public override string UnitString { get { return "Nm"; } }
+
+		[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) { }
+
+		public override string UnitString { get { return "Nms"; } }
+	}
+
+	/// <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 override string UnitString { get { return "V"; } }
+
+		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());
+		}
+	}
+
+	public class VolumePerMeter : SIBase<VolumePerMeter>
+	{
+		private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 };
+		private VolumePerMeter(double val) : base(val, Units) { }
+
+		public override string UnitString { get { return "m^3/m"; } }
+
+		public static VolumePerMeterMass operator /(VolumePerMeter vpm, Kilogram kg)
+		{
+			return SIBase<VolumePerMeterMass>.Create(vpm.Val / kg.Value());
+		}
+
+		public static VolumePerMeterVolume operator /(VolumePerMeter vpm, CubicMeter vol)
+		{
+			return SIBase<VolumePerMeterVolume>.Create(vpm.Val / vol.Value());
+		}
+
+	}
+
+	public class VolumePerMeterMass : SIBase<VolumePerMeterMass>
+	{
+		private static readonly int[] Units = { -1, 2, 0, 0, 0, 0, 0 };
+
+		private VolumePerMeterMass(double val) : base (val, Units) { }
+
+		public override string UnitString { get { return "m^3/kgm"; } }
+	}
+
+	public class VolumePerMeterVolume : SIBase<VolumePerMeterVolume>
+	{
+		private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 };
+
+		private VolumePerMeterVolume(double val) : base (val, Units) { }
+
+		public override string UnitString { get { return "m^3/kgm^3"; } }
+	}
+
+	public class KilogramPerMeterCubicMeter : SIBase<KilogramPerMeterCubicMeter>
+	{
+		private static readonly int[] Units = { 1, -4, 0, 0, 0, 0, 0 };
+
+		private KilogramPerMeterCubicMeter(double val) : base(val, Units) { }
+
+		public override string UnitString { get { return "kg/(m m^3)"; } }
+	}
+
+
+	public class KilogramPerMeterMass : SIBase<KilogramPerMeterMass>
+	{
+		private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 };
+
+		private KilogramPerMeterMass(double val) : base(val, Units) { }
+
+		public override string UnitString { get { return "kg/(m kg)"; } }
+	}
+
+	public class SpecificFuelConsumption : SIBase<SpecificFuelConsumption>
+	{
+		private static readonly int[] Units = { 0, -2,2, 0, 0, 0, 0 };
+
+		private SpecificFuelConsumption(double val) : base(val, Units) { }
+	}
+
+	/// <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) { }
+	{
+		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} [{UnitString}]")]
+	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);
+		}
 
-		protected SIBase(double value, double unitFactor, int[] units) : base(value, unitFactor, units) { }
+		[DebuggerHidden]
+		public static SI operator *(SI si1, double d)
+		{
+			return new SI(si1.Val * d, si1);
+		}
 
-		[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} [{UnitString}]")]
-    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;
+		[DebuggerHidden]
+		public static SI operator *(double d, SI si1)
+		{
+			return new SI(d * si1.Val, si1);
+		}
 
-		private double UnitFactor;
+		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.UnitString, si2.UnitString), ex);
+			}
 
-		/// <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;
+			var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1));
 
-            if (double.IsNaN(Val)) {
-                throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
-            }
+			return new SI(result, unitArray);
+		}
 
-            if (double.IsInfinity(Val)) {
-                throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString());
-            }
-        }
+		[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.UnitString), new DivideByZeroException());
+			}
 
-		protected SI(double val, int[] units) : this(val, 1, units) { }
+			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.UnitString),
+					new DivideByZeroException());
+			}
 
-		public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits()) { }
+			return new SI(d / si1.AsBasicUnit, si1._units.Select(u => -u).ToArray());
+		}
 
-        /// <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);
-        }
+		[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;
+		}
 
-		protected double AsBasicUnit
+		[DebuggerHidden]
+		public static bool operator <(SI si1, double d)
 		{
-			get { return Val * UnitFactor; }
+			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;
+		}
 
-        /// <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.UnitString, si2.UnitString), 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.UnitString), 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.UnitString),
-                    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 static string GetUnitString(int[] units = null)
-        {
-            if (units == null) {
+		#endregion
+
+		#region ToString
+
+		/// <summary>
+		///     Returns the Unit Part of the SI Unit Expression.
+		/// </summary>
+		public static string GetUnitString(int[] units = null)
+		{
+			if (units == null) {
 				return "";
 			}
-            return Unit.GetUnitString(units);
-        }
+			return Unit.GetUnitString(units);
+		}
 
-        public override string ToString()
-        {
-            return ToString(null);
-        }
+		public override string ToString()
+		{
+			return ToString(null);
+		}
 
 		public virtual string UnitString
 		{
 			get { return GetUnitString(_units); }
 		}
 
-        private string ToString(string format)
-        {
-            if (string.IsNullOrEmpty(format)) {
-                format = "F4";
-            }
-
-            return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, UnitString);
-        }
-
-        #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)) {
+		private string ToString(string format)
+		{
+			if (string.IsNullOrEmpty(format)) {
+				format = "F4";
+			}
+
+			return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, UnitString);
+		}
+
+		#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) + " [" +
-                       UnitString + "]";
-            }
-
-            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();
-            }
-        }
-    }
+				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) + " [" +
+					   UnitString + "]";
+			}
+
+			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/VectoCommon.csproj b/VectoCommon/VectoCommon/VectoCommon.csproj
index 863d09c76a..ada7b6397c 100644
--- a/VectoCommon/VectoCommon/VectoCommon.csproj
+++ b/VectoCommon/VectoCommon/VectoCommon.csproj
@@ -44,6 +44,8 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Hashing\IVectoHash.cs" />
+    <Compile Include="Hashing\VectoComponents.cs" />
     <Compile Include="InputData\DataSourceType.cs" />
     <Compile Include="InputData\TableData.cs">
       <SubType>Component</SubType>
diff --git a/VectoCommon/VectoHashing/VectoHash.cs b/VectoCommon/VectoHashing/VectoHash.cs
index 8b42dd4bd2..60b5ae0156 100644
--- a/VectoCommon/VectoHashing/VectoHash.cs
+++ b/VectoCommon/VectoHashing/VectoHash.cs
@@ -37,6 +37,7 @@ using System.Linq;
 using System.Security.Cryptography.X509Certificates;
 using System.Xml;
 using System.Xml.Linq;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCommon.Resources;
 using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoHashing.Impl;
diff --git a/VectoCommon/VectoHashing/VectoHashing.csproj b/VectoCommon/VectoHashing/VectoHashing.csproj
index ef6a15de8a..8d496c1df7 100644
--- a/VectoCommon/VectoHashing/VectoHashing.csproj
+++ b/VectoCommon/VectoHashing/VectoHashing.csproj
@@ -44,9 +44,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Impl\XmlDsigVectoTransform.cs" />
-    <Compile Include="IVectoHash.cs" />
     <Compile Include="Util\XmlDocumentExtensions.cs" />
-    <Compile Include="VectoComponents.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="VectoHash.cs" />
     <Compile Include="Impl\XmlHashProvider.cs" />
@@ -59,12 +57,6 @@
   <ItemGroup>
     <EmbeddedResource Include="Resources\XSLT\SortInputData.xslt" />
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\VectoCommon\VectoCommon.csproj">
-      <Project>{79A066AD-69A9-4223-90F6-6ED5D2D084F4}</Project>
-      <Name>VectoCommon</Name>
-    </ProjectReference>
-  </ItemGroup>
   <ItemGroup>
     <None Include="Properties\Version.tt">
       <Generator>TextTemplatingFileGenerator</Generator>
@@ -74,6 +66,12 @@
   <ItemGroup>
     <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\VectoCommon\VectoCommon.csproj">
+      <Project>{79A066AD-69A9-4223-90F6-6ED5D2D084F4}</Project>
+      <Name>VectoCommon</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/VectoCommon/VectoHashingTest/VectoHashTest.cs b/VectoCommon/VectoHashingTest/VectoHashTest.cs
index 163bff91ce..a627545a37 100644
--- a/VectoCommon/VectoHashingTest/VectoHashTest.cs
+++ b/VectoCommon/VectoHashingTest/VectoHashTest.cs
@@ -38,6 +38,7 @@ using System.Xml.Linq;
 using System.Xml.Schema;
 using System.Xml.XPath;
 using NUnit.Framework;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCore.Utils;
 using TUGraz.VectoHashing;
 using VectoHashingTest.Utils;
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs
index 2a028c292f..3ad0ed8663 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs
@@ -124,7 +124,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 		public string Date { get; private set; }
 		public CertificationMethod CertificationMethod { get; private set; }
 		public string CertificationNumber { get; private set; }
-		public string DigestValue { get; private set; }
+		public DigestData DigestValue { get; private set; }
 
 		IVehicleDeclarationInputData IDeclarationJobInputData.Vehicle
 		{
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs
index d3971d189c..a6af4ce772 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs
@@ -241,9 +241,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 			get { return "N/A"; }
 		}
 
-		public string DigestValue
+		public DigestData DigestValue
 		{
-			get { return "N/A"; }
+			get { return null; }
 		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs
index e541d37d53..ae7c0ba2f0 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs
@@ -500,9 +500,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 			get { return "N/A"; }
 		}
 
-		public string DigestValue
+		public DigestData DigestValue
 		{
-			get { return ""; }
+			get { return null; }
 		}
 	}
 }
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs
index 9f5a5f9005..21b708c4f9 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs
@@ -37,6 +37,7 @@ using System.Linq;
 using System.Xml;
 using System.Xml.Linq;
 using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Hashing;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Resources;
@@ -47,6 +48,7 @@ using TUGraz.VectoCore.InputData.Impl;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Utils;
+using TUGraz.VectoHashing;
 
 namespace TUGraz.VectoCore.InputData.FileIO.JSON
 {
@@ -98,9 +100,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 					throw new VectoException("Failed to read file for {0}: {1}", e, tableType, filename);
 				}
 			}
+
 			if (required) {
 				throw new VectoException("Invalid filename for {0}: {1}", tableType, filename);
 			}
+
 			return null;
 		}
 
@@ -113,10 +117,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public static JObject GetDummyJSONStructure()
 		{
-			return JObject.FromObject(new Dictionary<string, object>() {
-				{ JsonKeys.JsonHeader, new object() },
-				{ JsonKeys.JsonBody, new object() }
-			});
+			return JObject.FromObject(
+				new Dictionary<string, object>() {
+					{ JsonKeys.JsonHeader, new object() },
+					{ JsonKeys.JsonBody, new object() }
+				});
 		}
 	}
 
@@ -175,11 +180,14 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 					Path.Combine(BasePath, vehicleFile), this);
 			} catch (Exception e) {
 				if (!TolerateMissing) {
-					throw new VectoException("JobFile: Failed to read Vehicle file '{0}': {1}", e,
+					throw new VectoException(
+						"JobFile: Failed to read Vehicle file '{0}': {1}", e,
 						Body[JsonKeys.Vehicle_VehicleFile],
 						e.Message);
 				}
-				return new JSONVehicleDataV7(GetDummyJSONStructure(),
+
+				return new JSONVehicleDataV7(
+					GetDummyJSONStructure(),
 					Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_VehicleFile).Value<string>()) +
 					MissingFileSuffix, this);
 			}
@@ -193,11 +201,14 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 				return JSONInputDataFactory.ReadGearbox(Path.Combine(BasePath, gearboxFile));
 			} catch (Exception e) {
 				if (!TolerateMissing) {
-					throw new VectoException("JobFile: Failed to read Gearbox file '{0}': {1}", e,
+					throw new VectoException(
+						"JobFile: Failed to read Gearbox file '{0}': {1}", e,
 						Body[JsonKeys.Vehicle_GearboxFile],
 						e.Message);
 				}
-				return new JSONGearboxDataV6(GetDummyJSONStructure(),
+
+				return new JSONGearboxDataV6(
+					GetDummyJSONStructure(),
 					Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_GearboxFile).Value<string>()) +
 					MissingFileSuffix);
 			}
@@ -210,13 +221,15 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 					Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>()));
 			} catch (Exception e) {
 				if (!TolerateMissing) {
-					throw new VectoException("JobFile: Failed to read Engine file '{0}': {1}", e,
+					throw new VectoException(
+						"JobFile: Failed to read Engine file '{0}': {1}", e,
 						Body[JsonKeys.Vehicle_EngineFile],
 						e.Message);
 				}
 
 				return
-					new JSONEngineDataV3(GetDummyJSONStructure(),
+					new JSONEngineDataV3(
+						GetDummyJSONStructure(),
 						Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>()) +
 						MissingFileSuffix);
 			}
@@ -246,26 +259,28 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public virtual IVehicleEngineeringInputData VehicleInputData
 		{
-			[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
+			[System.Diagnostics.CodeAnalysis.SuppressMessage(
+				"Microsoft.Design",
 				"CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
-			get
-			{
+			get {
 				if (VehicleData == null) {
 					throw new InvalidFileFormatException("VehicleData not found ");
 				}
+
 				return VehicleData;
 			}
 		}
 
 		public virtual IEngineEngineeringInputData EngineOnly
 		{
-			[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
+			[System.Diagnostics.CodeAnalysis.SuppressMessage(
+				"Microsoft.Design",
 				"CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
-			get
-			{
+			get {
 				if (Engine == null) {
 					throw new InvalidFileFormatException("EngineData not found");
 				}
+
 				return Engine;
 			}
 		}
@@ -286,14 +301,15 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public virtual IList<ICycleData> Cycles
 		{
-			[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
+			[System.Diagnostics.CodeAnalysis.SuppressMessage(
+				"Microsoft.Design",
 				"CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
-			get
-			{
+			get {
 				var retVal = new List<ICycleData>();
 				if (Body[JsonKeys.Job_Cycles] == null) {
 					return retVal;
 				}
+
 				foreach (var cycle in Body.GetEx(JsonKeys.Job_Cycles)) {
 					//.Select(cycle => 
 					var cycleFile = Path.Combine(BasePath, cycle.Value<string>());
@@ -304,21 +320,26 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 						try {
 							var resourceName = DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." +
 												cycle.Value<string>() + Constants.FileExtensions.CycleFile;
-							cycleData = VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceName),
+							cycleData = VectoCSVFile.ReadStream(
+								RessourceHelper.ReadStream(resourceName),
 								source: resourceName);
 						} catch (Exception e) {
 							Log.Debug("Driving Cycle could not be read: " + cycleFile);
 							if (!TolerateMissing) {
 								throw new VectoException("Driving Cycle could not be read: " + cycleFile, e);
 							}
+
 							cycleData = new TableData(cycleFile + MissingFileSuffix, DataSourceType.Missing);
 						}
 					}
-					retVal.Add(new CycleInputData() {
-						Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()),
-						CycleData = cycleData
-					});
+
+					retVal.Add(
+						new CycleInputData() {
+							Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()),
+							CycleData = cycleData
+						});
 				}
+
 				return retVal;
 			}
 		}
@@ -339,8 +360,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public virtual ILookaheadCoastingInputData Lookahead
 		{
-			get
-			{
+			get {
 				if (Body[JsonKeys.DriverData_LookaheadCoasting] == null) {
 					return null;
 				}
@@ -362,6 +382,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 					: DeclarationData.Driver.LookAhead.MinimumSpeed;
 				return new LookAheadCoastingInputData() {
 					Enabled = lac.GetEx<bool>(JsonKeys.DriverData_Lookahead_Enabled),
+
 					//Deceleration = lac.GetEx<double>(JsonKeys.DriverData_Lookahead_Deceleration).SI<MeterPerSquareSecond>(),
 					MinSpeed = minSpeed,
 					LookaheadDistanceFactor = distanceScalingFactor,
@@ -379,8 +400,10 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 				string.IsNullOrWhiteSpace(lac["Df_velocityDropLookup"].Value<string>())) {
 				return null;
 			}
+
 			try {
-				return ReadTableData(lac.GetEx<string>("Df_velocityDropLookup"),
+				return ReadTableData(
+					lac.GetEx<string>("Df_velocityDropLookup"),
 					"Lookahead Coasting Decisionfactor - Velocity drop");
 			} catch (Exception) {
 				if (TolerateMissing) {
@@ -390,6 +413,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 							DataSourceType.Missing);
 				}
 			}
+
 			return null;
 		}
 
@@ -399,8 +423,10 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 				string.IsNullOrWhiteSpace(lac["DF_targetSpeedLookup"].Value<string>())) {
 				return null;
 			}
+
 			try {
-				return ReadTableData(lac.GetEx<string>("DF_targetSpeedLookup"),
+				return ReadTableData(
+					lac.GetEx<string>("DF_targetSpeedLookup"),
 					"Lookahead Coasting Decisionfactor - Target speed");
 			} catch (Exception) {
 				if (TolerateMissing) {
@@ -410,21 +436,21 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 							DataSourceType.Missing);
 				}
 			}
+
 			return null;
 		}
 
 		public virtual IOverSpeedEcoRollEngineeringInputData OverSpeedEcoRoll
 		{
-			get
-			{
+			get {
 				var overspeed = Body.GetEx(JsonKeys.DriverData_OverspeedEcoRoll);
 				return new OverSpeedEcoRollInputData() {
 					Mode = DriverData.ParseDriverMode(
 						overspeed.GetEx<string>(JsonKeys.DriverData_OverspeedEcoRoll_Mode)),
 					MinSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_MinSpeed)
-						.KMPHtoMeterPerSecond(),
+										.KMPHtoMeterPerSecond(),
 					OverSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_OverSpeed)
-						.KMPHtoMeterPerSecond(),
+										.KMPHtoMeterPerSecond(),
 					UnderSpeed =
 						overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_UnderSpeed).KMPHtoMeterPerSecond()
 				};
@@ -433,15 +459,17 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public virtual TableData AccelerationCurve
 		{
-			[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design",
+			[System.Diagnostics.CodeAnalysis.SuppressMessage(
+				"Microsoft.Design",
 				"CA1065:DoNotRaiseExceptionsInUnexpectedLocations")]
-			get
-			{
+			get {
 				var acceleration = Body[JsonKeys.DriverData_AccelerationCurve];
 				if (acceleration == null || EmptyOrInvalidFileName(acceleration.Value<string>())) {
 					return null;
+
 					//					throw new VectoException("AccelerationCurve (VACC) required");
 				}
+
 				try {
 					return ReadTableData(acceleration.Value<string>(), "DriverAccelerationCurve");
 				} catch (VectoException e) {
@@ -455,7 +483,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 						if (!TolerateMissing) {
 							throw new VectoException("Failed to read Driver Acceleration Curve: " + e.Message, e);
 						}
-						return new TableData(Path.Combine(BasePath, acceleration.Value<string>()) + MissingFileSuffix,
+
+						return new TableData(
+							Path.Combine(BasePath, acceleration.Value<string>()) + MissingFileSuffix,
 							DataSourceType.Missing);
 					}
 				}
@@ -512,9 +542,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 					continue;
 				}
 
-				AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData,
+				AuxiliaryFileHelper.FillAuxiliaryDataInputData(
+					auxData,
 					Path.Combine(BasePath, auxFile.Value<string>()));
 			}
+
 			return retVal;
 		}
 
@@ -535,6 +567,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 					newTech = tech;
 					break;
 			}
+
 			return newTech;
 		}
 
@@ -544,11 +577,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public AuxiliaryModel AuxiliaryAssembly
 		{
-			get
-			{
-				return AuxiliaryModelHelper.Parse(Body["AuxiliaryAssembly"] == null
-					? ""
-					: Body["AuxiliaryAssembly"].ToString());
+			get {
+				return AuxiliaryModelHelper.Parse(
+					Body["AuxiliaryAssembly"] == null
+						? ""
+						: Body["AuxiliaryAssembly"].ToString());
 			}
 		}
 
@@ -559,8 +592,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 
 		public string AdvancedAuxiliaryFilePath
 		{
-			get
-			{
+			get {
 				return Body["AdvancedAuxiliaryFilePath"] != null
 					? Path.Combine(Path.GetFullPath(BasePath), Body["AdvancedAuxiliaryFilePath"].Value<string>())
 					: "";
@@ -579,11 +611,12 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 		{
 			var retVal = new List<AuxiliaryDataInputData>();
 			if (Body["Padd"] != null) {
-				retVal.Add(new AuxiliaryDataInputData() {
-					ID = "ConstantAux",
-					AuxiliaryType = AuxiliaryDemandType.Constant,
-					ConstantPowerDemand = Body.GetEx<double>("Padd").SI<Watt>()
-				});
+				retVal.Add(
+					new AuxiliaryDataInputData() {
+						ID = "ConstantAux",
+						AuxiliaryType = AuxiliaryDemandType.Constant,
+						ConstantPowerDemand = Body.GetEx<double>("Padd").SI<Watt>()
+					});
 			}
 			foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) {
 				try {
@@ -608,9 +641,12 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 				if (auxFile == null || EmptyOrInvalidFileName(auxFile.Value<string>())) {
 					continue;
 				}
-				AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData,
+
+				AuxiliaryFileHelper.FillAuxiliaryDataInputData(
+					auxData,
 					Path.Combine(BasePath, auxFile.Value<string>()));
 			}
+
 			return retVal;
 		}
 	}
@@ -622,44 +658,64 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 			: base(data, filename, tolerateMissing) { }
 	}
 
-	public class JSONVTPInputDataV4 : JSONFile, IVTPEngineeringInputDataProvider, IVTPEngineeringJobInputData, IVTPDeclarationInputDataProvider
+	public class JSONVTPInputDataV4 : JSONFile, IVTPEngineeringInputDataProvider, IVTPEngineeringJobInputData,
+		IVTPDeclarationInputDataProvider, IManufacturerReport
 	{
-		public JSONVTPInputDataV4(JObject data, string filename, bool tolerateMissing = false) : base(data, filename,
-			tolerateMissing) { }
+		private IDictionary<VectoComponents, IList<string>> _componentDigests = null;
+		private DigestData _jobDigest = null;
+
+		public JSONVTPInputDataV4(JObject data, string filename, bool tolerateMissing = false) : base(
+			data, filename, tolerateMissing)
+		{
+			VectoJobHash = VectoHashing.VectoHash.Load(
+				Path.Combine(Path.GetFullPath(BasePath), Body["DeclarationVehicle"].Value<string>()));
+			VectoManufacturerReportHash = VectoHashing.VectoHash.Load(
+				Path.Combine(Path.GetFullPath(BasePath), Body["ManufacturerRecord"].Value<string>()));
+		}
 
 		public IVTPEngineeringJobInputData JobInputData
 		{
 			get { return this; }
 		}
 
+		public IManufacturerReport ManufacturerReportInputData
+		{
+			get { return this; }
+		}
+
 		public IVehicleDeclarationInputData Vehicle
 		{
-			get
-			{
+			get {
 				return new XMLDeclarationInputDataProvider(
 					Path.Combine(Path.GetFullPath(BasePath), Body["DeclarationVehicle"].Value<string>()),
 					true).JobInputData.Vehicle;
 			}
 		}
 
+		public IVectoHash VectoJobHash { get; }
+
+		public IVectoHash VectoManufacturerReportHash { get; }
+
 		public IList<ICycleData> Cycles
 		{
-			get
-			{
+			get {
 				var retVal = new List<ICycleData>();
 				if (Body[JsonKeys.Job_Cycles] == null) {
 					return retVal;
 				}
+
 				foreach (var cycle in Body.GetEx(JsonKeys.Job_Cycles)) {
 					var cycleFile = Path.Combine(BasePath, cycle.Value<string>());
 					if (File.Exists(cycleFile)) {
 						var cycleData = VectoCSVFile.Read(cycleFile);
-						retVal.Add(new CycleInputData() {
-							Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()),
-							CycleData = cycleData
-						});
+						retVal.Add(
+							new CycleInputData() {
+								Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()),
+								CycleData = cycleData
+							});
 					}
 				}
+
 				return retVal;
 			}
 		}
@@ -682,5 +738,60 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 		}
 
 		#endregion
+
+		#region Implementation of IManufacturerReport
+
+		IDictionary<VectoComponents, IList<string>> IManufacturerReport.ComponentDigests
+		{
+			get {
+				if (_componentDigests == null) {
+					ReadManufacturerReport();
+				}
+				return _componentDigests;
+			}
+		}
+
+		public DigestData JobDigest
+		{
+			get {
+				if (_jobDigest == null) {
+					ReadManufacturerReport();
+				}
+				return _jobDigest;
+			}
+		}
+
+		#endregion
+
+		private void ReadManufacturerReport()
+		{
+			var xmlDoc = new XmlDocument();
+			xmlDoc.Load(Path.Combine(Path.GetFullPath(BasePath), Body["ManufacturerRecord"].Value<string>()));
+			var components = XMLManufacturerReportReader.GetContainingComponents(xmlDoc).GroupBy(s => s)
+														.Select(g => new { Entry = g.Key, Count = g.Count() });
+			_componentDigests = new Dictionary<VectoComponents, IList<string>>();
+
+			try {
+				foreach (var component in components) {
+					if (component.Entry == VectoComponents.Vehicle) {
+						continue;
+					}
+
+					for (var i = 0; i < component.Count; i++) {
+						if (!_componentDigests.ContainsKey(component.Entry)) {
+							_componentDigests[component.Entry] = new List<string>();
+						}
+						_componentDigests[component.Entry].Add(
+							XMLManufacturerReportReader.GetComponentDataDigestValue(xmlDoc, component.Entry, i));
+					}
+				}
+			} catch (Exception) { }
+
+			try {
+				_jobDigest = new DigestData(xmlDoc.SelectSingleNode("//*[local-name()='InputDataSignature']"));
+			} catch (Exception) {
+				_jobDigest = new DigestData("", new string[] {},"","" );
+			}
+		}
 	}
-}
\ No newline at end of file
+}
diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs
index 0f44e5907d..0382ce6c7e 100644
--- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs
@@ -486,9 +486,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON
 			get { return "N.A."; }
 		}
 
-		public string DigestValue
+		public DigestData DigestValue
 		{
-			get { return ""; }
+			get { return null; }
 		}
 	}
 }
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs
index 09dd2e462e..2b292d2737 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs
@@ -112,17 +112,16 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 			get { return GetElementValue(XMLNames.Component_CertificationNumber); }
 		}
 
-		public virtual string DigestValue
+		public virtual DigestData DigestValue
 		{
-			get { return GetElementValue("..//*[local-name()='DigestValue']"); }
+			get { return new DigestData(Navigator.SelectSingleNode(XBasePath + "/..", Manager)); }
 		}
 
 
 		protected bool ElementExists(string relativePath)
 		{
 			var path = Helper.Query(XBasePath, relativePath.Any() ? relativePath : null);
-			//new StringBuilder(XBasePath + (relativePath.Any() ? "/" + relativePath : ""));
-
+			
 			var node = Navigator.SelectSingleNode(path, Manager);
 			return node != null;
 		}
@@ -138,6 +137,19 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 			return node.InnerXml;
 		}
 
+		protected string[] GetElementValues(string querypath)
+		{
+			var path = Helper.Query(XBasePath, querypath.Any() ? querypath : null);
+
+			var nodes = Navigator.Select(path, Manager);
+			var retVal = new List<string>();
+			while (nodes.MoveNext()) {
+				retVal.Add(nodes.Current.InnerXml);
+			}
+
+			return retVal.ToArray();
+		}
+
 		protected double GetDoubleElementValue(string relativePath)
 		{
 			return GetElementValue(relativePath).ToDouble();
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs
index 63ad01d6dd..f583290f3e 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs
@@ -49,19 +49,19 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 		private readonly XMLDeclarationJobInputDataProvider _xmlJobData;
 
 
-        public XMLDeclarationInputDataProvider(string filename, bool verifyXml) :
-            this(XmlReader.Create(filename), filename, verifyXml)
-        {
-        }
+		public XMLDeclarationInputDataProvider(string filename, bool verifyXml) :
+			this(XmlReader.Create(filename), filename, verifyXml)
+		{
+		}
 
-        public XMLDeclarationInputDataProvider(XmlReader inputData, bool verifyXml) : this(inputData, "", verifyXml)
-        {
-            
-        }
+		public XMLDeclarationInputDataProvider(XmlReader inputData, bool verifyXml) : this(inputData, "", verifyXml)
+		{
+			
+		}
 
-        protected XMLDeclarationInputDataProvider(XmlReader inputData, string source, bool verifyXml)
-        {
-            Source = source;
+		protected XMLDeclarationInputDataProvider(XmlReader inputData, string source, bool verifyXml)
+		{
+			Source = source;
 			var xmldoc = new XmlDocument();
 			xmldoc.Load(inputData);
 
@@ -72,13 +72,13 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 			var h = VectoHash.Load(xmldoc);
 			XMLHash = h.ComputeXmlHash();
 			Document = new XPathDocument(new XmlNodeReader(xmldoc));
-            
+			
 			_xmlJobData = new XMLDeclarationJobInputDataProvider(this);
 		}
 
-        public string Source { get; protected set; }
+		public string Source { get; protected set; }
 
-        private static void ValidationCallBack(XmlSeverityType severity, ValidationEvent evt)
+		private static void ValidationCallBack(XmlSeverityType severity, ValidationEvent evt)
 		{
 			if (severity == XmlSeverityType.Error) {
 				var args = evt.ValidationEventArgs;
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs
index c4a8d1c726..842f2050a7 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs
@@ -139,7 +139,6 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 					var rollResistance = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_RRCDeclared), Manager);
 					var tyreTestLoad = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_FzISO), Manager);
 					var certirficationNumber = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.Component_CertificationNumber), Manager);
-					var digestValue = tyre.SelectSingleNode(Helper.Query("..//*[local-name()='DigestValue']"), Manager);
 					retVal[axleNumber - 1] = new AxleInputData {
 						AxleType = axleType == null ? AxleType.VehicleNonDriven : axleType.Value.ParseEnum<AxleType>(),
 						TwinTyres = twinTyres != null && XmlConvert.ToBoolean(twinTyres.Value),
@@ -150,7 +149,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
 							Dimension = dimension == null ? null : dimension.Value,
 							CertificationNumber = certirficationNumber == null ? null : certirficationNumber.Value,
 							CertificationMethod = CertificationMethod.Measured,
-							DigestValue = digestValue == null ? "" : digestValue.Value
+							DigestValue = new DigestData(tyre.SelectSingleNode(Helper.Query("..//*[local-name()='DigestValue']/.."), Manager))
 						}
 					};
 				}
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs
new file mode 100644
index 0000000000..82d1b095e6
--- /dev/null
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using TUGraz.VectoCommon.Hashing;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Resources;
+using TUGraz.VectoCommon.Utils;
+
+namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration
+{
+	public class XMLManufacturerReportReader
+	{
+		public static IList<VectoComponents> GetContainingComponents(XmlDocument xmlDocument)
+		{
+			var retVal = new List<VectoComponents>();
+			foreach (var component in EnumHelper.GetValues<VectoComponents>()) {
+				var nodes = xmlDocument.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']/*[local-name()='Model']",
+																XMLNames.VectoManufacturerReport, component.XMLElementName()));
+				var count = nodes == null ? 0 : nodes.Count;
+				for (var i = 0; i < count; i++) {
+					retVal.Add(component);
+				}
+			}
+			foreach (var component in new[] { XMLNames.AxleWheels_Axles_Axle }) {
+				var nodes = xmlDocument.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']",
+																XMLNames.VectoManufacturerReport, component));
+				var count = nodes == null ? 0 : nodes.Count;
+				for (var i = 0; i < count; i++) {
+					retVal.Add(VectoComponents.Tyre);
+				}
+			}
+			return retVal;
+		}
+
+		public static string GetComponentDataDigestValue(XmlDocument xmlDocument, VectoComponents component, int i)
+		{
+			var node = GetNodes(xmlDocument, component, i);
+
+			return ReadElementValue(node, XMLNames.DI_Signature_Reference_DigestValue);
+		}
+
+		public static XmlNode GetNodes(XmlDocument xmlDocument, VectoComponents component, int index)
+		{
+			var nodes = xmlDocument.SelectNodes(GetComponentQueryString(component == VectoComponents.Tyre ? "Axle" : component.XMLElementName()));
+			if (nodes == null || nodes.Count == 0) {
+				throw new Exception(string.Format("Component {0} not found", component));
+			}
+			if (index >= nodes.Count) {
+				throw new Exception(string.Format("index exceeds number of components found! index: {0}, #components: {1}", index,
+												nodes.Count));
+			}
+			return nodes[index];
+		}
+
+		static string GetComponentQueryString(string component = null)
+		{
+			if (component == null) {
+				return "(//*[@id])[1]";
+			}
+			return string.Format("//*[local-name()='{0}']", component);
+		}
+
+		static string ReadElementValue(XmlNode xmlNode, string elementName)
+		{
+			var node = xmlNode.SelectSingleNode(string.Format("./*[local-name()='{0}']", elementName));
+			if (node == null) {
+				return null;
+			}
+			return node.InnerText;
+		}
+	}
+}
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs
index b4bc0fb6f9..c8060152b6 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs
@@ -89,9 +89,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering
 			get { return GetElementValue(XMLNames.Component_Date); }
 		}
 
-		public override string DigestValue
+		public override DigestData DigestValue
 		{
-			get { return ""; }
+			get { return null; }
 		}
 
 		public override string CertificationNumber
diff --git a/VectoCore/VectoCore/InputData/Impl/InputData.cs b/VectoCore/VectoCore/InputData/Impl/InputData.cs
index 968031b997..24f1862055 100644
--- a/VectoCore/VectoCore/InputData/Impl/InputData.cs
+++ b/VectoCore/VectoCore/InputData/Impl/InputData.cs
@@ -125,7 +125,7 @@ namespace TUGraz.VectoCore.InputData.Impl
 
 		public string CertificationNumber { get; internal set; }
 
-		public string DigestValue { get; internal set; }
+		public DigestData DigestValue { get; internal set; }
 
 		public string Dimension { get; internal set; }
 
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs
index ec5307606e..e48b0122dc 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs
@@ -56,7 +56,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				ModelName = data.Model,
 				Date = data.Date,
 				//CertificationNumber = data.CertificationNumber,
-				DigestValueInput = data.DigestValue,
+				DigestValueInput = data.DigestValue.DigestValue,
 				VehicleCategory = data.VehicleCategory,
 				AxleConfiguration = data.AxleConfiguration,
 				CurbWeight = data.CurbMassChassis,
@@ -76,7 +76,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				Date = data.Date,
 				CertificationMethod = data.CertificationMethod,
 				CertificationNumber = data.CertificationNumber,
-				DigestValueInput = data.DigestValue,
+				DigestValueInput = data.DigestValue.DigestValue,
 			};
 			return retVal;
 		}
@@ -113,7 +113,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				retarder.Date = data.Date;
 				retarder.CertificationMethod = data.CertificationMethod;
 				retarder.CertificationNumber = data.CertificationNumber;
-				retarder.DigestValueInput = data.DigestValue;
+				retarder.DigestValueInput = data.DigestValue.DigestValue;
 
 				return retarder;
 			} catch (Exception e) {
@@ -129,7 +129,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				ModelName = data.Model,
 				Date = data.Date,
 				CertificationNumber = data.CertificationNumber,
-				DigestValueInput = data.DigestValue,
+				DigestValueInput = data.DigestValue.DigestValue,
 				Displacement = data.Displacement,
 				IdleSpeed = data.IdleSpeed,
 				ConsumptionMap = FuelConsumptionMapReader.Create(data.FuelConsumptionMap),
@@ -150,7 +150,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				Date = data.Date,
 				CertificationMethod = data.CertificationMethod,
 				CertificationNumber = data.CertificationNumber,
-				DigestValueInput = data.DigestValue,
+				DigestValueInput = data.DigestValue.DigestValue,
 				Type = data.Type
 			};
 		}
@@ -224,7 +224,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 				Date = data.Date,
 				CertificationMethod = data.CertificationMethod,
 				CertificationNumber = data.CertificationNumber,
-				DigestValueInput = data.DigestValue,
+				DigestValueInput = data.DigestValue.DigestValue,
 				AxleGear = new GearData { Ratio = data.Ratio }
 			};
 		}
@@ -252,7 +252,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 							Date = data.Date,
 							CertificationMethod = data.CertificationMethod,
 							CertificationNumber = data.CertificationNumber,
-							DigestValueInput = data.DigestValue,
+							DigestValueInput = data.DigestValue.DigestValue,
 							Type = type,
 							Angledrive = new TransmissionData { Ratio = data.Ratio }
 						};
diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs
index 0c934c136d..0d051fc854 100644
--- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs
@@ -122,7 +122,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter
 					TyreTestLoad = axleInput.Tyre.TyreTestLoad,
 					Inertia = DeclarationData.Wheels.Lookup(axleInput.Tyre.Dimension.RemoveWhitespace()).Inertia,
 					CertificationNumber = axleInput.Tyre.CertificationNumber,
-					DigestValueInput = axleInput.Tyre.DigestValue,
+					DigestValueInput = axleInput.Tyre.DigestValue.DigestValue,
 				};
 				axleData.Add(axle);
 			}
diff --git a/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs b/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs
index 18879c3ce7..16a67cc062 100644
--- a/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs
@@ -74,9 +74,9 @@ namespace TUGraz.VectoCore.InputData.Reader
 			if (DistanceBasedCycleDataParser.ValidateHeader(cols, false)) {
 				return CycleType.DistanceBased;
 			}
-            if (VTPCycleDataParser.ValidateHeader(cols, false)) {
-                return CycleType.VTP;
-            }
+			if (VTPCycleDataParser.ValidateHeader(cols, false)) {
+				return CycleType.VTP;
+			}
 			throw new VectoException("CycleFile format is unknown.");
 		}
 
@@ -95,10 +95,10 @@ namespace TUGraz.VectoCore.InputData.Reader
 					return new MeasuredSpeedDataParser();
 				case CycleType.PTO:
 					return new PTOCycleDataParser();
-                case CycleType.VTP:
-                    return new VTPCycleDataParser();
+				case CycleType.VTP:
+					return new VTPCycleDataParser();
 
-                default:
+				default:
 					throw new ArgumentOutOfRangeException("Cycle Type", type.ToString());
 			}
 		}
@@ -317,8 +317,8 @@ namespace TUGraz.VectoCore.InputData.Reader
 			public const string RoadGradient = "grad";
 			public const string StoppingTime = "stop";
 			public const string EngineSpeed = "n";
-            public const string EngineSpeedSuffix = "n_eng";
-            public const string FanSpeed = "n_fan";
+			public const string EngineSpeedSuffix = "n_eng";
+			public const string FanSpeed = "n_fan";
 			public const string WheelTorqueLeft = "tq_left";
 			public const string WheelTorqueRight = "tq_right";
 			public const string WheelSpeedLeft = "n_wh_left";
@@ -414,7 +414,7 @@ namespace TUGraz.VectoCore.InputData.Reader
 					VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(),
 					RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
 					StoppingTime = row.ParseDouble(Fields.StoppingTime).SI<Second>(),
-				    AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
+					AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
 					AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
 					Gear = (uint)row.ParseDoubleOrGetDefault(Fields.Gear),
 					AirSpeedRelativeToVehicle =
@@ -467,7 +467,7 @@ namespace TUGraz.VectoCore.InputData.Reader
 						Time = row.ParseDoubleOrGetDefault(Fields.Time, absTime).SI<Second>(),
 						AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
 						AdditionalAuxPowerDemand =
-					        row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
+							row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
 						AuxiliarySupplyPower = row.GetAuxiliaries()
 					};
 
@@ -481,7 +481,7 @@ namespace TUGraz.VectoCore.InputData.Reader
 						if (row.Field<string>(Fields.EnginePower).Equals("<DRAG>")) {
 							entry.Drag = true;
 						} else {
-						    entry.Torque = row.ParseDouble(Fields.EnginePower).SI(Unit.SI.Kilo.Watt).Cast<Watt>() / entry.AngularVelocity;
+							entry.Torque = row.ParseDouble(Fields.EnginePower).SI(Unit.SI.Kilo.Watt).Cast<Watt>() / entry.AngularVelocity;
 						}
 					}
 					absTime += 1;
@@ -542,10 +542,10 @@ namespace TUGraz.VectoCore.InputData.Reader
 
 				var entries = table.Rows.Cast<DataRow>().Select(row => new DrivingCycleData.DrivingCycleEntry {
 					Time = row.ParseDouble(Fields.Time).SI<Second>(),
-				    PWheel = row.ParseDouble(Fields.PWheel).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
+					PWheel = row.ParseDouble(Fields.PWheel).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
 					Gear = (uint)row.ParseDouble(Fields.Gear),
 					AngularVelocity = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(),
-				    AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
+					AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
 				}).ToArray();
 
 				return entries;
@@ -585,7 +585,7 @@ namespace TUGraz.VectoCore.InputData.Reader
 					Time = row.ParseDouble(Fields.Time).SI<Second>(),
 					VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(),
 					RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
-				    AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
+					AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
 					AirSpeedRelativeToVehicle =
 						crossWindRequired ? row.ParseDouble(Fields.AirSpeedRelativeToVehicle).KMPHtoMeterPerSecond() : null,
 					WindYawAngle = crossWindRequired ? row.ParseDouble(Fields.WindYawAngle) : 0,
@@ -632,7 +632,7 @@ namespace TUGraz.VectoCore.InputData.Reader
 					Time = row.ParseDouble(Fields.Time).SI<Second>(),
 					VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(),
 					RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0),
-				    AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
+					AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(),
 					AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(),
 					Gear = (uint)row.ParseDouble(Fields.Gear),
 					TorqueConverterActive = table.Columns.Contains(Fields.TorqueConverterActive)
@@ -712,17 +712,17 @@ namespace TUGraz.VectoCore.InputData.Reader
 			}
 		}
 
-        /// <summary>
-        /// Parser for PTO Cycles.
-        /// </summary>
-        // <t>,<v> [km/h],<Pwheel> [kW],<n_eng> [rpm],<n_fan> [rpm], <Padd> [kW]
-        private class VTPCycleDataParser : AbstractCycleDataParser
-        {
-            public override IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table, bool crossWindRequired)
-            {
-                ValidateHeader(table.Columns);
-
-                var entries = table.Rows.Cast<DataRow>().Select(row => {
+		/// <summary>
+		/// Parser for PTO Cycles.
+		/// </summary>
+		// <t>,<v> [km/h],<Pwheel> [kW],<n_eng> [rpm],<n_fan> [rpm], <Padd> [kW]
+		private class VTPCycleDataParser : AbstractCycleDataParser
+		{
+			public override IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table, bool crossWindRequired)
+			{
+				ValidateHeader(table.Columns);
+
+				var entries = table.Rows.Cast<DataRow>().Select(row => {
 					var wheelSpeed =
 						((row.ParseDouble(Fields.WheelSpeedLeft) + row.ParseDouble(Fields.WheelSpeedRight)) / 2).RPMtoRad();
 					var wheelPower = row.ParseDouble(Fields.WheelTorqueLeft).SI<NewtonMeter>() * row.ParseDouble(Fields.WheelSpeedLeft).RPMtoRad() +
@@ -742,23 +742,23 @@ namespace TUGraz.VectoCore.InputData.Reader
 					};
 				}).ToArray();
 
-                return entries;
-            }
+				return entries;
+			}
 
-            public static bool ValidateHeader(DataColumnCollection header, bool throwExceptions = true)
-            {
-                var requiredCols = new[] {
-                    Fields.Time,
-                    Fields.VehicleSpeed,
-                    Fields.EngineSpeedSuffix,
-                    Fields.FanSpeed,
+			public static bool ValidateHeader(DataColumnCollection header, bool throwExceptions = true)
+			{
+				var requiredCols = new[] {
+					Fields.Time,
+					Fields.VehicleSpeed,
+					Fields.EngineSpeedSuffix,
+					Fields.FanSpeed,
 					Fields.WheelSpeedLeft,
 					Fields.WheelSpeedRight,
 					Fields.WheelTorqueLeft,
 					Fields.WheelTorqueRight,
-                };
+				};
 
-                var allowedCols = new[] {
+				var allowedCols = new[] {
 					Fields.Time,
 					Fields.VehicleSpeed,
 					Fields.EngineSpeedSuffix,
@@ -771,14 +771,14 @@ namespace TUGraz.VectoCore.InputData.Reader
 					Fields.FuelConsumption
 				};
 
-                const bool allowAux = true;
+				const bool allowAux = true;
 
-                return CheckColumns(header, allowedCols, requiredCols, throwExceptions, allowAux) &&
-                       CheckComboColumns(header, new[] { Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle }, throwExceptions);
-            }
-        }
+				return CheckColumns(header, allowedCols, requiredCols, throwExceptions, allowAux) &&
+					   CheckComboColumns(header, new[] { Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle }, throwExceptions);
+			}
+		}
 
-    }
+	}
 
 	#endregion
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs
index 90f36b8e84..74bd09ad7e 100644
--- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs
+++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs
@@ -67,6 +67,9 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
 											_segment.VehicleClass),
 			};
 			powertrainConfig.VehicleData.VehicleClass = _segment.VehicleClass;
+			Report.InputDataHash = JobInputData.VectoJobHash;
+			Report.ManufacturerRecord = JobInputData.ManufacturerReportInputData;
+			Report.ManufacturerRecordHash = JobInputData.VectoManufacturerReportHash;
 			Report.InitializeReport(powertrainConfig);
 		}
 
@@ -115,8 +118,8 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
 			}
 
 			// simulate the LongHaul cycle with RefLoad
-			foreach (var mission in _segment.Missions.Where(m => m.MissionType == MissionType.LongHaul)) {
-				foreach (var loading in mission.Loadings.Where(l => l.Key == LoadingType.ReferenceLoad)) {
+			foreach (var mission in _segment.Missions.Where(m => m.MissionType == DeclarationData.VTPMode.SelectedMission)) {
+				foreach (var loading in mission.Loadings.Where(l => l.Key == DeclarationData.VTPMode.SelectedLoading)) {
 					var runData = CreateVectoRunData(_segment, mission, loading.Value);
 					runData.ModFileSuffix = loading.Key.ToString();
 					var cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, CycleType.DistanceBased, "", false);
@@ -127,6 +130,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
 					runData.ExecutionMode = ExecutionMode.Declaration;
 					runData.SimulationType = SimulationType.DistanceCycle;
 					runData.Mission = mission;
+					runData.Loading = loading.Key;
 					yield return runData;
 				}
 			}
@@ -147,6 +151,10 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl
 				runData.Mission = new Mission() {
 					MissionType = MissionType.VerificationTest
 				};
+				runData.VTPData = new VTPData() {
+					CorrectionFactor = 1,
+					FuelNetCalorificValue = 0.SI<JoulePerKilogramm>()
+				};
 				yield return runData;
 			}
 
diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
index f4ec537cbe..111825b14a 100644
--- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
+++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs
@@ -499,5 +499,11 @@ namespace TUGraz.VectoCore.Models.Declaration
 			public const string DefaultPTOActivationCycle =
 				DeclarationDataResourcePrefix + ".MissionCycles.MunicipalUtility_PTO_generic.vptoc";
 		}
+
+		public static class VTPMode
+		{
+			public const MissionType SelectedMission = MissionType.LongHaul;
+			public const LoadingType SelectedLoading = LoadingType.ReferenceLoad;
+		}
 	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
index 1ab02409ad..21cfcb0a6f 100644
--- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs
@@ -104,10 +104,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 
 		public int JobRunId { get; internal set; }
 
-        public AuxFanData FanData { get; internal set; }
+		public AuxFanData FanData { get; internal set; }
 
 		public SimulationType SimulationType { get; set; }
 
+		public VTPData VTPData { get; set; }
+
 		public class AuxData
 		{
 			// ReSharper disable once InconsistentNaming
@@ -205,7 +207,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 			} catch (VectoException) {
 				return new ValidationResult(
 					string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key,
-                        inTorque, angularVelocity.ConvertToRoundsPerMinute()));
+						inTorque, angularVelocity.ConvertToRoundsPerMinute()));
 			}
 			var axlegearTorque = angledriveTorque;
 			try {
@@ -216,7 +218,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 			} catch (VectoException) {
 				return new ValidationResult(
 					string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}",
-                        angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertToRoundsPerMinute()));
+						angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertToRoundsPerMinute()));
 			}
 
 			if (axleGearData != null) {
@@ -228,13 +230,20 @@ namespace TUGraz.VectoCore.Models.Simulation.Data
 						new ValidationResult(
 							string.Format(
 								"Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})",
-                                axlegearTorque, axleAngularVelocity.ConvertToRoundsPerMinute(), gear.Key, velocity));
+								axlegearTorque, axleAngularVelocity.ConvertToRoundsPerMinute(), gear.Key, velocity));
 				}
 			}
 			return null;
 		}
 	}
 
+	public class VTPData
+	{
+		public double CorrectionFactor;
+
+		public JoulePerKilogramm FuelNetCalorificValue;
+	}
+
 	public class AuxFanData
 	{
 		public double[] FanCoefficients;
diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs
index b70bbb0ffb..5226da768a 100644
--- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs
+++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs
@@ -71,7 +71,7 @@ namespace TUGraz.VectoCore.OutputData
 		{
 			public MissionType Mission;
 
-			public Dictionary<LoadingType, TEntry> ModData;
+			public Dictionary<LoadingType, TEntry> ResultEntry;
 		}
 
 
@@ -103,10 +103,10 @@ namespace TUGraz.VectoCore.OutputData
 			if (!Missions.ContainsKey(mission.MissionType)) {
 				Missions[mission.MissionType] = new ResultContainer<T>() {
 					Mission = mission.MissionType,
-					ModData = new Dictionary<LoadingType, T>(),
+					ResultEntry = new Dictionary<LoadingType, T>(),
 				};
 			}
-			Missions[mission.MissionType].ModData[loading] = new T();
+			Missions[mission.MissionType].ResultEntry[loading] = new T();
 			_resultCount++;
 		}
 
@@ -118,12 +118,12 @@ namespace TUGraz.VectoCore.OutputData
 			if (!Missions.ContainsKey(mission.MissionType)) {
 				throw new VectoException("Unknown mission type {0} for generating declaration report", mission.MissionType);
 			}
-			if (!Missions[mission.MissionType].ModData.ContainsKey(loadingType)) {
+			if (!Missions[mission.MissionType].ResultEntry.ContainsKey(loadingType)) {
 				throw new VectoException("Unknown loading type {0} for mission {1}", loadingType, mission.MissionType);
 			}
 			_resultCount--;
 
-			DoAddResult(Missions[mission.MissionType].ModData[loadingType], runData, modData);
+			DoAddResult(Missions[mission.MissionType].ResultEntry[loadingType], runData, modData);
 
 			if (_resultCount == 0) {
 				DoWriteReport();
diff --git a/VectoCore/VectoCore/OutputData/VTPReport.cs b/VectoCore/VectoCore/OutputData/VTPReport.cs
index ef9ba34eeb..ea16cc1ea4 100644
--- a/VectoCore/VectoCore/OutputData/VTPReport.cs
+++ b/VectoCore/VectoCore/OutputData/VTPReport.cs
@@ -29,6 +29,14 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoHashing;
+
 namespace TUGraz.VectoCore.OutputData {
-	public interface IVTPReport : IDeclarationReport { }
+	public interface IVTPReport : IDeclarationReport {
+		IVectoHash InputDataHash { set; }
+
+		IManufacturerReport ManufacturerRecord { set; }
+		IVectoHash ManufacturerRecordHash { set; }
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs
index 068610a218..84f923be97 100644
--- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs
+++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs
@@ -111,7 +111,7 @@ namespace TUGraz.VectoCore.OutputData.XML
 		public void AddResult(
 			DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry)
 		{
-			foreach (var resultEntry in entry.ModData) {
+			foreach (var resultEntry in entry.ResultEntry) {
 				allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success;
 				Results.Add(new XElement(tns + XMLNames.Report_Result_Result,
 					new XAttribute(XMLNames.Report_Result_Status_Attr,
diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs
index a5876323b2..6cddaf27a9 100644
--- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs
+++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs
@@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.OutputData.XML
 			public CubicMeter CargoVolume { get; private set; }
 
 
-			public void SetResultData(VectoRunData runData, IModalDataContainer data)
+			public virtual void SetResultData(VectoRunData runData, IModalDataContainer data)
 			{
 				FuelType = data.FuelData.FuelType;
 				Payload = runData.VehicleData.Loading;
diff --git a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs
index 5e4646beb3..7ee4656e47 100644
--- a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs
+++ b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs
@@ -271,7 +271,7 @@ namespace TUGraz.VectoCore.OutputData.XML
 		public void AddResult(
 			DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry)
 		{
-			foreach (var resultEntry in entry.ModData) {
+			foreach (var resultEntry in entry.ResultEntry) {
 				_allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success;
 				Results.Add(new XElement(tns + XMLNames.Report_Result_Result,
 					new XAttribute(XMLNames.Report_Result_Status_Attr,
diff --git a/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs
index daa46516a3..5d9b0e8461 100644
--- a/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs
+++ b/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs
@@ -1,22 +1,33 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using System.Xml.Linq;
 using TUGraz.IVT.VectoXML.Writer;
+using TUGraz.VectoCommon.Hashing;
+using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Models;
 using TUGraz.VectoCommon.Resources;
 using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.Reader.Impl;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Models.Simulation.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data;
 using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox;
+using TUGraz.VectoCore.Utils;
+using TUGraz.VectoHashing;
 
-namespace TUGraz.VectoCore.OutputData.XML {
-	internal class XMLVTPReport : DeclarationReport<XMLDeclarationReport.ResultEntry>, IVTPReport
+namespace TUGraz.VectoCore.OutputData.XML
+{
+	internal class XMLVTPReport : DeclarationReport<XMLVTPReport.ResultEntry>, IVTPReport
 	{
 		public const string CURRENT_SCHEMA_VERSION = "0.1";
 
 		protected XElement VehiclePart;
+		protected XElement GeneralPart;
+		protected XElement DataIntegrityPart;
+		protected XElement TestConditionsPart;
 
 		protected XElement Results;
 
@@ -27,11 +38,47 @@ namespace TUGraz.VectoCore.OutputData.XML {
 		//protected XNamespace di;
 		//private bool allSuccess = true;
 
+		public class ResultEntry : XMLDeclarationReport.ResultEntry
+		{
+			public Watt AverageFanPower;
+			public Kilogram VTPFcFinalSimulated;
+			public WattSecond VTPWorkPWheelPos;
+			public double VTPFcCorrectionFactor;
+			public JoulePerKilogramm VTPNCV;
+			public Kilogram VTPFcMeasured;
+
+			#region Overrides of ResultEntry
+
+			public override void SetResultData(VectoRunData runData, IModalDataContainer data)
+			{
+				base.SetResultData(runData, data);
+
+				if (runData.SimulationType != SimulationType.VerificationTest) {
+					return;
+				}
+
+				var aux = data.Auxiliaries.FirstOrDefault(x => x.Key == Constants.Auxiliaries.IDs.Fan);
+				AverageFanPower = data.AuxiliaryWork(aux.Value) / data.Duration();
+				VTPWorkPWheelPos = runData.Cycle.Entries.Select(x => x.PWheel > 0 ? x.PWheel : 0.SI<Watt>()).Sum().Cast<Watt>() *
+									data.Duration();
+
+				VTPFcMeasured = runData.Cycle.Entries.Sum(x => x.Fuelconsumption) * data.Duration();
+				VTPFcFinalSimulated = data.TimeIntegral<Kilogram>(ModalResultField.FCFinal);
+				VTPFcCorrectionFactor = runData.VTPData.CorrectionFactor;
+				VTPNCV = runData.VTPData.FuelNetCalorificValue;
+			}
+
+			#endregion
+		}
+
 		public XMLVTPReport(IOutputDataWriter writer)
 		{
 			//di = "http://www.w3.org/2000/09/xmldsig#";
 			tns = "urn:tugraz:ivt:VectoAPI:VTPReport:v" + CURRENT_SCHEMA_VERSION;
 			VehiclePart = new XElement(tns + XMLNames.Component_Vehicle);
+			GeneralPart = new XElement(tns + "General");
+			DataIntegrityPart = new XElement(tns + "DataIntegrityCheck");
+			TestConditionsPart = new XElement(tns + "TestConditions");
 			Results = new XElement(tns + "Results");
 
 			_writer = writer;
@@ -40,37 +87,114 @@ namespace TUGraz.VectoCore.OutputData.XML {
 
 		#region Overrides of DeclarationReport<ResultEntry>
 
-		protected override void DoAddResult(XMLDeclarationReport.ResultEntry entry, VectoRunData runData, IModalDataContainer modData)
+		protected override void DoAddResult(
+			ResultEntry entry, VectoRunData runData, IModalDataContainer modData)
 		{
 			entry.SetResultData(runData, modData);
 		}
 
 		protected internal override void DoWriteReport()
 		{
+			GenerateResults();
+
 			var report = GenerateReport();
 			if (_writer != null) {
 				_writer.WriteReport(ReportType.DeclarationVTPReportXML, report);
 			}
 		}
 
+		private void GenerateResults()
+		{
+			var vtpResult = Missions.FirstOrDefault(x => x.Key == MissionType.VerificationTest).Value.ResultEntry
+									.FirstOrDefault().Value;
+
+			const MissionType selectedMission = DeclarationData.VTPMode.SelectedMission;
+			const LoadingType selectedLoading = DeclarationData.VTPMode.SelectedLoading;
+			var result = Missions.FirstOrDefault(x => x.Key == selectedMission).Value.ResultEntry
+								.FirstOrDefault(x => x.Key == selectedLoading).Value;
+			var vtpFcMeasured = vtpResult.VTPFcMeasured / vtpResult.VTPWorkPWheelPos;
+			var vtpFcMeasuredCorr = vtpResult.VTPFcMeasured / vtpResult.VTPWorkPWheelPos * vtpResult.VTPFcCorrectionFactor;
+			var vtpFcSimulated = vtpResult.VTPFcFinalSimulated / vtpResult.VTPWorkPWheelPos;
+			var cVtp = vtpFcMeasuredCorr / vtpFcSimulated;
+			var declaredCO2 = result.FuelConsumptionTotal / result.Distance / result.Payload;
+			var verifiedCO2 = declaredCO2 * cVtp;
+
+			Results.Add(
+				new XElement(tns + "Status", cVtp < 1.075 ? "Passed" : "Failed"),
+				new XElement(
+					tns + "AverageFanPower",
+					new XAttribute(XMLNames.Report_Results_Unit_Attr, "kW"),
+					vtpResult.AverageFanPower.ConvertToKiloWatt().ToXMLFormat(3)),
+				new XElement(
+					tns + "WorkPosVT", new XAttribute(XMLNames.Report_Results_Unit_Attr, "kWh"),
+					vtpResult.VTPWorkPWheelPos.ConvertToKiloWattHour().ToXMLFormat(3)),
+				new XElement(
+					tns + "TestFuelNCV", new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/kg"),
+					(vtpResult.VTPNCV / 1e6).ToXMLFormat(3)),
+				new XElement(
+					tns + "FuelConsumption",
+					new XElement(
+						tns + "Measured",
+						new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/kWh"),
+						vtpFcMeasured.ConvertToGramPerKiloWattHour().ToXMLFormat(3)
+					),
+					new XElement(
+						tns + "MeasuredCorrected",
+						new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/kWh"),
+						vtpFcMeasuredCorr.ConvertToGramPerKiloWattHour().ToXMLFormat(3)
+					),
+					new XElement(
+						tns + "Simulated",
+						new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/kWh"),
+						vtpFcSimulated.ConvertToGramPerKiloWattHour().ToXMLFormat(3)
+					)
+				),
+				new XElement(
+					tns + "CO2",
+					new XElement(
+						tns + "Mission",
+						string.Format("{0}, {1}", selectedMission.ToXMLFormat(), selectedLoading.ToString())
+					),
+					new XElement(
+						tns + "Declared", new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/t-km"),
+						declaredCO2.ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 1)
+					),
+					new XElement(
+						tns + "Verified", new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/t-km"),
+						verifiedCO2.ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 1)
+					)
+				),
+				new XElement(tns + "VTRatio", cVtp.ToXMLFormat(4)));
+		}
+
 		private XDocument GenerateReport()
 		{
 			var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
 			var retVal = new XDocument();
-			retVal.Add(new XProcessingInstruction("xml-stylesheet", "href=\"https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/CSS/VectoReports.css\""));
-			retVal.Add(new XElement(tns + XMLNames.VectoManufacturerReport,
-									new XAttribute("schemaVersion", CURRENT_SCHEMA_VERSION),
-									new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
-									new XAttribute("xmlns", tns),
-									//new XAttribute(XNamespace.Xmlns + "di", di),
-									new XAttribute(xsi + "schemaLocation",
-													string.Format("{0} {1}VTPReport.{2}.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl, CURRENT_SCHEMA_VERSION)),
-									new XElement(tns + "Data",
-												new XElement(VehiclePart)
-												//results,
-												//GetApplicationInfo()
-											)
-						)
+			retVal.Add(
+				new XProcessingInstruction(
+					"xml-stylesheet", "href=\"https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/CSS/VectoReports.css\""));
+			retVal.Add(
+				new XElement(
+					tns + "VectoVTPReport",
+					new XAttribute("schemaVersion", CURRENT_SCHEMA_VERSION),
+					new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
+					new XAttribute("xmlns", tns),
+
+					//new XAttribute(XNamespace.Xmlns + "di", di),
+					new XAttribute(
+						xsi + "schemaLocation",
+						string.Format("{0} {1}VTPReport.{2}.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl, CURRENT_SCHEMA_VERSION)),
+					new XElement(
+						tns + "Data",
+						new XElement(GeneralPart),
+						new XElement(VehiclePart),
+						new XElement(DataIntegrityPart),
+						new XElement(TestConditionsPart),
+						new XElement(Results),
+						GetApplicationInfo()
+					)
+				)
 			);
 
 			return retVal;
@@ -78,53 +202,184 @@ namespace TUGraz.VectoCore.OutputData.XML {
 
 		public override void InitializeReport(VectoRunData modelData)
 		{
+			GeneralPart.Add(
+				new XElement(tns + XMLNames.Component_Manufacturer, modelData.VehicleData.Manufacturer),
+				new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress));
 			VehiclePart.Add(
+				new XElement(tns + XMLNames.Component_Model, modelData.VehicleData.ModelName),
 				new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN),
 				new XElement(tns + XMLNames.Vehicle_LegislativeClass, modelData.VehicleData.LegislativeClass.ToXMLFormat()),
 				new XElement(tns + XMLNames.Report_Vehicle_VehicleGroup, modelData.VehicleData.VehicleClass.GetClassNumber()),
 				new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()),
 				new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)),
 				new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)),
+				modelData.Retarder.Type.IsDedicatedComponent()
+					? new XElement(tns + XMLNames.Vehicle_RetarderRatio, modelData.Retarder.Ratio.ToXMLFormat(3))
+					: null,
 				new XElement(tns + XMLNames.Vehicle_PTO, modelData.PTO != null),
-				
-				new XElement(tns + XMLNames.Vehicle_Components,
-							GetEngineDescription(modelData.EngineData),
-							GetGearboxDescription(modelData.GearboxData),
-							GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData),
-							GetRetarderDescription(modelData.Retarder),
-							GetAngledriveDescription(modelData.AngledriveData),
-							GetAxlegearDescription(modelData.AxleGearData),
-							GetAirDragDescription(modelData.AirdragData),
-							GetAxleWheelsDescription(modelData.VehicleData),
-							GetAuxiliariesDescription(modelData.Aux)
+				new XElement(
+					tns + XMLNames.Vehicle_Components,
+					GetEngineDescription(modelData.EngineData),
+					GetGearboxDescription(modelData.GearboxData),
+					GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData),
+					GetRetarderDescription(modelData.Retarder),
+					GetAngledriveDescription(modelData.AngledriveData),
+					GetAxlegearDescription(modelData.AxleGearData),
+					GetAirDragDescription(modelData.AirdragData),
+					GetAxleWheelsDescription(modelData.VehicleData),
+					GetAuxiliariesDescription(modelData.Aux)
+				)
+			);
+
+			var componentChecks = new List<object>();
+
+			if (InputDataHash == null) {
+				return;
+			}
+
+			var allSuccess = true;
+			var components = InputDataHash.GetContainigComponents().GroupBy(s => s)
+										.Select(g => new { Entry = g.Key, Count = g.Count() });
+			foreach (var component in components) {
+				if (component.Entry == VectoComponents.Vehicle) {
+					continue;
+				}
+
+				for (var i = 0; i < component.Count; i++) {
+					var recomputed = "";
+					var read = "";
+					var readJob = "";
+					var error = "";
+					bool status;
+					try {
+						recomputed = InputDataHash.ComputeHash(component.Entry, i);
+						readJob = InputDataHash.ReadHash(component.Entry, i);
+						read = ManufacturerRecord.ComponentDigests[component.Entry][i];
+						status = string.Equals(readJob, recomputed) && string.Equals(recomputed, read);
+					} catch (Exception e) {
+						status = false;
+						error = e.Message;
+					}
+
+					allSuccess = allSuccess && status;
+					componentChecks.Add(
+						new XElement(
+							tns + "Component",
+							new XAttribute(
+								"componentName", component.Count == 1
+									? component.Entry.XMLElementName()
+									: string.Format("{0} ({1})", component.Entry.XMLElementName(), i + 1)),
+							new XAttribute("status", status ? "success" : "failed"),
+							new XElement(tns + "DigestValueRecomputed", recomputed),
+							new XElement(
+								tns + "DigestValueRead",
+								new XAttribute("source", "JobData"),
+								readJob
+							),
+							new XElement(
+								tns + "DigestValueRead",
+								new XAttribute("source", "ManufacturerRecord"),
+								read
+							),
+							status ? null : new XElement(tns + "Error", error)
+						));
+				}
+			}
+
+			string jobHashRecomputed = null;
+			string jobHashRead = null;
+			bool jobStatus;
+			string jobError = null;
+			try {
+				var jobHashMethods = ManufacturerRecord.JobDigest;
+				jobHashRecomputed = InputDataHash.ComputeHash(jobHashMethods.CanonicalizationMethods, jobHashMethods.DigestMethod);
+				jobHashRead = jobHashMethods.DigestValue;
+				jobStatus = string.Equals(jobHashRecomputed, jobHashRead);
+			} catch (Exception e) {
+				jobStatus = false;
+				jobError = e.Message;
+			}
+
+			allSuccess = allSuccess && jobStatus;
+			string mrHashRead = null;
+			string mrHashRecomputed = null;
+			bool mrStatus;
+			string mrError = null;
+			try {
+				mrHashRead = ManufacturerRecordHash.ReadHash();
+				mrHashRecomputed = ManufacturerRecordHash.ComputeHash();
+				mrStatus = ManufacturerRecordHash.ValidateHash();
+			} catch (Exception e) {
+				mrStatus = false;
+				mrError = e.Message;
+			}
+			allSuccess = allSuccess && mrStatus;
+			DataIntegrityPart.Add(
+				new XAttribute("status", allSuccess ? "success" : "failed"),
+				new XElement(
+					tns + "Components",
+					componentChecks.ToArray()
+				),
+				new XElement(
+					tns + "ManufacturerReport",
+					new XAttribute("status", mrStatus ? "success" : "failed"),
+					new XElement(tns + "DigestValueRecomputed", mrHashRecomputed),
+					new XElement(
+						tns + "DigestValueRead",
+						new XAttribute("source", "ManufacturerRecord"), mrHashRead),
+					mrStatus ? null : new XElement(tns + "Error", mrError)
+				),
+				new XElement(
+					tns + "JobData",
+					new XAttribute("status", jobStatus ? "success" : "failed"),
+					new XElement(
+						tns + "DigestValueRecomputed",
+						jobHashRecomputed),
+					new XElement(
+						tns + "DigestValueRead",
+						new XAttribute("source", "ManufacturerRecord"),
+						jobHashRead),
+					jobStatus ? null : new XElement(tns + "Error", jobError)
 				)
 			);
 		}
 
 		#endregion
 
+		private XElement GetApplicationInfo()
+		{
+			return new XElement(
+				tns + XMLNames.Report_ApplicationInfo_ApplicationInformation,
+				new XElement(tns + XMLNames.Report_ApplicationInfo_SimulationToolVersion, VectoSimulationCore.VersionNumber),
+				new XElement(
+					tns + XMLNames.Report_ApplicationInfo_Date,
+					XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc)));
+		}
+
 		private XElement GetEngineDescription(CombustionEngineData engineData)
 		{
-			return new XElement(tns + XMLNames.Component_Engine,
+			return new XElement(
+				tns + XMLNames.Component_Engine,
 				GetCommonDescription(engineData),
 				new XElement(tns + XMLNames.Engine_RatedPower, engineData.RatedPowerDeclared.ToXMLFormat(0)),
-				new XElement(tns + XMLNames.Engine_IdlingSpeed, engineData.IdleSpeed.AsRPM.ToXMLFormat(0)),
-				new XElement(tns + XMLNames.Engine_RatedSpeed, engineData.RatedSpeedDeclared.AsRPM.ToXMLFormat(0)),
-				new XElement(tns + XMLNames.Engine_Displacement,
+				new XElement(
+					tns + XMLNames.Engine_Displacement,
 					engineData.Displacement.ConvertToCubicCentiMeter().ToXMLFormat(0)),
 				new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelType.ToXMLFormat())
-				);
+			);
 		}
 
 		private XElement GetGearboxDescription(GearboxData gearboxData)
 		{
-			return new XElement(tns + XMLNames.Component_Gearbox,
+			return new XElement(
+				tns + XMLNames.Component_Gearbox,
 				GetCommonDescription(gearboxData),
 				new XElement(tns + XMLNames.Gearbox_TransmissionType, gearboxData.Type.ToXMLFormat()),
 				new XElement(tns + XMLNames.Report_GetGearbox_GearsCount, gearboxData.Gears.Count),
-				new XElement(tns + XMLNames.Report_Gearbox_TransmissionRatioFinalGear,
+				new XElement(
+					tns + XMLNames.Report_Gearbox_TransmissionRatioFinalGear,
 					gearboxData.Gears.Last().Value.Ratio.ToXMLFormat(3))
-				);
+			);
 		}
 
 		private XElement GetTorqueConverterDescription(TorqueConverterData torqueConverterData)
@@ -132,13 +387,16 @@ namespace TUGraz.VectoCore.OutputData.XML {
 			if (torqueConverterData == null) {
 				return null;
 			}
-			return new XElement(tns + XMLNames.Component_TorqueConverter,
+
+			return new XElement(
+				tns + XMLNames.Component_TorqueConverter,
 				GetCommonDescription(torqueConverterData));
 		}
 
 		private XElement GetRetarderDescription(RetarderData retarder)
 		{
-			return new XElement(tns + XMLNames.Component_Retarder,
+			return new XElement(
+				tns + XMLNames.Component_Retarder,
 				new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()),
 				retarder.Type.IsDedicatedComponent() ? GetCommonDescription(retarder) : null);
 		}
@@ -148,14 +406,17 @@ namespace TUGraz.VectoCore.OutputData.XML {
 			if (angledriveData == null) {
 				return null;
 			}
-			return new XElement(tns + XMLNames.Component_Angledrive,
+
+			return new XElement(
+				tns + XMLNames.Component_Angledrive,
 				GetCommonDescription(angledriveData),
 				new XElement(tns + XMLNames.AngleDrive_Ratio, angledriveData.Angledrive.Ratio));
 		}
 
 		private XElement GetAxlegearDescription(AxleGearData axleGearData)
 		{
-			return new XElement(tns + XMLNames.Component_Axlegear,
+			return new XElement(
+				tns + XMLNames.Component_Axlegear,
 				GetCommonDescription(axleGearData),
 				new XElement(tns + XMLNames.Axlegear_LineType, axleGearData.LineType.ToXMLFormat()),
 				new XElement(tns + XMLNames.Axlegear_Ratio, axleGearData.AxleGear.Ratio.ToXMLFormat(3)));
@@ -164,18 +425,20 @@ namespace TUGraz.VectoCore.OutputData.XML {
 		private XElement GetAirDragDescription(AirdragData airdragData)
 		{
 			if (airdragData.CertificationMethod == CertificationMethod.StandardValues) {
-				return new XElement(tns + XMLNames.Component_AirDrag,
+				return new XElement(
+					tns + XMLNames.Component_AirDrag,
 					new XElement(tns + XMLNames.Report_Component_CertificationMethod, airdragData.CertificationMethod.ToXMLFormat()),
 					new XElement(tns + XMLNames.Report_AirDrag_CdxA, airdragData.DeclaredAirdragArea.ToXMLFormat(2))
-					);
+				);
 			}
-			return new XElement(tns + XMLNames.Component_AirDrag,
+
+			return new XElement(
+				tns + XMLNames.Component_AirDrag,
 				new XElement(tns + XMLNames.Component_Model, airdragData.ModelName),
 				new XElement(tns + XMLNames.Report_Component_CertificationMethod, airdragData.CertificationMethod.ToXMLFormat()),
 				new XElement(tns + XMLNames.Report_Component_CertificationNumber, airdragData.CertificationNumber),
-				new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, airdragData.DigestValueInput),
 				new XElement(tns + XMLNames.Report_AirDrag_CdxA, airdragData.DeclaredAirdragArea.ToXMLFormat(2))
-				);
+			);
 		}
 
 		private XElement GetAxleWheelsDescription(VehicleData vehicleData)
@@ -186,6 +449,7 @@ namespace TUGraz.VectoCore.OutputData.XML {
 				if (axleData[i].AxleType == AxleType.Trailer) {
 					continue;
 				}
+
 				retVal.Add(GetAxleDescription(i + 1, axleData[i]));
 			}
 
@@ -194,11 +458,11 @@ namespace TUGraz.VectoCore.OutputData.XML {
 
 		private XElement GetAxleDescription(int i, Axle axle)
 		{
-			return new XElement(tns + XMLNames.AxleWheels_Axles_Axle,
+			return new XElement(
+				tns + XMLNames.AxleWheels_Axles_Axle,
 				new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i),
 				new XElement(tns + XMLNames.Report_Tyre_TyreDimension, axle.WheelsDimension),
-				new XElement(tns + XMLNames.Report_Tyre_TyreCertificationNumber, axle.CertificationNumber),
-				new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, axle.DigestValueInput),
+				new XElement(tns + XMLNames.Component_CertificationNumber, axle.CertificationNumber),
 				new XElement(tns + XMLNames.Report_Tyre_TyreRRCDeclared, axle.RollResistanceCoefficient.ToXMLFormat(4)),
 				new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres, axle.TwinTyres));
 		}
@@ -216,6 +480,7 @@ namespace TUGraz.VectoCore.OutputData.XML {
 					retVal.Add(new XElement(tns + GetTagName(auxId), entry));
 				}
 			}
+
 			return retVal;
 		}
 
@@ -229,7 +494,6 @@ namespace TUGraz.VectoCore.OutputData.XML {
 			return new object[] {
 				new XElement(tns + XMLNames.Component_Model, data.ModelName),
 				new XElement(tns + XMLNames.Report_Component_CertificationNumber, data.CertificationNumber),
-				new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput)
 			};
 		}
 
@@ -241,8 +505,17 @@ namespace TUGraz.VectoCore.OutputData.XML {
 				data.CertificationMethod == CertificationMethod.StandardValues
 					? null
 					: new XElement(tns + XMLNames.Report_Component_CertificationNumber, data.CertificationNumber),
-				new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput)
 			};
 		}
+
+		#region Implementation of IVTPReport
+
+		public IVectoHash InputDataHash { protected get; set; }
+
+		public IManufacturerReport ManufacturerRecord { protected get; set; }
+
+		public IVectoHash ManufacturerRecordHash { protected get; set; }
+
+		#endregion
 	}
-}
\ No newline at end of file
+}
diff --git a/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd b/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd
index e19994b671..57728b89c5 100644
--- a/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd
+++ b/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd
@@ -180,6 +180,13 @@
 	</xs:complexType>
 	<xs:complexType name="CO2ResultType">
 		<xs:sequence>
+			<xs:element name="Mission">
+				<xs:simpleType>
+					<xs:restriction base="xs:string">
+						<xs:minLength value="1"/>
+					</xs:restriction>
+				</xs:simpleType>
+			</xs:element>
 			<xs:element name="Declared">
 				<xs:complexType>
 					<xs:simpleContent>
@@ -205,7 +212,7 @@
 			<xs:element name="Components">
 				<xs:complexType>
 					<xs:sequence>
-						<xs:element name="Component" maxOccurs="unbounded">
+						<xs:element name="Component" minOccurs="0" maxOccurs="unbounded">
 							<xs:complexType>
 								<xs:complexContent>
 									<xs:extension base="DataIntegrityResultType">
@@ -224,8 +231,17 @@
 	</xs:complexType>
 	<xs:complexType name="DataIntegrityResultType">
 		<xs:sequence>
-			<xs:element name="DigestValueRead"/>
-			<xs:element name="DigestValueRecomputed"/>
+			<xs:element name="DigestValueRecomputed" type="xs:token"/>
+			<xs:element name="DigestValueRead" maxOccurs="unbounded">
+				<xs:complexType>
+					<xs:simpleContent>
+						<xs:extension base="xs:token">
+							<xs:attribute name="source" type="xs:token" use="required"/>
+						</xs:extension>
+					</xs:simpleContent>
+				</xs:complexType>
+			</xs:element>
+			<xs:element name="Error" type="xs:string" minOccurs="0"/>
 		</xs:sequence>
 		<xs:attribute name="status" type="DataIntegrityStatusType" use="required"/>
 	</xs:complexType>
@@ -462,7 +478,7 @@
 						<xs:element name="Gearbox" type="GearboxType"/>
 						<xs:element name="TorqueConverter" type="TorqueConverterType" minOccurs="0"/>
 						<xs:element name="Retarder" type="RetarderType"/>
-						<xs:element name="AngleDrive" type="AngleDriveType"/>
+						<xs:element name="AngleDrive" type="AngleDriveType" minOccurs="0"/>
 						<xs:element name="Axlegear" type="AxlegearType"/>
 						<xs:element name="AirDrag" type="AirDragType"/>
 						<xs:element name="AxleWheels" type="AxleWheelsType"/>
diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj
index 65e64974d1..d9d686776b 100644
--- a/VectoCore/VectoCore/VectoCore.csproj
+++ b/VectoCore/VectoCore/VectoCore.csproj
@@ -124,6 +124,7 @@
     <Compile Include="InputData\FileIO\XML\Declaration\XMLDeclarationTorqueConverterDataProvider.cs" />
     <Compile Include="InputData\FileIO\XML\Declaration\XMLDeclarationVehicleDataProvider.cs" />
     <Compile Include="InputData\FileIO\XML\Declaration\XMLDeclarationInputDataProvider.cs" />
+    <Compile Include="InputData\FileIO\XML\Declaration\XMLManufacturerReportReader.cs" />
     <Compile Include="InputData\FileIO\XML\Engineering\AbstractEngineeringXMLComponentDataProvider.cs" />
     <Compile Include="InputData\FileIO\XML\Engineering\XMLEngineeringAirdragDataProvider.cs" />
     <Compile Include="InputData\FileIO\XML\Engineering\XMLEngineeringAngledriveDataProvider.cs" />
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
index e529782f2d..a6d639b66c 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
@@ -633,7 +633,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 		}
 
 		public string CertificationNumber { get; set; }
-		public string DigestValue { get; set; }
+		public DigestData DigestValue { get; set; }
 		public GearboxType Type { get; set; }
 		public IList<ITransmissionInputData> Gears { get; set; }
 
diff --git a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml
index 3356681805..dfa7c42f70 100644
--- a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml	
+++ b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml	
@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
-<tns:VectoInputDeclaration schemaVersion="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" xmlns:tns="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0" xsi:schemaLocation="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0 https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/XSD/VectoInput.xsd">
+<tns:VectoInputDeclaration schemaVersion="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+	xmlns="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" 
+	xmlns:tns="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0" 
+	xmlns:di="http://www.w3.org/2000/09/xmldsig#"
+	xsi:schemaLocation="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0 https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/XSD/VectoInput.xsd">
   <Vehicle id="VEH-Tabelle1_Class-5_Genericvehicle">
     <Manufacturer>Generic Vendor</Manufacturer>
     <ManufacturerAddress>N.A.</ManufacturerAddress>
@@ -176,12 +180,12 @@
         </Data>
         <Signature>
           <Reference URI="#ENG-GenericEngine" xmlns="http://www.w3.org/2000/09/xmldsig#">
-            <Transforms>
-              <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-              <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-            </Transforms>
-            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-            <DigestValue></DigestValue>
+            <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>UxwXPq/SM3L4WIYOBWlMy1KbUowxU670gdh+B1MXDpo=</di:DigestValue>
           </Reference>
         </Signature>
       </Engine>
@@ -379,12 +383,12 @@
         </Data>
         <Signature>
           <Reference URI="#GBX-GB_12-gear" xmlns="http://www.w3.org/2000/09/xmldsig#">
-            <Transforms>
-              <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-              <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-            </Transforms>
-            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-            <DigestValue></DigestValue>
+            <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>JN8KciKSKfvIE54oFkwnuOX1pcxsR//cklWLP8gtNvY=</di:DigestValue>
           </Reference>
         </Signature>
       </Gearbox>
@@ -432,12 +436,12 @@
         </Data>
         <Signature>
           <Reference URI="#RET-RET-generic" xmlns="http://www.w3.org/2000/09/xmldsig#">
-            <Transforms>
-              <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-              <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-            </Transforms>
-            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-            <DigestValue></DigestValue>
+            <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>acR2Tz1XQ825YZRvDenOm9zarI6Dcw5QLgwPtDRVW1c=</di:DigestValue>
           </Reference>
         </Signature>
       </Retarder>
@@ -466,12 +470,12 @@
         </Data>
         <Signature>
           <Reference URI="#AXLGEAR-2640" xmlns="http://www.w3.org/2000/09/xmldsig#">
-            <Transforms>
-              <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-              <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-            </Transforms>
-            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-            <DigestValue></DigestValue>
+            <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>cKOhQhbRAelCtdfBGL8VjF5HcvQkVrw9sr0OkWeEYb0=</di:DigestValue>
           </Reference>
         </Signature>
       </Axlegear>
@@ -494,14 +498,14 @@
                   <FzISO>33350</FzISO>
                 </Data>
                 <Signature>
-                  <Reference URI="#TYRE-315_70R225" xmlns="http://www.w3.org/2000/09/xmldsig#">
-                    <Transforms>
-                      <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-                      <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-                    </Transforms>
-                    <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-                    <DigestValue></DigestValue>
-                  </Reference>
+				<di:Reference URI="#TYRE-315_70R225">
+                  <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>hr4Dcmy/uO+zoYr0KcPvcAOS93XYlCIKMyy1XeMO0AM=</di:DigestValue>
+                  </di:Reference>
                 </Signature>
               </Tyre>
             </Axle>
@@ -521,14 +525,14 @@
                   <FzISO>33350</FzISO>
                 </Data>
                 <Signature>
-                  <Reference URI="#TYRE-315_70R225" xmlns="http://www.w3.org/2000/09/xmldsig#">
-                    <Transforms>
-                      <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-                      <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-                    </Transforms>
-                    <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-                    <DigestValue></DigestValue>
-                  </Reference>
+				<di:Reference URI="#TYRE-315_70R225">
+                 <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>AsCRWiSEqb1HYnmM1SPXdz6KVzEZjXfvDkFppwyImY0=</di:DigestValue>
+                  </di:Reference>
                 </Signature>
               </Tyre>
             </Axle>
@@ -567,12 +571,12 @@
         </Data>
         <Signature>
           <Reference URI="#Airdrag-genericcabin" xmlns="http://www.w3.org/2000/09/xmldsig#">
-            <Transforms>
-              <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" />
-              <Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
-            </Transforms>
-            <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
-            <DigestValue></DigestValue>
+            <di:Transforms>
+        <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" />
+        <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+      </di:Transforms>
+      <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+      <di:DigestValue>xbCnjthzGoDH8oiydVX5eQmUoaeZ4aXpKwHtvd3ZkNQ=</di:DigestValue>
           </Reference>
         </Signature>
       </AirDrag>
diff --git a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto
index 4d6d7b6a60..fdc0895c42 100644
--- a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto	
+++ b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto	
@@ -8,6 +8,7 @@
   "Body": {
     "SavedInDeclMode": true,
     "DeclarationVehicle": "Tractor_4x2_vehicle-class-5_Generic vehicle.xml",
+	"ManufacturerRecord": "Tractor_4x2_vehicle-class-5_Generic vehicle.RSLT_MANUFACTURER.xml",
     "FanPowerCoefficients": [
       5.5E-07,
       15.0,
diff --git a/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs b/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs
index f857cd088e..7d6b8fe901 100644
--- a/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs
+++ b/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs
@@ -48,7 +48,7 @@ namespace TUGraz.VectoCore.Tests.Utils
 		public string TechnicalReportId { get; set; }
 		public CertificationMethod CertificationMethod { get{return CertificationMethod.NotCertified;} }
 		public string CertificationNumber { get; set; }
-		public string DigestValue { get; set; }
+		public DigestData DigestValue { get; set; }
 		public CubicMeter Displacement { get; set; }
 		public PerSecond IdleSpeed { get; set; }
 		public double WHTCMotorway { get; set; }
-- 
GitLab