diff --git a/VectoCommon/VectoHashingTest/VectoHashTest.cs b/VectoCommon/VectoHashingTest/VectoHashTest.cs
index 2a6c5c43ea742558568b64662e0cb0bc01664fb7..a38bbeacaa4f12c341bbeb90019ade3c44ff749a 100644
--- a/VectoCommon/VectoHashingTest/VectoHashTest.cs
+++ b/VectoCommon/VectoHashingTest/VectoHashTest.cs
@@ -29,430 +29,430 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Xml;
-using System.Xml.Linq;
-using System.Xml.Schema;
-using NUnit.Framework;
-using TUGraz.VectoCore.Utils;
-using TUGraz.VectoHashing;
-using VectoHashingTest.Utils;
-using Assert = NUnit.Framework.Assert;
-
-namespace VectoHashingTest
-{
-	[TestFixture]
-	public class VectoHashTest
-	{
-		public const string ReferenceXMLEngine = @"Testdata\XML\Reference\vecto_engine-sample.xml";
-		public const string ReferenceXMLVehicle = @"Testdata\XML\Reference\vecto_vehicle-sample_FULL.xml";
-
-		[TestCase]
-		public void TestComponentsEngineFile()
-		{
-			var h = VectoHash.Load(ReferenceXMLEngine);
-			var components = h.GetContainigComponents().ToList();
-
-			Assert.AreEqual(1, components.Count);
-			Assert.AreEqual(VectoComponents.Engine, components[0]);
-		}
-
-		[TestCase]
-		public void TestComponentsVehicleFile()
-		{
-			var h = VectoHash.Load(ReferenceXMLVehicle);
-			var components = h.GetContainigComponents().ToList();
-
-			Assert.AreEqual(10, components.Count);
-		}
-
-		[TestCase(ReferenceXMLEngine, VectoComponents.Engine, BasicHasingTests.HashEngineXML)]
-		public void TestHashComputationSelected(string file, VectoComponents component, string expectedHash)
-		{
-			var h = VectoHash.Load(file);
-			var hash = h.ComputeHash(component);
-
-			Assert.AreEqual(expectedHash, hash);
-		}
-
-		[TestCase(ReferenceXMLVehicle, BasicHasingTests.HashVehicleXML),
-		TestCase(ReferenceXMLEngine, BasicHasingTests.HashEngineXML)]
-		public void TestHashComputation(string file, string expectedHash)
-		{
-			var h = VectoHash.Load(file);
-			var hash = h.ComputeHash();
-
-			Assert.AreEqual(expectedHash, hash);
-		}
-
-		[TestCase(ReferenceXMLEngine)]
-		public void TestHashComputationInvalidComponent(string file)
-		{
-			var h = VectoHash.Load(file);
-			AssertHelper.Exception<Exception>(() => h.ComputeHash(VectoComponents.Gearbox), "Component Gearbox not found");
-		}
-
-		[TestCase(ReferenceXMLEngine)]
-		public void TestReadHashInvalidComponent(string file)
-		{
-			var h = VectoHash.Load(file);
-			AssertHelper.Exception<Exception>(() => h.ReadHash(VectoComponents.Gearbox), "Component Gearbox not found");
-		}
-
-		[TestCase(ReferenceXMLVehicle, VectoComponents.Engine, "e0c253b643f7f8f09b963aca4a264d06fbfa599f"),
-		TestCase(ReferenceXMLVehicle, VectoComponents.Gearbox, "d14189366134120e08fa3f2c6e3328dd13c08a23")]
-		public void TestReadHash(string file, VectoComponents component, string expectedHash)
-		{
-			var h = VectoHash.Load(file);
-			var existingHash = h.ReadHash(component);
-
-			Assert.AreEqual(expectedHash, existingHash);
-		}
-
-		[TestCase(ReferenceXMLVehicle, VectoComponents.Tyre, 0, "5074334bb2c090c5e258e9a664f5d19689a3f13d"),
-		TestCase(ReferenceXMLVehicle, VectoComponents.Tyre, 1, "6074334bb2c090c5e258e9a664f5d19689a3f13d")]
-		public void TestReadHashIdx(string file, VectoComponents component, int index, string expectedHash)
-		{
-			var h = VectoHash.Load(file);
-			var existingHash = h.ReadHash(component, index);
-
-			Assert.AreEqual(expectedHash, existingHash);
-		}
-
-		[TestCase]
-		public void TestReadTyres1Index()
-		{
-			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle1.xml";
-			var h = VectoHash.Load(file);
-			var expectedHash = new[] {
-				"5074334bb2c090c5e258e9a664f5d19689a3f13d",
-				"6074334bb2c090c5e258e9a664f5d19689a3f13d",
-				"6074334bb2c090c5e258e9a664f5d19689a3f13d"
-			};
-
-			for (int i = 0; i < expectedHash.Length; i++) {
-				var existingHash = h.ReadHash(VectoComponents.Tyre, i);
-
-				Assert.AreEqual(expectedHash[i], existingHash);
-			}
-		}
-
-		[TestCase]
-		public void TestReadTyres2Index()
-		{
-			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle2.xml";
-			var h = VectoHash.Load(file);
-			var expectedHash = new[] {
-				"5074334bb2c090c5e258e9a664f5d19689a3f13d",
-				"5074334bb2c090c5e258e9a664f5d19689a3f13d",
-				"6074334bb2c090c5e258e9a664f5d19689a3f13d"
-			};
-
-			for (int i = 0; i < expectedHash.Length; i++) {
-				var existingHash = h.ReadHash(VectoComponents.Tyre, i);
-
-				Assert.AreEqual(expectedHash[i], existingHash);
-			}
-
-			AssertHelper.Exception<Exception>(() => h.ReadHash(VectoComponents.Tyre, 3),
-				"index exceeds number of components found! index: 3, #components: 3");
-		}
-
-		[TestCase]
-		public void TestComputeTyres1Index()
-		{
-			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle1.xml";
-			var h = VectoHash.Load(file);
-
-			var hash1 = h.ComputeHash(VectoComponents.Tyre, 1);
-			var hash2 = h.ComputeHash(VectoComponents.Tyre, 2);
-
-			Assert.AreEqual(hash1, hash2);
-
-			AssertHelper.Exception<Exception>(() => h.ComputeHash(VectoComponents.Tyre, 3),
-				"index exceeds number of components found! index: 3, #components: 3");
-		}
-
-		[TestCase]
-		public void TestComputeTyres2Index()
-		{
-			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle2.xml";
-			var h = VectoHash.Load(file);
-
-			var hash1 = h.ComputeHash(VectoComponents.Tyre, 0);
-			var hash2 = h.ComputeHash(VectoComponents.Tyre, 1);
-
-			Assert.AreEqual(hash1, hash2);
-
-			AssertHelper.Exception<Exception>(() => h.ComputeHash(VectoComponents.Tyre, 3),
-				"index exceeds number of components found! index: 3, #components: 3");
-		}
-
-		[TestCase("vecto_vehicle-sample_FULL_Comments.xml", BasicHasingTests.HashVehicleXML),
-		TestCase("vecto_vehicle-sample_FULL_Entry_Order.xml", BasicHasingTests.HashVehicleXML),
-		TestCase("vecto_vehicle-sample_FULL_Newlines_Linux_LF.xml", BasicHasingTests.HashVehicleXML),
-		TestCase("vecto_vehicle-sample_FULL_Newlines_Mac_CR.xml", BasicHasingTests.HashVehicleXML),
-		TestCase("vecto_vehicle-sample_FULL_Newlines_Windows_CRLF.xml", BasicHasingTests.HashVehicleXML),
-		TestCase("vecto_engine-sample Encoding ISO 8859-15.xml", BasicHasingTests.HashEngineXML),
-		TestCase("vecto_engine-sample Encoding UTF-8 BOM.xml", BasicHasingTests.HashEngineXML),
-		TestCase("vecto_engine-sample Encoding UTF-8.xml", BasicHasingTests.HashEngineXML),
-		TestCase("vecto_engine-sample Encoding UTF-16 BE BOM.xml", BasicHasingTests.HashEngineXML),
-		TestCase("vecto_engine-sample Encoding UTF-16 LE.xml", BasicHasingTests.HashEngineXML),
-		TestCase("vecto_engine-sample Encoding windows-1292.xml", BasicHasingTests.HashEngineXML),
-		TestCase("vecto_engine-sample_Whitespaces.xml", BasicHasingTests.HashEngineXML),
-		]
-		public void TestHashComputationVariations(string file, string expectedHash)
-		{
-			var h = VectoHash.Load(@"Testdata\XML\Variations\" + file);
-			var hash = h.ComputeHash();
-
-			Assert.AreEqual(expectedHash, hash);
-		}
-
-
-		[TestCase(@"Testdata\XML\Validation\vecto_engine_valid.xml"),
-		TestCase(@"Testdata\XML\Validation\vecto_gearbox_valid.xml")]
-		public void TestValidation(string file)
-		{
-			var h = VectoHash.Load(file);
-			Assert.IsTrue(h.ValidateHash());
-		}
-
-		[TestCase(@"Testdata\XML\Validation\vecto_engine_invalid.xml"),
-		TestCase(@"Testdata\XML\Validation\vecto_gearbox_invalid.xml")]
-		public void TestValidationInvalid(string file)
-		{
-			var h = VectoHash.Load(file);
-			Assert.IsFalse(h.ValidateHash());
-		}
-
-		[TestCase(VectoComponents.Engine),
-		TestCase(VectoComponents.Gearbox),
-		]
-		public void TestValidationComponentValid(VectoComponents component)
-		{
-			var file = @"Testdata\XML\Validation\vecto_vehicle_components_valid-engine_gbx.xml";
-			var h = VectoHash.Load(file);
-
-			Assert.IsTrue(h.ValidateHash(component));
-		}
-
-		[TestCase(VectoComponents.Engine),
-		TestCase(VectoComponents.Gearbox),
-		TestCase(VectoComponents.Axlegear),
-		TestCase(VectoComponents.Angledrive),
-		TestCase(VectoComponents.Retarder),
-		TestCase(VectoComponents.TorqueConverter),
-		TestCase(VectoComponents.Tyre),
-		TestCase(VectoComponents.Airdrag),
-		]
-		public void TestValidationComponentInvalid(VectoComponents component)
-		{
-			var file = @"Testdata\XML\Validation\vecto_vehicle_components_invalid.xml";
-			var h = VectoHash.Load(file);
-
-			Assert.IsFalse(h.ValidateHash(component));
-		}
-
-		[TestCase(@"Testdata\XML\ToHash\vecto_engine-input.xml"),
-		TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml"),
-		TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input.xml")]
-		public void TestAddHash(string file)
-		{
-			var destination = Path.GetFileNameWithoutExtension(file) + "_hashed.xml";
-
-			var h = VectoHash.Load(file);
-			var r = h.AddHash();
-
-			var writer = new XmlTextWriter(destination, Encoding.UTF8);
-			r.WriteTo(writer);
-			writer.Flush();
-			writer.Close();
-
-			var h2 = VectoHash.Load(destination);
-			Assert.IsTrue(h2.ValidateHash());
-		}
-
-		[TestCase(@"Testdata\XML\ToHash\vecto_engine_withhash-input.xml", "input data already contains a signature element"),
-		TestCase(@"Testdata\XML\ToHash\vecto_vehicle-sample.xml", "adding hash for Vehicle is not supported"),
-		TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input_nodata.xml", "'Data' element for component 'Gearbox' not found!"),
-		TestCase(@"Testdata\XML\ToHash\multiple_components.xml", "input must not contain multiple components!"),
-		]
-		public void TestAddHashException(string file, string expectedExceptionMsg)
-		{
-			var destination = Path.GetFileNameWithoutExtension(file) + "_hashed.xml";
-
-			var h = VectoHash.Load(file);
-			AssertHelper.Exception<Exception>(() => { var r = h.AddHash(); }, expectedExceptionMsg);
-		}
-
-		[TestCase]
-		public void TestDuplicateSigElement()
-		{
-			var filename = @"Testdata\XML\Invalid\duplicate-sig.xml";
-			var h = VectoHash.Load(filename);
-
-			AssertHelper.Exception<Exception>(() => { var r = h.ReadHash(); }, "Multiple DigestValue elements found!");
-		}
-
-
-		[TestCase()]
-		public void TestLoadFromStream()
-		{
-			var fs = new FileStream(BasicHasingTests.ReferenceXMLVehicle, FileMode.Open);
-			var h = VectoHash.Load(fs);
-
-			var hash = h.ComputeHash();
-			Assert.AreEqual(BasicHasingTests.HashVehicleXML, hash);
-			fs.Close();
-		}
-
-		[TestCase(WhitespaceHandling.All),
-		TestCase(WhitespaceHandling.None),
-		TestCase(WhitespaceHandling.Significant)]
-		public void TestLoadXmlDocument(WhitespaceHandling whitespace)
-		{
-			var xml = new XmlDocument();
-			var reader = new XmlTextReader(BasicHasingTests.ReferenceXMLVehicle);
-			reader.WhitespaceHandling = whitespace;
-			xml.Load(reader);
-			var h = VectoHash.Load(xml);
-
-			var hash = h.ComputeHash();
-			Assert.AreEqual(BasicHasingTests.HashVehicleXML, hash);
-		}
-
-		[TestCase(@"Testdata\XML\ToHash\vecto_engine-input.xml"),
-		TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml"),
-		TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input.xml")]
-		public void TestHashedComponentIsValid(string file)
-		{
-			var destination = Path.GetFileNameWithoutExtension(file) + "_hashed.xml";
-
-			var h = VectoHash.Load(file);
-			var r = h.AddHash();
-
-			var writer = new XmlTextWriter(destination, Encoding.UTF8);
-			r.WriteTo(writer);
-			writer.Flush();
-			writer.Close();
-
-			var h2 = VectoHash.Load(destination);
-			Assert.IsTrue(h2.ValidateHash());
-
-			// re-load generated XML and perform XSD validation
-			var settings = new XmlReaderSettings() {
-				ValidationType = ValidationType.Schema,
-				ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
-								//XmlSchemaValidationFlags.ProcessSchemaLocation |
-								XmlSchemaValidationFlags.ReportValidationWarnings
-			};
-			settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
-			settings.Schemas.Add(GetXMLSchema(false));
-			var xmlValidator = XmlReader.Create(destination, settings);
-			var xmlDoc = XDocument.Load(xmlValidator);
-		}
-
-
-		[TestCase("vecto_vehicle-namespace_prefix.xml", BasicHasingTests.HashVehicleXML)]
-		public void TestNamespacePrefixVariations(string file, string expectedHash)
-		{
-			var h = VectoHash.Load(@"Testdata\XML\Variations\" + file);
-			var hash = h.ComputeHash();
-
-			Assert.AreEqual(expectedHash, hash);
-		}
-
-		[TestCase()]
-		public void TestInvalidXMLAsFile()
-		{
-			var file = @"Testdata\XML\Invalid\invalid-comp.xml";
-
-			AssertHelper.Exception<Exception>(() => VectoHash.Load(file), "failed to read XML document");
-		}
-
-		[TestCase()]
-		public void TestInvalidXMLAsStream()
-		{
-			var file = @"Testdata\XML\Invalid\invalid-comp.xml";
-			var stream = File.Open(file, FileMode.Open);
-			AssertHelper.Exception<Exception>(() => VectoHash.Load(stream), "failed to read XML document");
-		}
-
-		[TestCase()]
-		public void TestComputeHashNoComponentInXML()
-		{
-			var xml = @"<VectoInputDeclaration/>";
-			var stream = new MemoryStream();
-			var writer = new StreamWriter(stream);
-			writer.Write(xml);
-			writer.Flush();
-			stream.Seek(0, SeekOrigin.Begin);
-
-			var h = VectoHash.Load(stream);
-			AssertHelper.Exception<Exception>(() => h.ComputeHash(), "No component found");
-		}
-
-		[TestCase()]
-		public void TestReadHashNoComponentInXML()
-		{
-			var xml = @"<VectoInputDeclaration/>";
-			var stream = new MemoryStream();
-			var writer = new StreamWriter(stream);
-			writer.Write(xml);
-			writer.Flush();
-			stream.Seek(0, SeekOrigin.Begin);
-
-			var h = VectoHash.Load(stream);
-			AssertHelper.Exception<Exception>(() => h.ReadHash(), "No component found");
-		}
-
-		[TestCase(VectoComponents.Engine, "ENG-"),
-		TestCase(VectoComponents.Gearbox, "GBX-"),
-		TestCase(VectoComponents.Axlegear, "AXL-"),
-		TestCase(VectoComponents.Retarder, "RET-"),
-		TestCase(VectoComponents.TorqueConverter, "TC-"),
-		TestCase(VectoComponents.Angledrive, "ANGL-"),
-		TestCase(VectoComponents.Airdrag, "AD-"),
-		TestCase(VectoComponents.Tyre, "TYRE-"),
-		]
-		public void TestIdPrefix(VectoComponents component, string expectedPrefix)
-		{
-			Assert.AreEqual(expectedPrefix, component.HashIdPrefix());
-		}
-
-		[TestCase()]
-		public void TestInvalidComponentXMLName()
-		{
-			AssertHelper.Exception<ArgumentOutOfRangeException>(() => ((VectoComponents)9999).XMLElementName());
-		}
-
-		[TestCase()]
-		public void TestInvalidComponentPrefix()
-		{
-			AssertHelper.Exception<ArgumentOutOfRangeException>(() => ((VectoComponents)9999).HashIdPrefix());
-		}
-
-		private static XmlSchemaSet GetXMLSchema(bool job)
-		{
-			var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema,
-				job ? "VectoInput.xsd" : "VectoComponent.xsd");
-			var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() };
-			var reader = XmlReader.Create(resource, new XmlReaderSettings(), "schema://");
-			xset.Add(XmlSchema.Read(reader, null));
-			xset.Compile();
-			return xset;
-		}
-
-		private static void ValidationCallBack(object sender, ValidationEventArgs args)
-		{
-			if (args.Severity == XmlSeverityType.Error) {
-				throw new Exception(string.Format("Validation error: {0}" + Environment.NewLine +
-												"Line: {1}", args.Message, args.Exception.LineNumber));
-			}
-		}
-	}
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using NUnit.Framework;
+using TUGraz.VectoCore.Utils;
+using TUGraz.VectoHashing;
+using VectoHashingTest.Utils;
+using Assert = NUnit.Framework.Assert;
+
+namespace VectoHashingTest
+{
+	[TestFixture]
+	public class VectoHashTest
+	{
+		public const string ReferenceXMLEngine = @"Testdata\XML\Reference\vecto_engine-sample.xml";
+		public const string ReferenceXMLVehicle = @"Testdata\XML\Reference\vecto_vehicle-sample_FULL.xml";
+
+		[TestCase]
+		public void TestComponentsEngineFile()
+		{
+			var h = VectoHash.Load(ReferenceXMLEngine);
+			var components = h.GetContainigComponents().ToList();
+
+			Assert.AreEqual(1, components.Count);
+			Assert.AreEqual(VectoComponents.Engine, components[0]);
+		}
+
+		[TestCase]
+		public void TestComponentsVehicleFile()
+		{
+			var h = VectoHash.Load(ReferenceXMLVehicle);
+			var components = h.GetContainigComponents().ToList();
+
+			Assert.AreEqual(10, components.Count);
+		}
+
+		[TestCase(ReferenceXMLEngine, VectoComponents.Engine, BasicHasingTests.HashEngineXML)]
+		public void TestHashComputationSelected(string file, VectoComponents component, string expectedHash)
+		{
+			var h = VectoHash.Load(file);
+			var hash = h.ComputeHash(component);
+
+			Assert.AreEqual(expectedHash, hash);
+		}
+
+		[TestCase(ReferenceXMLVehicle, BasicHasingTests.HashVehicleXML),
+		TestCase(ReferenceXMLEngine, BasicHasingTests.HashEngineXML)]
+		public void TestHashComputation(string file, string expectedHash)
+		{
+			var h = VectoHash.Load(file);
+			var hash = h.ComputeHash();
+
+			Assert.AreEqual(expectedHash, hash);
+		}
+
+		[TestCase(ReferenceXMLEngine)]
+		public void TestHashComputationInvalidComponent(string file)
+		{
+			var h = VectoHash.Load(file);
+			AssertHelper.Exception<Exception>(() => h.ComputeHash(VectoComponents.Gearbox), "Component Gearbox not found");
+		}
+
+		[TestCase(ReferenceXMLEngine)]
+		public void TestReadHashInvalidComponent(string file)
+		{
+			var h = VectoHash.Load(file);
+			AssertHelper.Exception<Exception>(() => h.ReadHash(VectoComponents.Gearbox), "Component Gearbox not found");
+		}
+
+		[TestCase(ReferenceXMLVehicle, VectoComponents.Engine, "e0c253b643f7f8f09b963aca4a264d06fbfa599f"),
+		TestCase(ReferenceXMLVehicle, VectoComponents.Gearbox, "d14189366134120e08fa3f2c6e3328dd13c08a23")]
+		public void TestReadHash(string file, VectoComponents component, string expectedHash)
+		{
+			var h = VectoHash.Load(file);
+			var existingHash = h.ReadHash(component);
+
+			Assert.AreEqual(expectedHash, existingHash);
+		}
+
+		[TestCase(ReferenceXMLVehicle, VectoComponents.Tyre, 0, "5074334bb2c090c5e258e9a664f5d19689a3f13d"),
+		TestCase(ReferenceXMLVehicle, VectoComponents.Tyre, 1, "6074334bb2c090c5e258e9a664f5d19689a3f13d")]
+		public void TestReadHashIdx(string file, VectoComponents component, int index, string expectedHash)
+		{
+			var h = VectoHash.Load(file);
+			var existingHash = h.ReadHash(component, index);
+
+			Assert.AreEqual(expectedHash, existingHash);
+		}
+
+		[TestCase]
+		public void TestReadTyres1Index()
+		{
+			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle1.xml";
+			var h = VectoHash.Load(file);
+			var expectedHash = new[] {
+				"5074334bb2c090c5e258e9a664f5d19689a3f13d",
+				"6074334bb2c090c5e258e9a664f5d19689a3f13d",
+				"6074334bb2c090c5e258e9a664f5d19689a3f13d"
+			};
+
+			for (int i = 0; i < expectedHash.Length; i++) {
+				var existingHash = h.ReadHash(VectoComponents.Tyre, i);
+
+				Assert.AreEqual(expectedHash[i], existingHash);
+			}
+		}
+
+		[TestCase]
+		public void TestReadTyres2Index()
+		{
+			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle2.xml";
+			var h = VectoHash.Load(file);
+			var expectedHash = new[] {
+				"5074334bb2c090c5e258e9a664f5d19689a3f13d",
+				"5074334bb2c090c5e258e9a664f5d19689a3f13d",
+				"6074334bb2c090c5e258e9a664f5d19689a3f13d"
+			};
+
+			for (int i = 0; i < expectedHash.Length; i++) {
+				var existingHash = h.ReadHash(VectoComponents.Tyre, i);
+
+				Assert.AreEqual(expectedHash[i], existingHash);
+			}
+
+			AssertHelper.Exception<Exception>(() => h.ReadHash(VectoComponents.Tyre, 3),
+				"index exceeds number of components found! index: 3, #components: 3");
+		}
+
+		[TestCase]
+		public void TestComputeTyres1Index()
+		{
+			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle1.xml";
+			var h = VectoHash.Load(file);
+
+			var hash1 = h.ComputeHash(VectoComponents.Tyre, 1);
+			var hash2 = h.ComputeHash(VectoComponents.Tyre, 2);
+
+			Assert.AreEqual(hash1, hash2);
+
+			AssertHelper.Exception<Exception>(() => h.ComputeHash(VectoComponents.Tyre, 3),
+				"index exceeds number of components found! index: 3, #components: 3");
+		}
+
+		[TestCase]
+		public void TestComputeTyres2Index()
+		{
+			var file = @"Testdata\XML\ToHash\vecto_vehicle-sample_3axle2.xml";
+			var h = VectoHash.Load(file);
+
+			var hash1 = h.ComputeHash(VectoComponents.Tyre, 0);
+			var hash2 = h.ComputeHash(VectoComponents.Tyre, 1);
+
+			Assert.AreEqual(hash1, hash2);
+
+			AssertHelper.Exception<Exception>(() => h.ComputeHash(VectoComponents.Tyre, 3),
+				"index exceeds number of components found! index: 3, #components: 3");
+		}
+
+		[TestCase("vecto_vehicle-sample_FULL_Comments.xml", BasicHasingTests.HashVehicleXML),
+		TestCase("vecto_vehicle-sample_FULL_Entry_Order.xml", BasicHasingTests.HashVehicleXML),
+		TestCase("vecto_vehicle-sample_FULL_Newlines_Linux_LF.xml", BasicHasingTests.HashVehicleXML),
+		TestCase("vecto_vehicle-sample_FULL_Newlines_Mac_CR.xml", BasicHasingTests.HashVehicleXML),
+		TestCase("vecto_vehicle-sample_FULL_Newlines_Windows_CRLF.xml", BasicHasingTests.HashVehicleXML),
+		TestCase("vecto_engine-sample Encoding ISO 8859-15.xml", BasicHasingTests.HashEngineXML),
+		TestCase("vecto_engine-sample Encoding UTF-8 BOM.xml", BasicHasingTests.HashEngineXML),
+		TestCase("vecto_engine-sample Encoding UTF-8.xml", BasicHasingTests.HashEngineXML),
+		TestCase("vecto_engine-sample Encoding UTF-16 BE BOM.xml", BasicHasingTests.HashEngineXML),
+		TestCase("vecto_engine-sample Encoding UTF-16 LE.xml", BasicHasingTests.HashEngineXML),
+		TestCase("vecto_engine-sample Encoding windows-1292.xml", BasicHasingTests.HashEngineXML),
+		TestCase("vecto_engine-sample_Whitespaces.xml", BasicHasingTests.HashEngineXML),
+		]
+		public void TestHashComputationVariations(string file, string expectedHash)
+		{
+			var h = VectoHash.Load(@"Testdata\XML\Variations\" + file);
+			var hash = h.ComputeHash();
+
+			Assert.AreEqual(expectedHash, hash);
+		}
+
+
+		[TestCase(@"Testdata\XML\Validation\vecto_engine_valid.xml"),
+		TestCase(@"Testdata\XML\Validation\vecto_gearbox_valid.xml")]
+		public void TestValidation(string file)
+		{
+			var h = VectoHash.Load(file);
+			Assert.IsTrue(h.ValidateHash());
+		}
+
+		[TestCase(@"Testdata\XML\Validation\vecto_engine_invalid.xml"),
+		TestCase(@"Testdata\XML\Validation\vecto_gearbox_invalid.xml")]
+		public void TestValidationInvalid(string file)
+		{
+			var h = VectoHash.Load(file);
+			Assert.IsFalse(h.ValidateHash());
+		}
+
+		[TestCase(VectoComponents.Engine),
+		TestCase(VectoComponents.Gearbox),
+		]
+		public void TestValidationComponentValid(VectoComponents component)
+		{
+			var file = @"Testdata\XML\Validation\vecto_vehicle_components_valid-engine_gbx.xml";
+			var h = VectoHash.Load(file);
+
+			Assert.IsTrue(h.ValidateHash(component));
+		}
+
+		[TestCase(VectoComponents.Engine),
+		TestCase(VectoComponents.Gearbox),
+		TestCase(VectoComponents.Axlegear),
+		TestCase(VectoComponents.Angledrive),
+		TestCase(VectoComponents.Retarder),
+		TestCase(VectoComponents.TorqueConverter),
+		TestCase(VectoComponents.Tyre),
+		TestCase(VectoComponents.Airdrag),
+		]
+		public void TestValidationComponentInvalid(VectoComponents component)
+		{
+			var file = @"Testdata\XML\Validation\vecto_vehicle_components_invalid.xml";
+			var h = VectoHash.Load(file);
+
+			Assert.IsFalse(h.ValidateHash(component));
+		}
+
+		[TestCase(@"Testdata\XML\ToHash\vecto_engine-input.xml"),
+		TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml"),
+		TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input.xml")]
+		public void TestAddHash(string file)
+		{
+			var destination = Path.GetFileNameWithoutExtension(file) + "_hashed.xml";
+
+			var h = VectoHash.Load(file);
+			var r = h.AddHash();
+
+			var writer = new XmlTextWriter(destination, Encoding.UTF8);
+			r.WriteTo(writer);
+			writer.Flush();
+			writer.Close();
+
+			var h2 = VectoHash.Load(destination);
+			Assert.IsTrue(h2.ValidateHash());
+		}
+
+		[TestCase(@"Testdata\XML\ToHash\vecto_engine_withhash-input.xml", "input data already contains a signature element"),
+		TestCase(@"Testdata\XML\ToHash\vecto_vehicle-sample.xml", "adding hash for Vehicle is not supported"),
+		TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input_nodata.xml", "'Data' element for component 'Gearbox' not found!"),
+		TestCase(@"Testdata\XML\ToHash\multiple_components.xml", "input must not contain multiple components!"),
+		]
+		public void TestAddHashException(string file, string expectedExceptionMsg)
+		{
+			var destination = Path.GetFileNameWithoutExtension(file) + "_hashed.xml";
+
+			var h = VectoHash.Load(file);
+			AssertHelper.Exception<Exception>(() => { var r = h.AddHash(); }, expectedExceptionMsg);
+		}
+
+		[TestCase]
+		public void TestDuplicateSigElement()
+		{
+			var filename = @"Testdata\XML\Invalid\duplicate-sig.xml";
+			var h = VectoHash.Load(filename);
+
+			AssertHelper.Exception<Exception>(() => { var r = h.ReadHash(); }, "Multiple DigestValue elements found!");
+		}
+
+
+		[TestCase()]
+		public void TestLoadFromStream()
+		{
+			var fs = new FileStream(BasicHasingTests.ReferenceXMLVehicle, FileMode.Open);
+			var h = VectoHash.Load(fs);
+
+			var hash = h.ComputeHash();
+			Assert.AreEqual(BasicHasingTests.HashVehicleXML, hash);
+			fs.Close();
+		}
+
+		[TestCase(WhitespaceHandling.All),
+		TestCase(WhitespaceHandling.None),
+		TestCase(WhitespaceHandling.Significant)]
+		public void TestLoadXmlDocument(WhitespaceHandling whitespace)
+		{
+			var xml = new XmlDocument();
+			var reader = new XmlTextReader(BasicHasingTests.ReferenceXMLVehicle);
+			reader.WhitespaceHandling = whitespace;
+			xml.Load(reader);
+			var h = VectoHash.Load(xml);
+
+			var hash = h.ComputeHash();
+			Assert.AreEqual(BasicHasingTests.HashVehicleXML, hash);
+		}
+
+		[TestCase(@"Testdata\XML\ToHash\vecto_engine-input.xml"),
+		TestCase(@"Testdata\XML\ToHash\vecto_engine_withid-input.xml"),
+		TestCase(@"Testdata\XML\ToHash\vecto_gearbox-input.xml")]
+		public void TestHashedComponentIsValid(string file)
+		{
+			var destination = Path.GetFileNameWithoutExtension(file) + "_hashed.xml";
+
+			var h = VectoHash.Load(file);
+			var r = h.AddHash();
+
+			var writer = new XmlTextWriter(destination, Encoding.UTF8);
+			r.WriteTo(writer);
+			writer.Flush();
+			writer.Close();
+
+			var h2 = VectoHash.Load(destination);
+			Assert.IsTrue(h2.ValidateHash());
+
+			// re-load generated XML and perform XSD validation
+			var settings = new XmlReaderSettings() {
+				ValidationType = ValidationType.Schema,
+				ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
+								//XmlSchemaValidationFlags.ProcessSchemaLocation |
+								XmlSchemaValidationFlags.ReportValidationWarnings
+			};
+			settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
+			settings.Schemas.Add(GetXMLSchema(false));
+			var xmlValidator = XmlReader.Create(destination, settings);
+			var xmlDoc = XDocument.Load(xmlValidator);
+		}
+
+
+		[TestCase("vecto_vehicle-namespace_prefix.xml", BasicHasingTests.HashVehicleXML)]
+		public void TestNamespacePrefixVariations(string file, string expectedHash)
+		{
+			var h = VectoHash.Load(@"Testdata\XML\Variations\" + file);
+			var hash = h.ComputeHash();
+
+			Assert.AreEqual(expectedHash, hash);
+		}
+
+		[TestCase()]
+		public void TestInvalidXMLAsFile()
+		{
+			var file = @"Testdata\XML\Invalid\invalid-comp.xml";
+
+			AssertHelper.Exception<Exception>(() => VectoHash.Load(file), "failed to read XML document");
+		}
+
+		[TestCase()]
+		public void TestInvalidXMLAsStream()
+		{
+			var file = @"Testdata\XML\Invalid\invalid-comp.xml";
+			var stream = File.Open(file, FileMode.Open);
+			AssertHelper.Exception<Exception>(() => VectoHash.Load(stream), "failed to read XML document");
+		}
+
+		[TestCase()]
+		public void TestComputeHashNoComponentInXML()
+		{
+			var xml = @"<VectoInputDeclaration/>";
+			var stream = new MemoryStream();
+			var writer = new StreamWriter(stream);
+			writer.Write(xml);
+			writer.Flush();
+			stream.Seek(0, SeekOrigin.Begin);
+
+			var h = VectoHash.Load(stream);
+			AssertHelper.Exception<Exception>(() => h.ComputeHash(), "No component found");
+		}
+
+		[TestCase()]
+		public void TestReadHashNoComponentInXML()
+		{
+			var xml = @"<VectoInputDeclaration/>";
+			var stream = new MemoryStream();
+			var writer = new StreamWriter(stream);
+			writer.Write(xml);
+			writer.Flush();
+			stream.Seek(0, SeekOrigin.Begin);
+
+			var h = VectoHash.Load(stream);
+			AssertHelper.Exception<Exception>(() => h.ReadHash(), "No component found");
+		}
+
+		[TestCase(VectoComponents.Engine, "ENG-"),
+		TestCase(VectoComponents.Gearbox, "GBX-"),
+		TestCase(VectoComponents.Axlegear, "AXL-"),
+		TestCase(VectoComponents.Retarder, "RET-"),
+		TestCase(VectoComponents.TorqueConverter, "TC-"),
+		TestCase(VectoComponents.Angledrive, "ANGL-"),
+		TestCase(VectoComponents.Airdrag, "AD-"),
+		TestCase(VectoComponents.Tyre, "TYRE-"),
+		]
+		public void TestIdPrefix(VectoComponents component, string expectedPrefix)
+		{
+			Assert.AreEqual(expectedPrefix, component.HashIdPrefix());
+		}
+
+		[TestCase()]
+		public void TestInvalidComponentXMLName()
+		{
+			AssertHelper.Exception<ArgumentOutOfRangeException>(() => ((VectoComponents)9999).XMLElementName());
+		}
+
+		[TestCase()]
+		public void TestInvalidComponentPrefix()
+		{
+			AssertHelper.Exception<ArgumentOutOfRangeException>(() => ((VectoComponents)9999).HashIdPrefix());
+		}
+
+		private static XmlSchemaSet GetXMLSchema(bool job)
+		{
+			var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema,
+				job ? "VectoInput.xsd" : "VectoComponent.xsd");
+			var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() };
+			var reader = XmlReader.Create(resource, new XmlReaderSettings(), "schema://");
+			xset.Add(XmlSchema.Read(reader, null));
+			xset.Compile();
+			return xset;
+		}
+
+		private static void ValidationCallBack(object sender, ValidationEventArgs args)
+		{
+			if (args.Severity == XmlSeverityType.Error) {
+				throw new Exception(string.Format("Validation error: {0}" + Environment.NewLine +
+												"Line: {1}", args.Message, args.Exception.LineNumber));
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
index 207f17c59015785251f2b258189b341a30a84534..dbae9245a3542a478016f308e9015468cad9c090 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/DistanceBasedDrivingCycle.cs
@@ -29,525 +29,527 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using TUGraz.VectoCommon.Exceptions;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Connector.Ports;
-using TUGraz.VectoCore.Models.Connector.Ports.Impl;
-using TUGraz.VectoCore.Models.Simulation;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.Utils;
-
-namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
-{
-	/// <summary>
-	///     Class representing one Distance Based Driving Cycle
-	/// </summary>
-	public sealed class DistanceBasedDrivingCycle : StatefulProviderComponent
-		<DistanceBasedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDrivingCycleInPort, IDrivingCycleOutPort>,
-		IDrivingCycle, ISimulationOutPort, IDrivingCycleInPort, IDisposable
-	{
-		private const double LookaheadTimeSafetyMargin = 1.5;
-		internal readonly IDrivingCycleData Data;
-		internal readonly DrivingCycleEnumerator CycleIntervalIterator;
-		private bool _intervalProlonged;
-		internal IdleControllerSwitcher IdleController;
-
-		private DrivingCycleData.DrivingCycleEntry Left
-		{
-			get { return CycleIntervalIterator.LeftSample; }
-		}
-
-		private DrivingCycleData.DrivingCycleEntry Right
-		{
-			get { return CycleIntervalIterator.RightSample; }
-		}
-
-		public DistanceBasedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container)
-		{
-			Data = cycle;
-			CycleIntervalIterator = new DrivingCycleEnumerator(Data);
-			CycleStartDistance = Data.Entries.Count > 0 ? Data.Entries.First().Distance : 0.SI<Meter>();
-
-			var first = Data.Entries.First();
-			PreviousState = new DrivingCycleState {
-				AbsTime = 0.SI<Second>(),
-				WaitTime = 0.SI<Second>(),
-				Distance = first.Distance,
-				Altitude = first.Altitude,
-			};
-			CurrentState = PreviousState.Clone();
-		}
-
-		public IResponse Initialize()
-		{
-			if (Left.VehicleTargetSpeed.IsEqual(0)) {
-				var retVal = NextComponent.Initialize(DataBus.StartSpeed,
-					Left.RoadGradient, DataBus.StartAcceleration);
-				if (!(retVal is ResponseSuccess)) {
-					throw new UnexpectedResponseException("DistanceBasedDrivingCycle.Initialize: Couldn't find start gear.", retVal);
-				}
-			}
-
-			return NextComponent.Initialize(Left.VehicleTargetSpeed,
-				Left.RoadGradient);
-		}
-
-		public IResponse Request(Second absTime, Second dt)
-		{
-			throw new NotImplementedException("Distance Based Driving Cycle does not support time requests.");
-		}
-
-		public IResponse Request(Second absTime, Meter ds)
-		{
-			if (Left.Distance.IsEqual(PreviousState.Distance.Value())) {
-				// we are exactly on an entry in the cycle.
-				var stopTime = Left.PTOActive && IdleController != null
-					? Left.StoppingTime + IdleController.Duration
-					: Left.StoppingTime;
-
-				if (stopTime.IsGreater(0) && PreviousState.WaitTime.IsSmaller(stopTime)) {
-					// stop for certain time unless we've already waited long enough ...
-
-					// we are stopping: ensure that velocity is 0.
-					if (!Left.VehicleTargetSpeed.IsEqual(0)) {
-						Log.Warn("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}",
-							Left.StoppingTime, Left.VehicleTargetSpeed);
-						throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!");
-					}
-					var dt = GetStopTimeInterval();
-					if (dt == null) {
-						CurrentState.WaitPhase++;
-						dt = GetStopTimeInterval();
-					}
-					CurrentState.Response = DriveTimeInterval(absTime, dt);
-					return CurrentState.Response;
-				}
-			}
-			if (CycleIntervalIterator.LastEntry && PreviousState.Distance.IsEqual(Right.Distance)) {
-				CurrentState.Response = new ResponseCycleFinished();
-				return CurrentState.Response;
-			}
-
-			var nextSpeedChange = GetSpeedChangeWithinSimulationInterval(ds);
-			if (nextSpeedChange == null || ds.IsSmallerOrEqual(nextSpeedChange - PreviousState.Distance)) {
-				if (nextSpeedChange == null || DataBus.VehicleSpeed.IsEqual(0.SI<MeterPerSecond>())) {
-					CurrentState.Response = DriveDistance(absTime, ds);
-					return CurrentState.Response;
-				}
-				var remainingDistance = nextSpeedChange - PreviousState.Distance - ds;
-				var estimatedRemainingTime = remainingDistance / DataBus.VehicleSpeed;
-				if (_intervalProlonged || remainingDistance.IsEqual(0.SI<Meter>()) ||
-					estimatedRemainingTime.IsGreater(Constants.SimulationSettings.LowerBoundTimeInterval)) {
-					CurrentState.Response = DriveDistance(absTime, ds);
-					return CurrentState.Response;
-				}
-				Log.Debug("Extending distance by {0} to next sample point. ds: {1} new ds: {2}", remainingDistance, ds,
-					nextSpeedChange - PreviousState.Distance);
-				_intervalProlonged = true;
-				CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
-					Source = this,
-					MaxDistance = nextSpeedChange - PreviousState.Distance
-				};
-				return CurrentState.Response;
-			}
-			// only drive until next sample point in cycle with speed change
-			Log.Debug("Limiting distance to next sample point {0}",
-				Right.Distance - PreviousState.Distance);
-			CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
-				Source = this,
-				MaxDistance = nextSpeedChange - PreviousState.Distance
-			};
-			return CurrentState.Response;
-		}
-
-		private Second GetStopTimeInterval()
-		{
-			if (!Left.PTOActive || IdleController == null) {
-				return Left.StoppingTime.IsGreater(3 * Constants.SimulationSettings.TargetTimeInterval)
-					? GetStopTimeIntervalThreePhases()
-					: Left.StoppingTime;
-			}
-			if (Left.StoppingTime.IsGreater(6 * Constants.SimulationSettings.TargetTimeInterval)) {
-				// 7 phases
-				return GetStopTimeIntervalSevenPhasesPTO();
-			}
-			if (Left.StoppingTime.IsGreater(0)) {
-				// 3 phases
-				return GetStopTimeIntervalThreePhasesPTO();
-			}
-			// we have a pto cycle without stopping time.
-			IdleController.ActivatePTO();
-			return IdleController.GetNextCycleTime();
-		}
-
-		private Second GetStopTimeIntervalThreePhases()
-		{
-			switch (CurrentState.WaitPhase) {
-				case 1:
-				case 3:
-					CurrentState.WaitPhase++;
-					return Constants.SimulationSettings.TargetTimeInterval;
-				case 2:
-					CurrentState.WaitPhase++;
-					return Left.StoppingTime - 2 * Constants.SimulationSettings.TargetTimeInterval;
-			}
-			return null;
-		}
-
-		private Second GetStopTimeIntervalThreePhasesPTO()
-		{
-			switch (CurrentState.WaitPhase) {
-				case 1:
-				case 3:
-					CurrentState.WaitPhase++;
-					IdleController.ActivateIdle();
-					PTOActive = false;
-					return Left.StoppingTime / 2;
-				case 2:
-					PTOActive = true;
-					IdleController.ActivatePTO();
-					return IdleController.GetNextCycleTime();
-			}
-			return null;
-		}
-
-		private Second GetStopTimeIntervalSevenPhasesPTO()
-		{
-			switch (CurrentState.WaitPhase) {
-				case 1:
-				case 5:
-					CurrentState.WaitPhase++;
-					IdleController.ActivateIdle();
-					PTOActive = false;
-					return Constants.SimulationSettings.TargetTimeInterval;
-				case 3:
-				case 7:
-					CurrentState.WaitPhase++;
-					return Constants.SimulationSettings.TargetTimeInterval;
-				case 2:
-				case 6:
-					CurrentState.WaitPhase++;
-					return Left.StoppingTime / 2 - 2 * Constants.SimulationSettings.TargetTimeInterval;
-				case 4:
-					PTOActive = true;
-					IdleController.ActivatePTO();
-					return IdleController.GetNextCycleTime();
-			}
-			return null;
-		}
-
-		private IResponse DriveTimeInterval(Second absTime, Second dt)
-		{
-			CurrentState.AbsTime = absTime;
-			CurrentState.WaitTime = PreviousState.WaitTime + dt;
-			CurrentState.Gradient = ComputeGradient(0.SI<Meter>());
-			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
-
-			return NextComponent.Request(absTime, dt, Left.VehicleTargetSpeed, CurrentState.Gradient);
-		}
-
-		private IResponse DriveDistance(Second absTime, Meter ds)
-		{
-			var nextSpeedChanges = LookAhead(Constants.SimulationSettings.BrakeNextTargetDistance);
-			if (nextSpeedChanges.Count > 0 && !CurrentState.RequestToNextSamplePointDone) {
-				CurrentState.RequestToNextSamplePointDone = true;
-				Log.Debug("current distance is close to the next speed change: {0}",
-					nextSpeedChanges.First().Distance - PreviousState.Distance);
-				return new ResponseDrivingCycleDistanceExceeded {
-					Source = this,
-					MaxDistance = Constants.SimulationSettings.BrakeNextTargetDistance
-				};
-			}
-
-			CurrentState.WaitPhase = 0;
-			//CurrentState.Distance = PreviousState.Distance + ds;
-			CurrentState.SimulationDistance = ds;
-			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
-			CurrentState.Gradient = ComputeGradient(ds);
-
-			var retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
-			retVal.Switch()
-				.Case<ResponseFailTimeInterval>(
-					r => {
-						retVal = NextComponent.Request(absTime, r.DeltaT, 0.SI<MeterPerSecond>(), CurrentState.Gradient);
-						retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
-					});
-			CurrentState.AbsTime = absTime;
-			if (retVal is ResponseSuccess) {
-				CurrentState.Distance = PreviousState.Distance + retVal.SimulationDistance;
-			}
-			return retVal;
-		}
-
-		protected override void DoWriteModalResults(IModalDataContainer container)
-		{
-			container[ModalResultField.dist] = CurrentState.Distance; // (CurrentState.Distance + PreviousState.Distance) / 2.0;
-			container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
-			container[ModalResultField.v_targ] = CurrentState.VehicleTargetSpeed;
-			container[ModalResultField.grad] = (Math.Tan(CurrentState.Gradient.Value()) * 100).SI<Scalar>();
-			container[ModalResultField.altitude] = CurrentState.Altitude;
-
-			if (IdleController != null) {
-				IdleController.CommitSimulationStep(container);
-			}
-		}
-
-		protected override void DoCommitSimulationStep()
-		{
-			if (!(CurrentState.Response is ResponseSuccess)) {
-				throw new VectoSimulationException("Previous request did not succeed!");
-			}
-
-			PreviousState = CurrentState;
-			CurrentState = CurrentState.Clone();
-			_intervalProlonged = false;
-
-			var stopTime = Left.PTOActive && IdleController != null
-				? Left.StoppingTime + IdleController.Duration
-				: Left.StoppingTime;
-
-			if (!stopTime.IsEqual(0) && stopTime.IsEqual(PreviousState.WaitTime)) {
-				// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
-				if (IdleController != null) {
-					IdleController.ActivateIdle();
-				}
-				CycleIntervalIterator.MoveNext();
-			}
-
-			stopTime = Left.PTOActive && IdleController != null ? Left.StoppingTime + IdleController.Duration : Left.StoppingTime;
-
-			// separately test for equality and greater than to have tolerance for equality comparison
-			if (stopTime.IsEqual(0)) {
-				while (stopTime.IsEqual(0) && CurrentState.Distance.IsGreaterOrEqual(Right.Distance) &&
-						!CycleIntervalIterator.LastEntry) {
-					// we have reached the end of the current interval in the cycle, move on...
-					CycleIntervalIterator.MoveNext();
-
-					stopTime = Left.PTOActive && IdleController != null
-						? Left.StoppingTime + IdleController.Duration
-						: Left.StoppingTime;
-				}
-			} else {
-				if (stopTime.IsEqual(PreviousState.WaitTime)) {
-					// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
-					if (IdleController != null) {
-						IdleController.ActivateIdle();
-					}
-					CycleIntervalIterator.MoveNext();
-				}
-			}
-		}
-
-		private Radian ComputeGradient(Meter ds)
-		{
-			var cycleIterator = CycleIntervalIterator.Clone();
-			while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && !cycleIterator.LastEntry) {
-				cycleIterator.MoveNext();
-			}
-			var leftSamplePoint = cycleIterator.LeftSample;
-			var rightSamplePoint = cycleIterator.RightSample;
-
-			if (leftSamplePoint.Distance.IsEqual(rightSamplePoint.Distance)) {
-				return leftSamplePoint.RoadGradient;
-			}
-			if (ds.IsEqual(0.SI<Meter>())) {
-				return leftSamplePoint.RoadGradient;
-			}
-			CurrentState.Altitude = VectoMath.Interpolate(leftSamplePoint.Distance, rightSamplePoint.Distance,
-				leftSamplePoint.Altitude, rightSamplePoint.Altitude, PreviousState.Distance + ds);
-
-			var gradient = VectoMath.InclinationToAngle(((CurrentState.Altitude - PreviousState.Altitude) /
-														ds).Value());
-			//return 0.SI<Radian>();
-			return gradient;
-		}
-
-		private Meter GetSpeedChangeWithinSimulationInterval(Meter ds)
-		{
-			var leftSamplePoint = Left;
-			var cycleIterator = CycleIntervalIterator.Clone();
-
-			do {
-				if (!leftSamplePoint.VehicleTargetSpeed.IsEqual(cycleIterator.RightSample.VehicleTargetSpeed)) {
-					return cycleIterator.RightSample.Distance;
-				}
-			} while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && cycleIterator.MoveNext());
-			if (cycleIterator.LastEntry) {
-				return cycleIterator.RightSample.Distance;
-			}
-			return null;
-		}
-
-		/// <summary>
-		/// Progress of the distance in the driving cycle.
-		/// </summary>
-		public double Progress
-		{
-			get {
-				return Data.Entries.Count > 0
-					? (CurrentState.Distance.Value() - Data.Entries.First().Distance.Value()) /
-					(Data.Entries.Last().Distance.Value() - Data.Entries.First().Distance.Value())
-					: 0;
-			}
-		}
-
-		public Meter CycleStartDistance { get; internal set; }
-
-		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance)
-		{
-			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
-
-			var cycleIterator = CycleIntervalIterator.Clone();
-			var velocity = cycleIterator.LeftSample.VehicleTargetSpeed;
-
-			do {
-				if (cycleIterator.RightSample.VehicleTargetSpeed.IsEqual(velocity)) {
-					continue;
-				}
-				var lookaheadEntry = retVal.Find(x => x.Distance == cycleIterator.RightSample.Distance);
-				if (lookaheadEntry != null) {
-					// an entry may occur twice when vehicle stops (one entry with v=0 and the other with drive on after stop)
-					// only use the one with min. speed
-					if (cycleIterator.RightSample.VehicleTargetSpeed < lookaheadEntry.VehicleTargetSpeed) {
-						retVal.Remove(lookaheadEntry);
-						retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
-					}
-				} else {
-					retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
-				}
-				velocity = cycleIterator.RightSample.VehicleTargetSpeed;
-				if (velocity.IsEqual(0.KMPHtoMeterPerSecond())) {
-					// do not look beyond vehicle stop
-					break;
-				}
-			} while (cycleIterator.MoveNext() && cycleIterator.RightSample.Distance < PreviousState.Distance + lookaheadDistance);
-			if (retVal.Count > 0) {
-				retVal = retVal.Where(x => x.Distance <= PreviousState.Distance + lookaheadDistance).ToList();
-				retVal.Sort((x, y) => x.Distance.CompareTo(y.Distance));
-			}
-			return retVal;
-		}
-
-		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
-		{
-			return LookAhead(LookaheadTimeSafetyMargin * DataBus.VehicleSpeed * time);
-		}
-
-		public void FinishSimulation()
-		{
-			Data.Finish();
-		}
-
-		public CycleData CycleData
-		{
-			get {
-				return new CycleData {
-					AbsTime = CurrentState.AbsTime,
-					AbsDistance = CurrentState.Distance,
-					LeftSample = Left,
-					RightSample = CycleIntervalIterator.RightSample
-				};
-			}
-		}
-
-		public bool PTOActive { get; private set; }
-
-		public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
-		{
-			var absDistance = CurrentState.Distance + distance;
-			var myIterator = CycleIntervalIterator.Clone();
-
-			if (absDistance > Data.Entries.Last().Distance) {
-				return ExtrapolateCycleEntry(absDistance, Data.Entries.Last());
-			}
-			while (myIterator.RightSample.Distance < absDistance) {
-				myIterator.MoveNext();
-			}
-
-			return InterpolateCycleEntry(absDistance, myIterator.RightSample);
-		}
-
-		private DrivingCycleData.DrivingCycleEntry InterpolateCycleEntry(Meter absDistance,
-			DrivingCycleData.DrivingCycleEntry lookahead)
-		{
-			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
-				Distance = absDistance,
-				Altitude = VectoMath.Interpolate(CurrentState.Distance, lookahead.Distance, CurrentState.Altitude,
-					lookahead.Altitude, absDistance)
-			};
-
-			retVal.RoadGradient =
-				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
-
-			return retVal;
-		}
-
-		private DrivingCycleData.DrivingCycleEntry ExtrapolateCycleEntry(Meter absDistance,
-			DrivingCycleData.DrivingCycleEntry lookahead)
-		{
-			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
-				Distance = absDistance,
-				Altitude = lookahead.Altitude + lookahead.RoadGradient * (absDistance - lookahead.Distance),
-			};
-
-			retVal.RoadGradient =
-				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
-
-			return retVal;
-		}
-
-		public Meter Altitude
-		{
-			get { return PreviousState.Altitude; }
-		}
-
-		public sealed class DrivingCycleState
-		{
-			public DrivingCycleState Clone()
-			{
-				return new DrivingCycleState {
-					AbsTime = AbsTime,
-					Distance = Distance,
-					VehicleTargetSpeed = VehicleTargetSpeed,
-					Altitude = Altitude,
-					WaitPhase = WaitPhase,
-					// WaitTime is not cloned on purpose!
-					WaitTime = 0.SI<Second>(),
-					Response = null
-				};
-			}
-
-			public Second AbsTime;
-
-			public Meter Distance;
-
-			public Second WaitTime;
-
-			public uint WaitPhase;
-
-			public MeterPerSecond VehicleTargetSpeed;
-
-			public Meter Altitude;
-
-			public Radian Gradient;
-
-			public IResponse Response;
-
-			public bool RequestToNextSamplePointDone;
-
-			public Meter SimulationDistance;
-		}
-
-		public void Dispose()
-		{
-			CycleIntervalIterator.Dispose();
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Connector.Ports;
+using TUGraz.VectoCore.Models.Connector.Ports.Impl;
+using TUGraz.VectoCore.Models.Simulation;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.Utils;
+
+namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
+{
+	/// <summary>
+	///     Class representing one Distance Based Driving Cycle
+	/// </summary>
+	public sealed class DistanceBasedDrivingCycle : StatefulProviderComponent
+		<DistanceBasedDrivingCycle.DrivingCycleState, ISimulationOutPort, IDrivingCycleInPort, IDrivingCycleOutPort>,
+		IDrivingCycle, ISimulationOutPort, IDrivingCycleInPort, IDisposable
+	{
+		private const double LookaheadTimeSafetyMargin = 1.5;
+		internal readonly IDrivingCycleData Data;
+		internal readonly DrivingCycleEnumerator CycleIntervalIterator;
+		private bool _intervalProlonged;
+		internal IdleControllerSwitcher IdleController;
+
+		private DrivingCycleData.DrivingCycleEntry Left
+		{
+			get { return CycleIntervalIterator.LeftSample; }
+		}
+
+		private DrivingCycleData.DrivingCycleEntry Right
+		{
+			get { return CycleIntervalIterator.RightSample; }
+		}
+
+		public DistanceBasedDrivingCycle(IVehicleContainer container, IDrivingCycleData cycle) : base(container)
+		{
+			Data = cycle;
+			CycleIntervalIterator = new DrivingCycleEnumerator(Data);
+			CycleStartDistance = Data.Entries.Count > 0 ? Data.Entries.First().Distance : 0.SI<Meter>();
+
+			var first = Data.Entries.First();
+			PreviousState = new DrivingCycleState {
+				AbsTime = 0.SI<Second>(),
+				WaitTime = 0.SI<Second>(),
+				Distance = first.Distance,
+				Altitude = first.Altitude,
+			};
+			CurrentState = PreviousState.Clone();
+		}
+
+		public IResponse Initialize()
+		{
+			if (Left.VehicleTargetSpeed.IsEqual(0)) {
+				var retVal = NextComponent.Initialize(DataBus.StartSpeed,
+					Left.RoadGradient, DataBus.StartAcceleration);
+				if (!(retVal is ResponseSuccess)) {
+					throw new UnexpectedResponseException("DistanceBasedDrivingCycle.Initialize: Couldn't find start gear.", retVal);
+				}
+			}
+
+			return NextComponent.Initialize(Left.VehicleTargetSpeed,
+				Left.RoadGradient);
+		}
+
+		public IResponse Request(Second absTime, Second dt)
+		{
+			throw new NotImplementedException("Distance Based Driving Cycle does not support time requests.");
+		}
+
+		public IResponse Request(Second absTime, Meter ds)
+		{
+			if (Left.Distance.IsEqual(PreviousState.Distance.Value())) {
+				// we are exactly on an entry in the cycle.
+				var stopTime = Left.PTOActive && IdleController != null
+					? Left.StoppingTime + IdleController.Duration
+					: Left.StoppingTime;
+
+				if (stopTime.IsGreater(0) && PreviousState.WaitTime.IsSmaller(stopTime)) {
+					// stop for certain time unless we've already waited long enough ...
+
+					// we are stopping: ensure that velocity is 0.
+					if (!Left.VehicleTargetSpeed.IsEqual(0)) {
+						Log.Warn("Stopping Time requested in cycle but target-velocity not zero. distance: {0}, target speed: {1}",
+							Left.StoppingTime, Left.VehicleTargetSpeed);
+						throw new VectoSimulationException("Stopping Time only allowed when target speed is zero!");
+					}
+					var dt = GetStopTimeInterval();
+					if (dt == null) {
+						CurrentState.WaitPhase++;
+						dt = GetStopTimeInterval();
+					}
+					CurrentState.Response = DriveTimeInterval(absTime, dt);
+					return CurrentState.Response;
+				}
+			}
+			if (CycleIntervalIterator.LastEntry && PreviousState.Distance.IsEqual(Right.Distance)) {
+				CurrentState.Response = new ResponseCycleFinished();
+				return CurrentState.Response;
+			}
+
+			var nextSpeedChange = GetSpeedChangeWithinSimulationInterval(ds);
+			if (nextSpeedChange == null || ds.IsSmallerOrEqual(nextSpeedChange - PreviousState.Distance)) {
+				if (nextSpeedChange == null || DataBus.VehicleSpeed.IsEqual(0.SI<MeterPerSecond>())) {
+					CurrentState.Response = DriveDistance(absTime, ds);
+					return CurrentState.Response;
+				}
+				var remainingDistance = nextSpeedChange - PreviousState.Distance - ds;
+				var estimatedRemainingTime = remainingDistance / DataBus.VehicleSpeed;
+				if (_intervalProlonged || remainingDistance.IsEqual(0.SI<Meter>()) ||
+					estimatedRemainingTime.IsGreater(Constants.SimulationSettings.LowerBoundTimeInterval)) {
+					CurrentState.Response = DriveDistance(absTime, ds);
+					return CurrentState.Response;
+				}
+				Log.Debug("Extending distance by {0} to next sample point. ds: {1} new ds: {2}", remainingDistance, ds,
+					nextSpeedChange - PreviousState.Distance);
+				_intervalProlonged = true;
+				CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
+					Source = this,
+					MaxDistance = nextSpeedChange - PreviousState.Distance
+				};
+				return CurrentState.Response;
+			}
+			// only drive until next sample point in cycle with speed change
+			Log.Debug("Limiting distance to next sample point {0}",
+				Right.Distance - PreviousState.Distance);
+			CurrentState.Response = new ResponseDrivingCycleDistanceExceeded {
+				Source = this,
+				MaxDistance = nextSpeedChange - PreviousState.Distance
+			};
+			return CurrentState.Response;
+		}
+
+		private Second GetStopTimeInterval()
+		{
+			if (!Left.PTOActive || IdleController == null) {
+				return Left.StoppingTime.IsGreater(3 * Constants.SimulationSettings.TargetTimeInterval)
+					? GetStopTimeIntervalThreePhases()
+					: Left.StoppingTime;
+			}
+			if (Left.StoppingTime.IsGreater(6 * Constants.SimulationSettings.TargetTimeInterval)) {
+				// 7 phases
+				return GetStopTimeIntervalSevenPhasesPTO();
+			}
+			if (Left.StoppingTime.IsGreater(0)) {
+				// 3 phases
+				return GetStopTimeIntervalThreePhasesPTO();
+			}
+			// we have a pto cycle without stopping time.
+			IdleController.ActivatePTO();
+			return IdleController.GetNextCycleTime();
+		}
+
+		private Second GetStopTimeIntervalThreePhases()
+		{
+			switch (CurrentState.WaitPhase) {
+				case 1:
+				case 3:
+					CurrentState.WaitPhase++;
+					return Constants.SimulationSettings.TargetTimeInterval;
+				case 2:
+					CurrentState.WaitPhase++;
+					return Left.StoppingTime - 2 * Constants.SimulationSettings.TargetTimeInterval;
+			}
+			return null;
+		}
+
+		private Second GetStopTimeIntervalThreePhasesPTO()
+		{
+			switch (CurrentState.WaitPhase) {
+				case 1:
+				case 3:
+					CurrentState.WaitPhase++;
+					IdleController.ActivateIdle();
+					PTOActive = false;
+					return Left.StoppingTime / 2;
+				case 2:
+					PTOActive = true;
+					IdleController.ActivatePTO();
+					return IdleController.GetNextCycleTime();
+			}
+			return null;
+		}
+
+		private Second GetStopTimeIntervalSevenPhasesPTO()
+		{
+			switch (CurrentState.WaitPhase) {
+				case 1:
+				case 5:
+					CurrentState.WaitPhase++;
+					IdleController.ActivateIdle();
+					PTOActive = false;
+					return Constants.SimulationSettings.TargetTimeInterval;
+				case 3:
+				case 7:
+					CurrentState.WaitPhase++;
+					return Constants.SimulationSettings.TargetTimeInterval;
+				case 2:
+				case 6:
+					CurrentState.WaitPhase++;
+					return Left.StoppingTime / 2 - 2 * Constants.SimulationSettings.TargetTimeInterval;
+				case 4:
+					PTOActive = true;
+					IdleController.ActivatePTO();
+					return IdleController.GetNextCycleTime();
+			}
+			return null;
+		}
+
+		private IResponse DriveTimeInterval(Second absTime, Second dt)
+		{
+			CurrentState.AbsTime = absTime;
+			CurrentState.WaitTime = PreviousState.WaitTime + dt;
+			CurrentState.Gradient = ComputeGradient(0.SI<Meter>());
+			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
+
+			return NextComponent.Request(absTime, dt, Left.VehicleTargetSpeed, CurrentState.Gradient);
+		}
+
+		private IResponse DriveDistance(Second absTime, Meter ds)
+		{
+			var nextSpeedChanges = LookAhead(Constants.SimulationSettings.BrakeNextTargetDistance);
+			if (nextSpeedChanges.Count > 0 && !CurrentState.RequestToNextSamplePointDone) {
+				CurrentState.RequestToNextSamplePointDone = true;
+				Log.Debug("current distance is close to the next speed change: {0}",
+					nextSpeedChanges.First().Distance - PreviousState.Distance);
+				return new ResponseDrivingCycleDistanceExceeded {
+					Source = this,
+					MaxDistance = Constants.SimulationSettings.BrakeNextTargetDistance
+				};
+			}
+
+			CurrentState.WaitPhase = 0;
+			//CurrentState.Distance = PreviousState.Distance + ds;
+			CurrentState.SimulationDistance = ds;
+			CurrentState.VehicleTargetSpeed = Left.VehicleTargetSpeed;
+			CurrentState.Gradient = ComputeGradient(ds);
+
+			var retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
+			retVal.Switch()
+				.Case<ResponseFailTimeInterval>(
+					r => {
+						retVal = NextComponent.Request(absTime, r.DeltaT, 0.SI<MeterPerSecond>(), CurrentState.Gradient);
+						retVal = NextComponent.Request(absTime, ds, CurrentState.VehicleTargetSpeed, CurrentState.Gradient);
+					});
+			CurrentState.AbsTime = absTime;
+			if (retVal is ResponseSuccess) {
+				CurrentState.Distance = PreviousState.Distance + retVal.SimulationDistance;
+			}
+			return retVal;
+		}
+
+		protected override void DoWriteModalResults(IModalDataContainer container)
+		{
+			container[ModalResultField.dist] = CurrentState.Distance; // (CurrentState.Distance + PreviousState.Distance) / 2.0;
+			container[ModalResultField.simulationDistance] = CurrentState.SimulationDistance;
+			container[ModalResultField.v_targ] = CurrentState.VehicleTargetSpeed;
+			container[ModalResultField.grad] = (Math.Tan(CurrentState.Gradient.Value()) * 100).SI<Scalar>();
+			container[ModalResultField.altitude] = CurrentState.Altitude;
+
+			if (IdleController != null) {
+				IdleController.CommitSimulationStep(container);
+			}
+		}
+
+		protected override void DoCommitSimulationStep()
+		{
+			if (!(CurrentState.Response is ResponseSuccess)) {
+				throw new VectoSimulationException("Previous request did not succeed!");
+			}
+
+			PreviousState = CurrentState;
+			CurrentState = CurrentState.Clone();
+			_intervalProlonged = false;
+
+			//var stopTime = Left.PTOActive && IdleController != null
+			//	? Left.StoppingTime + IdleController.Duration
+			//	: Left.StoppingTime;
+
+			//if (!stopTime.IsEqual(0) && stopTime.IsEqual(PreviousState.WaitTime)) {
+			//	// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
+			//	if (IdleController != null) {
+			//		IdleController.ActivateIdle();
+			//	}
+			//	CycleIntervalIterator.MoveNext();
+			//}
+
+			var stopTime = Left.PTOActive && IdleController != null
+				? Left.StoppingTime + IdleController.Duration
+				: Left.StoppingTime;
+
+			// separately test for equality and greater than to have tolerance for equality comparison
+			if (stopTime.IsEqual(0)) {
+				while (stopTime.IsEqual(0) && CurrentState.Distance.IsGreaterOrEqual(Right.Distance) &&
+						!CycleIntervalIterator.LastEntry) {
+					// we have reached the end of the current interval in the cycle, move on...
+					CycleIntervalIterator.MoveNext();
+
+					stopTime = Left.PTOActive && IdleController != null
+						? Left.StoppingTime + IdleController.Duration
+						: Left.StoppingTime;
+				}
+			} else {
+				if (stopTime.IsEqual(PreviousState.WaitTime)) {
+					// we needed to stop at the current interval in the cycle and have already waited enough time, move on..
+					if (IdleController != null) {
+						IdleController.ActivateIdle();
+					}
+					CycleIntervalIterator.MoveNext();
+				}
+			}
+		}
+
+		private Radian ComputeGradient(Meter ds)
+		{
+			var cycleIterator = CycleIntervalIterator.Clone();
+			while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && !cycleIterator.LastEntry) {
+				cycleIterator.MoveNext();
+			}
+			var leftSamplePoint = cycleIterator.LeftSample;
+			var rightSamplePoint = cycleIterator.RightSample;
+
+			if (leftSamplePoint.Distance.IsEqual(rightSamplePoint.Distance)) {
+				return leftSamplePoint.RoadGradient;
+			}
+			if (ds.IsEqual(0.SI<Meter>())) {
+				return leftSamplePoint.RoadGradient;
+			}
+			CurrentState.Altitude = VectoMath.Interpolate(leftSamplePoint.Distance, rightSamplePoint.Distance,
+				leftSamplePoint.Altitude, rightSamplePoint.Altitude, PreviousState.Distance + ds);
+
+			var gradient = VectoMath.InclinationToAngle(((CurrentState.Altitude - PreviousState.Altitude) /
+														ds).Value());
+			//return 0.SI<Radian>();
+			return gradient;
+		}
+
+		private Meter GetSpeedChangeWithinSimulationInterval(Meter ds)
+		{
+			var leftSamplePoint = Left;
+			var cycleIterator = CycleIntervalIterator.Clone();
+
+			do {
+				if (!leftSamplePoint.VehicleTargetSpeed.IsEqual(cycleIterator.RightSample.VehicleTargetSpeed)) {
+					return cycleIterator.RightSample.Distance;
+				}
+			} while (cycleIterator.RightSample.Distance < PreviousState.Distance + ds && cycleIterator.MoveNext());
+			if (cycleIterator.LastEntry) {
+				return cycleIterator.RightSample.Distance;
+			}
+			return null;
+		}
+
+		/// <summary>
+		/// Progress of the distance in the driving cycle.
+		/// </summary>
+		public double Progress
+		{
+			get {
+				return Data.Entries.Count > 0
+					? (CurrentState.Distance.Value() - Data.Entries.First().Distance.Value()) /
+					(Data.Entries.Last().Distance.Value() - Data.Entries.First().Distance.Value())
+					: 0;
+			}
+		}
+
+		public Meter CycleStartDistance { get; internal set; }
+
+		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Meter lookaheadDistance)
+		{
+			var retVal = new List<DrivingCycleData.DrivingCycleEntry>();
+
+			var cycleIterator = CycleIntervalIterator.Clone();
+			var velocity = cycleIterator.LeftSample.VehicleTargetSpeed;
+
+			do {
+				if (cycleIterator.RightSample.VehicleTargetSpeed.IsEqual(velocity)) {
+					continue;
+				}
+				var lookaheadEntry = retVal.Find(x => x.Distance == cycleIterator.RightSample.Distance);
+				if (lookaheadEntry != null) {
+					// an entry may occur twice when vehicle stops (one entry with v=0 and the other with drive on after stop)
+					// only use the one with min. speed
+					if (cycleIterator.RightSample.VehicleTargetSpeed < lookaheadEntry.VehicleTargetSpeed) {
+						retVal.Remove(lookaheadEntry);
+						retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
+					}
+				} else {
+					retVal.Add(cycleIterator.RightSample); // TODO: MQ 2016-05-13: use clone of iterator here?
+				}
+				velocity = cycleIterator.RightSample.VehicleTargetSpeed;
+				if (velocity.IsEqual(0.KMPHtoMeterPerSecond())) {
+					// do not look beyond vehicle stop
+					break;
+				}
+			} while (cycleIterator.MoveNext() && cycleIterator.RightSample.Distance < PreviousState.Distance + lookaheadDistance);
+			if (retVal.Count > 0) {
+				retVal = retVal.Where(x => x.Distance <= PreviousState.Distance + lookaheadDistance).ToList();
+				retVal.Sort((x, y) => x.Distance.CompareTo(y.Distance));
+			}
+			return retVal;
+		}
+
+		public IReadOnlyList<DrivingCycleData.DrivingCycleEntry> LookAhead(Second time)
+		{
+			return LookAhead(LookaheadTimeSafetyMargin * DataBus.VehicleSpeed * time);
+		}
+
+		public void FinishSimulation()
+		{
+			Data.Finish();
+		}
+
+		public CycleData CycleData
+		{
+			get {
+				return new CycleData {
+					AbsTime = CurrentState.AbsTime,
+					AbsDistance = CurrentState.Distance,
+					LeftSample = Left,
+					RightSample = CycleIntervalIterator.RightSample
+				};
+			}
+		}
+
+		public bool PTOActive { get; private set; }
+
+		public DrivingCycleData.DrivingCycleEntry CycleLookAhead(Meter distance)
+		{
+			var absDistance = CurrentState.Distance + distance;
+			var myIterator = CycleIntervalIterator.Clone();
+
+			if (absDistance > Data.Entries.Last().Distance) {
+				return ExtrapolateCycleEntry(absDistance, Data.Entries.Last());
+			}
+			while (myIterator.RightSample.Distance < absDistance) {
+				myIterator.MoveNext();
+			}
+
+			return InterpolateCycleEntry(absDistance, myIterator.RightSample);
+		}
+
+		private DrivingCycleData.DrivingCycleEntry InterpolateCycleEntry(Meter absDistance,
+			DrivingCycleData.DrivingCycleEntry lookahead)
+		{
+			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
+				Distance = absDistance,
+				Altitude = VectoMath.Interpolate(CurrentState.Distance, lookahead.Distance, CurrentState.Altitude,
+					lookahead.Altitude, absDistance)
+			};
+
+			retVal.RoadGradient =
+				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
+
+			return retVal;
+		}
+
+		private DrivingCycleData.DrivingCycleEntry ExtrapolateCycleEntry(Meter absDistance,
+			DrivingCycleData.DrivingCycleEntry lookahead)
+		{
+			var retVal = new DrivingCycleData.DrivingCycleEntry(lookahead) {
+				Distance = absDistance,
+				Altitude = lookahead.Altitude + lookahead.RoadGradient * (absDistance - lookahead.Distance),
+			};
+
+			retVal.RoadGradient =
+				((retVal.Altitude - CurrentState.Altitude) / (absDistance - CurrentState.Distance)).Value().SI<Radian>();
+
+			return retVal;
+		}
+
+		public Meter Altitude
+		{
+			get { return PreviousState.Altitude; }
+		}
+
+		public sealed class DrivingCycleState
+		{
+			public DrivingCycleState Clone()
+			{
+				return new DrivingCycleState {
+					AbsTime = AbsTime,
+					Distance = Distance,
+					VehicleTargetSpeed = VehicleTargetSpeed,
+					Altitude = Altitude,
+					WaitPhase = WaitPhase,
+					// WaitTime is not cloned on purpose!
+					WaitTime = 0.SI<Second>(),
+					Response = null
+				};
+			}
+
+			public Second AbsTime;
+
+			public Meter Distance;
+
+			public Second WaitTime;
+
+			public uint WaitPhase;
+
+			public MeterPerSecond VehicleTargetSpeed;
+
+			public Meter Altitude;
+
+			public Radian Gradient;
+
+			public IResponse Response;
+
+			public bool RequestToNextSamplePointDone;
+
+			public Meter SimulationDistance;
+		}
+
+		public void Dispose()
+		{
+			CycleIntervalIterator.Dispose();
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
index 622d04724afe278f28bc7f2c170bcca68dc41f9a..d58d0a42cb7b122f4016ac40b118223eb777387f 100644
--- a/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/IModalDataContainer.cs
@@ -29,529 +29,529 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.DataBus;
-using TUGraz.VectoCore.Models.Simulation.Impl;
-
-namespace TUGraz.VectoCore.OutputData
-{
-	public interface IModalDataFilter
-	{
-		ModalResults Filter(ModalResults data);
-		string ID { get; }
-	}
-
-	public interface IModalDataContainer
-	{
-		/// <summary>
-		/// Indexer for fields of the DataWriter. Accesses the data of the current step.
-		/// </summary>
-		/// <param name="key"></param>
-		/// <returns></returns>
-		object this[ModalResultField key] { get; set; }
-
-		/// <summary>
-		/// Indexer for auxiliary fields of the DataWriter.
-		/// </summary>
-		/// <param name="auxId"></param>
-		/// <returns></returns>
-		object this[string auxId] { get; set; }
-
-		bool HasTorqueConverter { set; }
-
-		/// <summary>
-		/// Commits the data of the current simulation step.
-		/// </summary>
-		void CommitSimulationStep();
-
-		FuelData.Entry FuelData { get; }
-
-		VectoRun.Status RunStatus { get; }
-
-		string Error { get; }
-
-		string StackTrace { get; }
-
-		/// <summary>
-		/// Finishes the writing of the DataWriter.
-		/// </summary>
-		void Finish(VectoRun.Status runStatus);
-
-		IEnumerable<T> GetValues<T>(ModalResultField key);
-
-		IEnumerable<T> GetValues<T>(DataColumn col);
-
-		IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc);
-
-		Dictionary<string, DataColumn> Auxiliaries { get; }
-
-		T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T>;
-
-		void SetDataValue(string fieldName, object value);
-
-		void AddAuxiliary(string id, string columnName = null);
-
-		/// <summary>
-		/// clear the modal data after the simulation
-		/// called after the simulation is finished and the sum-entries have been written
-		/// </summary>
-		/// <param name="exception"></param>
-		void FinishSimulation(Exception exception = null);
-	}
-
-	public static class ModalDataContainerExtensions
-	{
-		public static T Max<T>(this IModalDataContainer data, ModalResultField field)
-		{
-			return data.GetValues<T>(field).Max();
-		}
-
-		public static T Min<T>(this IModalDataContainer data, ModalResultField field)
-		{
-			return data.GetValues<T>(field).Min();
-		}
-
-		/// <summary>
-		/// Returns a default value if the SI object is null.
-		/// </summary>
-		/// <typeparam name="T">The SI Type.</typeparam>
-		/// <param name="self">The SI Instance.</param>
-		/// <param name="defaultValue">The default value.</param>
-		/// <returns>If self is null, the default value as SI-Type is returned. Otherwise self is returned.</returns>
-		/// <code>
-		/// NewtonMeter t = null;
-		/// var x = t.DefaultIfNull(0);
-		/// </code>
-		public static T DefaultIfNull<T>(this T self, double defaultValue) where T : SIBase<T>
-		{
-			return self ?? defaultValue.SI<T>();
-		}
-
-		public static MeterPerSquareSecond AccelerationsPositive(this IModalDataContainer data)
-		{
-			return data.GetValues<MeterPerSquareSecond>(ModalResultField.acc)
-				.Where(x => x > 0.125)
-				.DefaultIfEmpty(0.SI<MeterPerSquareSecond>())
-				.Average();
-		}
-
-		public static MeterPerSquareSecond AccelerationsNegative(this IModalDataContainer data)
-		{
-			return data.GetValues<MeterPerSquareSecond>(ModalResultField.acc)
-				.Where(x => x < -0.125)
-				.DefaultIfEmpty(0.SI<MeterPerSquareSecond>())
-				.Average();
-		}
-
-		public static Scalar AccelerationTimeShare(this IModalDataContainer data)
-		{
-			var accelerationTimeShare = data.GetValues(x => new {
-				a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			})
-				.Sum(x => x.a > 0.125 ? x.dt : 0.SI<Second>()).DefaultIfNull(0);
-			return 100 * (accelerationTimeShare / data.Duration()).Cast<Scalar>();
-		}
-
-		public static Scalar DecelerationTimeShare(this IModalDataContainer data)
-		{
-			var decelerationTimeShare = data.GetValues(x => new {
-				a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			})
-				.Sum(x => x.a < -0.125 ? x.dt : 0.SI<Second>()).DefaultIfNull(0);
-			return 100 * (decelerationTimeShare / data.Duration()).Cast<Scalar>();
-		}
-
-		public static Scalar CruiseTimeShare(this IModalDataContainer data)
-		{
-			var cruiseTime = data.GetValues(x => new {
-				v = x.Field<MeterPerSecond>((int)ModalResultField.v_act).DefaultIfNull(0),
-				a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			})
-				.Sum(x => x.v >= 0.1.KMPHtoMeterPerSecond() && x.a.IsBetween(-0.125, 0.125) ? x.dt : 0.SI<Second>())
-				.DefaultIfNull(0);
-			return 100 * (cruiseTime / data.Duration()).Cast<Scalar>();
-		}
-
-		public static Scalar StopTimeShare(this IModalDataContainer data)
-		{
-			var stopTime = data.GetValues(x => new {
-				v = x.Field<MeterPerSecond>((int)ModalResultField.v_act).DefaultIfNull(0),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			})
-				.Sum(x => x.v < 0.1.KMPHtoMeterPerSecond() ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
-			return 100 * (stopTime / data.Duration()).Cast<Scalar>();
-		}
-
-		public static MeterPerSquareSecond AccelerationAverage(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<MeterPerSecond>(ModalResultField.acc) / data.Duration();
-		}
-
-		public static Meter AltitudeDelta(this IModalDataContainer data)
-		{
-			var altitudes = data.GetValues<Meter>(ModalResultField.altitude).ToList();
-			var first = altitudes.First();
-			var last = altitudes.Last();
-			return first == null || last == null ? null : last - first;
-		}
-
-		public static WattSecond PowerAccelerations(this IModalDataContainer data)
-		{
-			var paEngine = data.TimeIntegral<WattSecond>(ModalResultField.P_eng_inertia);
-			var paGearbox = data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_inertia);
-			return paEngine + paGearbox;
-		}
-
-		public static WattSecond WorkClutch(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_clutch_loss);
-		}
-
-		public static WattSecond WorkGearshift(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_shift_loss);
-		}
-
-		public static WattSecond WorkGearbox(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_loss);
-		}
-
-		public static WattSecond WorkAxlegear(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_axle_loss);
-		}
-
-		public static WattSecond WorkRetarder(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_ret_loss);
-		}
-
-		public static WattSecond WorkAngledrive(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_angle_loss);
-		}
-
-		public static WattSecond WorkTorqueConverter(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_TC_loss);
-		}
-
-		public static Second Duration(this IModalDataContainer data)
-		{
-			var time = data.GetValues<Second>(ModalResultField.time).ToList();
-			var dt = data.GetValues<Second>(ModalResultField.simulationInterval).ToList();
-			if (time.Count == 1) {
-				return time.First();
-			}
-			return time.Max() - time.Min() + dt.First() / 2 + dt.Last() / 2;
-		}
-
-		public static Meter Distance(this IModalDataContainer data)
-		{
-			var max = data.Max<Meter>(ModalResultField.dist);
-			var min = data.Min<Meter>(ModalResultField.dist);
-			return max == null || min == null ? null : max - min;
-		}
-
-		public static WattSecond WorkTotalMechanicalBrake(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_brake_loss);
-		}
-
-		public static WattSecond WorkVehicleInertia(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_veh_inertia) +
-					data.TimeIntegral<WattSecond>(ModalResultField.P_wheel_inertia);
-		}
-
-		public static WattSecond WorkAuxiliaries(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_aux);
-		}
-
-		public static WattSecond WorkRoadGradientResistance(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_slope);
-		}
-
-		public static WattSecond WorkRollingResistance(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_roll);
-		}
-
-		public static WattSecond WorkAirResistance(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_air);
-		}
-
-
-		public static WattSecond TotalEngineWorkPositive(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_eng_fcmap, x => x > 0);
-		}
-
-		public static WattSecond TotalEngineWorkNegative(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_eng_fcmap, x => x < 0);
-		}
-
-		public static Watt PowerWheelPositive(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<WattSecond>(ModalResultField.P_wheel_in, x => x > 0) / data.Duration();
-		}
-
-		public static KilogramPerMeter FuelConsumptionWHTC(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / distance;
-		}
-
-		public static KilogramPerSecond FuelConsumptionWHTCPerSecond(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / data.Duration();
-		}
-
-		public static KilogramPerMeter FuelConsumptionAuxStartStop(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCAUXc) / distance;
-		}
-
-		public static KilogramPerSecond FuelConsumptionAAUXPerSecond(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCAAUX) / data.Duration();
-		}
-
-		public static KilogramPerMeter FuelConsumptionAAUX(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCAAUX) / distance;
-		}
-
-		public static KilogramPerSecond FuelConsumptionAuxStartStopPerSecond(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCAUXc) / data.Duration();
-		}
-
-		public static KilogramPerSecond FuelConsumptionFinalPerSecond(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) / data.Duration();
-		}
-
-		public static KilogramPerMeter FuelConsumptionFinal(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) / distance;
-		}
-
-		public static SI FuelConsumptionFinalLiterPer100Kilometer(this IModalDataContainer data)
-		{
-			var fuelConsumptionFinal = data.FuelConsumptionFinal();
-			if (fuelConsumptionFinal == null || data.FuelData.FuelDensity == null) {
-				return null;
-			}
-
-			var fcVolumePerMeter = fuelConsumptionFinal / data.FuelData.FuelDensity;
-			return fcVolumePerMeter.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter;
-		}
-
-		public static KilogramPerMeter CO2PerMeter(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * data.FuelData.CO2PerFuelWeight / distance;
-		}
-
-		public static JoulePerMeter EnergyPerMeter(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * data.FuelData.LowerHeatingValue / distance;
-		}
-
-		public static KilogramPerSecond FCMapPerSecond(this IModalDataContainer data)
-		{
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) / data.Duration();
-		}
-
-		public static KilogramPerMeter FCMapPerMeter(this IModalDataContainer data)
-		{
-			var distance = data.Distance();
-			if (distance == null || distance.IsEqual(0)) {
-				return null;
-			}
-			return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) / distance;
-		}
-
-
-		public static Watt TotalPowerEnginePositiveAverage(this IModalDataContainer data)
-		{
-			var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval);
-			var values = data.GetValues<Watt>(ModalResultField.P_eng_fcmap)
-				.Zip(simulationIntervals, (value, dt) => new { Dt = dt, Value = value * dt })
-				.Where(v => v.Value > 0).ToList();
-			if (values.Any()) {
-				return values.Sum(v => v.Value) / Duration(data);
-			}
-			return 0.SI<Watt>();
-		}
-
-		public static MeterPerSecond Speed(this IModalDataContainer data)
-		{
-			var distance = Distance(data);
-			var duration = Duration(data);
-			if (distance == null || duration == null || duration.IsEqual(0)) {
-				return null;
-			}
-			return distance / duration;
-		}
-
-		public static WattSecond AuxiliaryWork(this IModalDataContainer data, DataColumn auxCol)
-		{
-			var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval).ToArray();
-			var auxValues = data.GetValues<Watt>(auxCol).ToArray();
-			var sum = 0.SI<WattSecond>();
-			for (var i = 0; i < simulationIntervals.Length; i++) {
-				if (auxValues[i] != null && simulationIntervals[i] != null) {
-					sum += auxValues[i] * simulationIntervals[i];
-				}
-			}
-			return sum;
-		}
-
-
-		public static MeterPerSecond MaxSpeed(this IModalDataContainer data)
-		{
-			return data.Max<MeterPerSecond>(ModalResultField.v_act).DefaultIfNull(0);
-		}
-
-		public static MeterPerSecond MinSpeed(this IModalDataContainer data)
-		{
-			return data.Min<MeterPerSecond>(ModalResultField.v_act).DefaultIfNull(0);
-		}
-
-		public static MeterPerSquareSecond MaxAcceleration(this IModalDataContainer data)
-		{
-			return data.Max<MeterPerSquareSecond>(ModalResultField.acc).DefaultIfNull(0);
-		}
-
-		public static MeterPerSquareSecond MaxDeceleration(this IModalDataContainer data)
-		{
-			return -data.Min<MeterPerSquareSecond>(ModalResultField.acc).DefaultIfNull(0);
-		}
-
-		public static PerSecond AvgEngineSpeed(this IModalDataContainer data)
-		{
-			var integral = data.GetValues(x => x.Field<PerSecond>((int)ModalResultField.n_eng_avg).Value() *
-												x.Field<Second>((int)ModalResultField.simulationInterval).Value()).Sum();
-			return (integral / Duration(data).Value()).SI<PerSecond>();
-		}
-
-		public static PerSecond MaxEngineSpeed(this IModalDataContainer data)
-		{
-			return data.Max<PerSecond>(ModalResultField.n_eng_avg);
-		}
-
-		public static Scalar EngineMaxLoadTimeShare(this IModalDataContainer data)
-		{
-			var sum = data.GetValues(x => new {
-				tMax = x.Field<NewtonMeter>((int)ModalResultField.Tq_full).DefaultIfNull(-1),
-				tEng = x.Field<NewtonMeter>((int)ModalResultField.T_eng_fcmap).DefaultIfNull(0),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			}).Sum(x => x.tMax.IsEqual(x.tEng, 5.SI<NewtonMeter>()) ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
-			return 100 * sum / Duration(data);
-		}
-
-		public static Scalar GearshiftCount(this IModalDataContainer data)
-		{
-			var prevGear = data.GetValues<uint>(ModalResultField.Gear).First();
-			var gearCount = 0;
-
-			data.GetValues(x => {
-				var gear = x.Field<uint>((int)ModalResultField.Gear);
-				var speed = x.Field<MeterPerSecond>((int)ModalResultField.v_act);
-				if (speed != null && speed.IsSmallerOrEqual(0.1)) {
-					prevGear = 0;
-					gearCount++;
-					return gear; // not used
-				}
-				if (gear == 0 || gear == prevGear) {
-					return gear; // not used
-				}
-				gearCount++;
-				prevGear = gear;
-				return gear; // not used
-			});
-			return gearCount.SI<Scalar>();
-		}
-
-		public static Scalar CoastingTimeShare(this IModalDataContainer data)
-		{
-			var sum = data.GetValues(x => new {
-				DrivingBehavior = x.Field<DrivingBehavior>((int)ModalResultField.drivingBehavior),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			})
-				.Sum(x => x.DrivingBehavior == DrivingBehavior.Coasting ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
-			return 100 * sum / Duration(data);
-		}
-
-		public static Scalar BrakingTimeShare(this IModalDataContainer data)
-		{
-			var sum = data.GetValues(x => new {
-				DrivingBehavior = x.Field<DrivingBehavior>((int)ModalResultField.drivingBehavior),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			})
-				.Sum(x => x.DrivingBehavior == DrivingBehavior.Braking ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
-			return 100 * sum / Duration(data);
-		}
-
-		public static Dictionary<uint, Scalar> TimeSharePerGear(this IModalDataContainer data, uint gearCount)
-		{
-			var retVal = new Dictionary<uint, Scalar>();
-			for (uint i = 0; i <= gearCount; i++) {
-				retVal[i] = 0.SI<Scalar>();
-			}
-
-			var gearData = data.GetValues(x => new {
-				Gear = x.Field<uint>((int)ModalResultField.Gear),
-				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
-			});
-
-			foreach (var entry in gearData) {
-				retVal[entry.Gear] += entry.dt.Value();
-			}
-
-			var duration = Duration(data).Value();
-			for (uint i = 0; i <= gearCount; i++) {
-				retVal[i] = 100 * retVal[i] / duration;
-			}
-			return retVal;
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.DataBus;
+using TUGraz.VectoCore.Models.Simulation.Impl;
+
+namespace TUGraz.VectoCore.OutputData
+{
+	public interface IModalDataFilter
+	{
+		ModalResults Filter(ModalResults data);
+		string ID { get; }
+	}
+
+	public interface IModalDataContainer
+	{
+		/// <summary>
+		/// Indexer for fields of the DataWriter. Accesses the data of the current step.
+		/// </summary>
+		/// <param name="key"></param>
+		/// <returns></returns>
+		object this[ModalResultField key] { get; set; }
+
+		/// <summary>
+		/// Indexer for auxiliary fields of the DataWriter.
+		/// </summary>
+		/// <param name="auxId"></param>
+		/// <returns></returns>
+		object this[string auxId] { get; set; }
+
+		bool HasTorqueConverter { set; }
+
+		/// <summary>
+		/// Commits the data of the current simulation step.
+		/// </summary>
+		void CommitSimulationStep();
+
+		FuelData.Entry FuelData { get; }
+
+		VectoRun.Status RunStatus { get; }
+
+		string Error { get; }
+
+		string StackTrace { get; }
+
+		/// <summary>
+		/// Finishes the writing of the DataWriter.
+		/// </summary>
+		void Finish(VectoRun.Status runStatus);
+
+		IEnumerable<T> GetValues<T>(ModalResultField key);
+
+		IEnumerable<T> GetValues<T>(DataColumn col);
+
+		IEnumerable<T> GetValues<T>(Func<DataRow, T> selectorFunc);
+
+		Dictionary<string, DataColumn> Auxiliaries { get; }
+
+		T TimeIntegral<T>(ModalResultField field, Func<SI, bool> filter = null) where T : SIBase<T>;
+
+		void SetDataValue(string fieldName, object value);
+
+		void AddAuxiliary(string id, string columnName = null);
+
+		/// <summary>
+		/// clear the modal data after the simulation
+		/// called after the simulation is finished and the sum-entries have been written
+		/// </summary>
+		/// <param name="exception"></param>
+		void FinishSimulation(Exception exception = null);
+	}
+
+	public static class ModalDataContainerExtensions
+	{
+		public static T Max<T>(this IModalDataContainer data, ModalResultField field)
+		{
+			return data.GetValues<T>(field).Max();
+		}
+
+		public static T Min<T>(this IModalDataContainer data, ModalResultField field)
+		{
+			return data.GetValues<T>(field).Min();
+		}
+
+		/// <summary>
+		/// Returns a default value if the SI object is null.
+		/// </summary>
+		/// <typeparam name="T">The SI Type.</typeparam>
+		/// <param name="self">The SI Instance.</param>
+		/// <param name="defaultValue">The default value.</param>
+		/// <returns>If self is null, the default value as SI-Type is returned. Otherwise self is returned.</returns>
+		/// <code>
+		/// NewtonMeter t = null;
+		/// var x = t.DefaultIfNull(0);
+		/// </code>
+		public static T DefaultIfNull<T>(this T self, double defaultValue) where T : SIBase<T>
+		{
+			return self ?? defaultValue.SI<T>();
+		}
+
+		public static MeterPerSquareSecond AccelerationsPositive(this IModalDataContainer data)
+		{
+			return data.GetValues<MeterPerSquareSecond>(ModalResultField.acc)
+				.Where(x => x > 0.125)
+				.DefaultIfEmpty(0.SI<MeterPerSquareSecond>())
+				.Average();
+		}
+
+		public static MeterPerSquareSecond AccelerationsNegative(this IModalDataContainer data)
+		{
+			return data.GetValues<MeterPerSquareSecond>(ModalResultField.acc)
+				.Where(x => x < -0.125)
+				.DefaultIfEmpty(0.SI<MeterPerSquareSecond>())
+				.Average();
+		}
+
+		public static Scalar AccelerationTimeShare(this IModalDataContainer data)
+		{
+			var accelerationTimeShare = data.GetValues(x => new {
+				a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			})
+				.Sum(x => x.a > 0.125 ? x.dt : 0.SI<Second>()).DefaultIfNull(0);
+			return 100 * (accelerationTimeShare / data.Duration()).Cast<Scalar>();
+		}
+
+		public static Scalar DecelerationTimeShare(this IModalDataContainer data)
+		{
+			var decelerationTimeShare = data.GetValues(x => new {
+				a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			})
+				.Sum(x => x.a < -0.125 ? x.dt : 0.SI<Second>()).DefaultIfNull(0);
+			return 100 * (decelerationTimeShare / data.Duration()).Cast<Scalar>();
+		}
+
+		public static Scalar CruiseTimeShare(this IModalDataContainer data)
+		{
+			var cruiseTime = data.GetValues(x => new {
+				v = x.Field<MeterPerSecond>((int)ModalResultField.v_act).DefaultIfNull(0),
+				a = x.Field<MeterPerSquareSecond>((int)ModalResultField.acc).DefaultIfNull(0),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			})
+				.Sum(x => x.v >= 0.1.KMPHtoMeterPerSecond() && x.a.IsBetween(-0.125, 0.125) ? x.dt : 0.SI<Second>())
+				.DefaultIfNull(0);
+			return 100 * (cruiseTime / data.Duration()).Cast<Scalar>();
+		}
+
+		public static Scalar StopTimeShare(this IModalDataContainer data)
+		{
+			var stopTime = data.GetValues(x => new {
+				v = x.Field<MeterPerSecond>((int)ModalResultField.v_act).DefaultIfNull(0),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			})
+				.Sum(x => x.v < 0.1.KMPHtoMeterPerSecond() ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
+			return 100 * (stopTime / data.Duration()).Cast<Scalar>();
+		}
+
+		public static MeterPerSquareSecond AccelerationAverage(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<MeterPerSecond>(ModalResultField.acc) / data.Duration();
+		}
+
+		public static Meter AltitudeDelta(this IModalDataContainer data)
+		{
+			var altitudes = data.GetValues<Meter>(ModalResultField.altitude).ToList();
+			var first = altitudes.First();
+			var last = altitudes.Last();
+			return first == null || last == null ? null : last - first;
+		}
+
+		public static WattSecond PowerAccelerations(this IModalDataContainer data)
+		{
+			var paEngine = data.TimeIntegral<WattSecond>(ModalResultField.P_eng_inertia);
+			var paGearbox = data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_inertia);
+			return paEngine + paGearbox;
+		}
+
+		public static WattSecond WorkClutch(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_clutch_loss);
+		}
+
+		public static WattSecond WorkGearshift(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_shift_loss);
+		}
+
+		public static WattSecond WorkGearbox(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_gbx_loss);
+		}
+
+		public static WattSecond WorkAxlegear(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_axle_loss);
+		}
+
+		public static WattSecond WorkRetarder(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_ret_loss);
+		}
+
+		public static WattSecond WorkAngledrive(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_angle_loss);
+		}
+
+		public static WattSecond WorkTorqueConverter(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_TC_loss);
+		}
+
+		public static Second Duration(this IModalDataContainer data)
+		{
+			var time = data.GetValues<Second>(ModalResultField.time).ToList();
+			var dt = data.GetValues<Second>(ModalResultField.simulationInterval).ToList();
+			if (time.Count == 1) {
+				return time.First();
+			}
+			return time.Max() - time.Min() + dt.First() / 2 + dt.Last() / 2;
+		}
+
+		public static Meter Distance(this IModalDataContainer data)
+		{
+			var max = data.Max<Meter>(ModalResultField.dist);
+			var min = data.Min<Meter>(ModalResultField.dist);
+			return max == null || min == null ? null : max - min;
+		}
+
+		public static WattSecond WorkTotalMechanicalBrake(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_brake_loss);
+		}
+
+		public static WattSecond WorkVehicleInertia(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_veh_inertia) +
+					data.TimeIntegral<WattSecond>(ModalResultField.P_wheel_inertia);
+		}
+
+		public static WattSecond WorkAuxiliaries(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_aux);
+		}
+
+		public static WattSecond WorkRoadGradientResistance(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_slope);
+		}
+
+		public static WattSecond WorkRollingResistance(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_roll);
+		}
+
+		public static WattSecond WorkAirResistance(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_air);
+		}
+
+
+		public static WattSecond TotalEngineWorkPositive(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_eng_fcmap, x => x > 0);
+		}
+
+		public static WattSecond TotalEngineWorkNegative(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_eng_fcmap, x => x < 0);
+		}
+
+		public static Watt PowerWheelPositive(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<WattSecond>(ModalResultField.P_wheel_in, x => x > 0) / data.Duration();
+		}
+
+		public static KilogramPerMeter FuelConsumptionWHTC(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / distance;
+		}
+
+		public static KilogramPerSecond FuelConsumptionWHTCPerSecond(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCWHTCc) / data.Duration();
+		}
+
+		public static KilogramPerMeter FuelConsumptionAuxStartStop(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCAUXc) / distance;
+		}
+
+		public static KilogramPerSecond FuelConsumptionAAUXPerSecond(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCAAUX) / data.Duration();
+		}
+
+		public static KilogramPerMeter FuelConsumptionAAUX(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCAAUX) / distance;
+		}
+
+		public static KilogramPerSecond FuelConsumptionAuxStartStopPerSecond(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCAUXc) / data.Duration();
+		}
+
+		public static KilogramPerSecond FuelConsumptionFinalPerSecond(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) / data.Duration();
+		}
+
+		public static KilogramPerMeter FuelConsumptionFinal(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) / distance;
+		}
+
+		public static SI FuelConsumptionFinalLiterPer100Kilometer(this IModalDataContainer data)
+		{
+			var fuelConsumptionFinal = data.FuelConsumptionFinal();
+			if (fuelConsumptionFinal == null || data.FuelData.FuelDensity == null) {
+				return null;
+			}
+
+			var fcVolumePerMeter = fuelConsumptionFinal / data.FuelData.FuelDensity;
+			return fcVolumePerMeter.ConvertTo().Cubic.Dezi.Meter * 100.SI().Kilo.Meter;
+		}
+
+		public static KilogramPerMeter CO2PerMeter(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * data.FuelData.CO2PerFuelWeight / distance;
+		}
+
+		public static JoulePerMeter EnergyPerMeter(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCFinal) * data.FuelData.LowerHeatingValue / distance;
+		}
+
+		public static KilogramPerSecond FCMapPerSecond(this IModalDataContainer data)
+		{
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) / data.Duration();
+		}
+
+		public static KilogramPerMeter FCMapPerMeter(this IModalDataContainer data)
+		{
+			var distance = data.Distance();
+			if (distance == null || distance.IsEqual(0)) {
+				return null;
+			}
+			return data.TimeIntegral<Kilogram>(ModalResultField.FCMap) / distance;
+		}
+
+
+		public static Watt TotalPowerEnginePositiveAverage(this IModalDataContainer data)
+		{
+			var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval);
+			var values = data.GetValues<Watt>(ModalResultField.P_eng_fcmap)
+				.Zip(simulationIntervals, (value, dt) => new { Dt = dt, Value = value * dt })
+				.Where(v => v.Value > 0).ToList();
+			if (values.Any()) {
+				return values.Sum(v => v.Value) / Duration(data);
+			}
+			return 0.SI<Watt>();
+		}
+
+		public static MeterPerSecond Speed(this IModalDataContainer data)
+		{
+			var distance = Distance(data);
+			var duration = Duration(data);
+			if (distance == null || duration == null || duration.IsEqual(0)) {
+				return null;
+			}
+			return distance / duration;
+		}
+
+		public static WattSecond AuxiliaryWork(this IModalDataContainer data, DataColumn auxCol)
+		{
+			var simulationIntervals = data.GetValues<Second>(ModalResultField.simulationInterval).ToArray();
+			var auxValues = data.GetValues<Watt>(auxCol).ToArray();
+			var sum = 0.SI<WattSecond>();
+			for (var i = 0; i < simulationIntervals.Length; i++) {
+				if (auxValues[i] != null && simulationIntervals[i] != null) {
+					sum += auxValues[i] * simulationIntervals[i];
+				}
+			}
+			return sum;
+		}
+
+
+		public static MeterPerSecond MaxSpeed(this IModalDataContainer data)
+		{
+			return data.Max<MeterPerSecond>(ModalResultField.v_act).DefaultIfNull(0);
+		}
+
+		public static MeterPerSecond MinSpeed(this IModalDataContainer data)
+		{
+			return data.Min<MeterPerSecond>(ModalResultField.v_act).DefaultIfNull(0);
+		}
+
+		public static MeterPerSquareSecond MaxAcceleration(this IModalDataContainer data)
+		{
+			return data.Max<MeterPerSquareSecond>(ModalResultField.acc).DefaultIfNull(0);
+		}
+
+		public static MeterPerSquareSecond MaxDeceleration(this IModalDataContainer data)
+		{
+			return -data.Min<MeterPerSquareSecond>(ModalResultField.acc).DefaultIfNull(0);
+		}
+
+		public static PerSecond AvgEngineSpeed(this IModalDataContainer data)
+		{
+			var integral = data.GetValues(x => x.Field<PerSecond>((int)ModalResultField.n_eng_avg).Value() *
+												x.Field<Second>((int)ModalResultField.simulationInterval).Value()).Sum();
+			return (integral / Duration(data).Value()).SI<PerSecond>();
+		}
+
+		public static PerSecond MaxEngineSpeed(this IModalDataContainer data)
+		{
+			return data.Max<PerSecond>(ModalResultField.n_eng_avg);
+		}
+
+		public static Scalar EngineMaxLoadTimeShare(this IModalDataContainer data)
+		{
+			var sum = data.GetValues(x => new {
+				tMax = x.Field<NewtonMeter>((int)ModalResultField.Tq_full).DefaultIfNull(-1),
+				tEng = x.Field<NewtonMeter>((int)ModalResultField.T_eng_fcmap).DefaultIfNull(0),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			}).Sum(x => x.tMax.IsEqual(x.tEng, 5.SI<NewtonMeter>()) ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
+			return 100 * sum / Duration(data);
+		}
+
+		public static Scalar GearshiftCount(this IModalDataContainer data)
+		{
+			var prevGear = data.GetValues<uint>(ModalResultField.Gear).First();
+			var gearCount = 0;
+
+			var shifts = data.GetValues(x => new {
+				Gear = x.Field<uint>((int)ModalResultField.Gear),
+				Speed = x.Field<MeterPerSecond>((int)ModalResultField.v_act)
+			});
+			foreach (var entry in shifts) {
+				if (entry.Speed != null && entry.Speed.IsSmallerOrEqual(0.1)) {
+					prevGear = 0;
+					gearCount++;
+				}
+				if (entry.Gear == 0 || entry.Gear == prevGear) {
+					continue;
+				}
+				gearCount++;
+				prevGear = entry.Gear;
+			}
+			return gearCount.SI<Scalar>();
+		}
+
+		public static Scalar CoastingTimeShare(this IModalDataContainer data)
+		{
+			var sum = data.GetValues(x => new {
+				DrivingBehavior = x.Field<DrivingBehavior>((int)ModalResultField.drivingBehavior),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			})
+				.Sum(x => x.DrivingBehavior == DrivingBehavior.Coasting ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
+			return 100 * sum / Duration(data);
+		}
+
+		public static Scalar BrakingTimeShare(this IModalDataContainer data)
+		{
+			var sum = data.GetValues(x => new {
+				DrivingBehavior = x.Field<DrivingBehavior>((int)ModalResultField.drivingBehavior),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			})
+				.Sum(x => x.DrivingBehavior == DrivingBehavior.Braking ? x.dt : 0.SI<Second>()) ?? 0.SI<Second>();
+			return 100 * sum / Duration(data);
+		}
+
+		public static Dictionary<uint, Scalar> TimeSharePerGear(this IModalDataContainer data, uint gearCount)
+		{
+			var retVal = new Dictionary<uint, Scalar>();
+			for (uint i = 0; i <= gearCount; i++) {
+				retVal[i] = 0.SI<Scalar>();
+			}
+
+			var gearData = data.GetValues(x => new {
+				Gear = x.Field<uint>((int)ModalResultField.Gear),
+				dt = x.Field<Second>((int)ModalResultField.simulationInterval)
+			});
+
+			foreach (var entry in gearData) {
+				retVal[entry.Gear] += entry.dt.Value();
+			}
+
+			var duration = Duration(data).Value();
+			for (uint i = 0; i <= gearCount; i++) {
+				retVal[i] = 100 * retVal[i] / duration;
+			}
+			return retVal;
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
index 7a69faf093e6c94035e30fd0dcd67f9ff55a6667..10c29e57190056f883d4a4147a85447b36f5b292 100644
--- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
@@ -29,566 +29,566 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Data;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.Models.Declaration;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.SimulationComponent.Data;
-
-// ReSharper disable MemberCanBePrivate.Global  -- used by API!
-
-namespace TUGraz.VectoCore.OutputData
-{
-	public delegate void WriteSumData(IModalDataContainer data);
-
-	/// <summary>
-	/// Class for the sum file in vecto.
-	/// </summary>
-	public class SummaryDataContainer : LoggingObject, IDisposable
-	{
-		// ReSharper disable InconsistentNaming
-		public const string INTERNAL_PREFIX = "INTERNAL";
-		public const string SORT = INTERNAL_PREFIX + " Sorting";
-		public const string JOB = "Job [-]";
-		public const string INPUTFILE = "Input File [-]";
-		public const string CYCLE = "Cycle [-]";
-		public const string STATUS = "Status";
-		public const string CURB_MASS = "Chassis curb mass [kg]";
-		public const string LOADING = "Loading [kg]";
-
-		public const string VEHICLE_MANUFACTURER = "Vehicle manufacturer [-]";
-		public const string VIN_NUMBER = "VIN number";
-		public const string VEHICLE_MODEL = "Vehicle model [-]";
-
-		public const string ENGINE_MANUFACTURER = "Engine manufacturer [-]";
-		public const string ENGINE_MODEL = "Engine model [-]";
-		public const string ENGINE_FUEL_TYPE = "Engine fuel type [-]";
-		public const string ENGINE_WHTC_URBAN = "Engine WHTCUrban";
-		public const string ENGINE_WHTC_RURAL = "Engine WHTCRural";
-		public const string ENGINE_WHTC_MOTORWAY = "Engine WHTCMotorway";
-		public const string ENGINE_BF_COLD_HOT = "Engine BFColdHot";
-		public const string ENGINE_CF_REG_PER = "Engine CFRegPer";
-		public const string ENGINE_ACTUAL_CORRECTION_FACTOR = "Engine actual CF";
-		public const string ENGINE_RATED_POWER = "Engine rated power [kW]";
-		public const string ENGINE_IDLING_SPEED = "Engine idling speed [rpm]";
-		public const string ENGINE_RATED_SPEED = "Engine rated speed [rpm]";
-		public const string ENGINE_DISPLACEMENT = "Engine displacement [ccm]";
-
-		public const string ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER = "total RRC [-]";
-		public const string ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER = "weighted RRC w/o trailer [-]";
-
-		public const string GEARBOX_MANUFACTURER = "Gearbox manufacturer [-]";
-		public const string GEARBOX_MODEL = "Gearbox model [-]";
-		public const string GEARBOX_TYPE = "Gearbox type [-]";
-		public const string GEAR_RATIO_FIRST_GEAR = "Gear ratio first gear [-]";
-		public const string GEAR_RATIO_LAST_GEAR = "Gear ratio last gear [-]";
-
-		public const string TORQUECONVERTER_MANUFACTURER = "Torque converter manufacturer [-]";
-		public const string TORQUECONVERTER_MODEL = "Torque converter model [-]";
-
-		public const string RETARDER_MANUFACTURER = "Retarder manufacturer [-]";
-		public const string RETARDER_MODEL = "Retarder model [-]";
-		public const string RETARDER_TYPE = "Retarder type [-]";
-
-		public const string ANGLEDRIVE_MANUFACTURER = "Angledrive manufacturer [-]";
-		public const string ANGLEDRIVE_MODEL = "Angledrive model [-]";
-		public const string ANGLEDRIVE_RATIO = "Angledrive ratio [-]";
-
-		public const string AXLE_MANUFACTURER = "Axle manufacturer [-]";
-		public const string AXLE_MODEL = "Axle model [-]";
-		public const string AXLE_RATIO = "Axle gear ratio [-]";
-
-		public const string AUX_TECH_FORMAT = "Auxiliary technology {0} [-]";
-
-		public const string HDV_CO2_VEHICLE_CLASS = "HDV CO2 vehicle class [-]";
-		public const string TOTAL_VEHICLE_MASS = "Total vehicle mass [kg]";
-		public const string CD_x_A = "CdxA [m²]";
-		//public const string ROLLING_RESISTANCE_COEFFICIENT = "weighed RRC [-]";
-		public const string R_DYN = "r_dyn [m]";
-
-		public const string CARGO_VOLUME = "Cargo Volume [m³]";
-		public const string TIME = "time [s]";
-		public const string DISTANCE = "distance [km]";
-		public const string SPEED = "speed [km/h]";
-		public const string ALTITUDE_DELTA = "altitudeDelta [m]";
-
-		public const string FCMAP_H = "FC-Map [g/h]";
-		public const string FCMAP_KM = "FC-Map [g/km]";
-		public const string FCAUXC_H = "FC-AUXc [g/h]";
-		public const string FCAUXC_KM = "FC-AUXc [g/km]";
-		public const string FCWHTCC_H = "FC-WHTCc [g/h]";
-		public const string FCWHTCC_KM = "FC-WHTCc [g/km]";
-		public const string FCAAUX_H = "FC-AAUX [g/h]";
-		public const string FCAAUX_KM = "FC-AAUX [g/km]";
-
-		public const string FCFINAL_H = "FC-Final [g/h]";
-		public const string FCFINAL_KM = "FC-Final [g/km]";
-		public const string FCFINAL_LITERPER100KM = "FC-Final [l/100km]";
-		public const string FCFINAL_LITERPER100TKM = "FC-Final [l/100tkm]";
-		public const string FCFINAL_LiterPer100M3KM = "FC-Final [l/100m³km]";
-
-		public const string CO2_KM = "CO2 [g/km]";
-		public const string CO2_TKM = "CO2 [g/tkm]";
-		public const string CO2_M3KM = "CO2 [g/m³km]";
-
-		public const string P_WHEEL_POS = "P_wheel_in_pos [kW]";
-		public const string P_FCMAP_POS = "P_fcmap_pos [kW]";
-
-		public const string E_FORMAT = "E_{0} [kWh]";
-		public const string E_AUX_FORMAT = "E_aux_{0} [kWh]";
-		public const string E_AUX = "E_aux_sum [kWh]";
-
-		public const string E_AIR = "E_air [kWh]";
-		public const string E_ROLL = "E_roll [kWh]";
-		public const string E_GRAD = "E_grad [kWh]";
-		public const string E_VEHICLE_INERTIA = "E_vehi_inertia [kWh]";
-		public const string E_POWERTRAIN_INERTIA = "E_powertrain_inertia [kWh]";
-		public const string E_BRAKE = "E_brake [kWh]";
-		public const string E_GBX_LOSS = "E_gbx_loss [kWh]";
-		public const string E_SHIFT_LOSS = "E_shift_loss [kWh]";
-		public const string E_AXL_LOSS = "E_axl_loss [kWh]";
-		public const string E_RET_LOSS = "E_ret_loss [kWh]";
-		public const string E_TC_LOSS = "E_tc_loss [kWh]";
-		public const string E_ANGLE_LOSS = "E_angle_loss [kWh]";
-		public const string E_CLUTCH_LOSS = "E_clutch_loss [kWh]";
-		public const string E_FCMAP_POS = "E_fcmap_pos [kWh]";
-		public const string E_FCMAP_NEG = "E_fcmap_neg [kWh]";
-
-		public const string ACC = "a [m/s^2]";
-		public const string ACC_POS = "a_pos [m/s^2]";
-		public const string ACC_NEG = "a_neg [m/s^2]";
-
-		public const string ACC_TIMESHARE = "AccelerationTimeShare [%]";
-		public const string DEC_TIMESHARE = "DecelerationTimeShare [%]";
-		public const string CRUISE_TIMESHARE = "CruiseTimeShare [%]";
-		public const string STOP_TIMESHARE = "StopTimeShare [%]";
-
-		public const string MAX_SPEED = "max. speed [km/h";
-		public const string MAX_ACCELERATION = "max. acc [m/s²]";
-		public const string MAX_DECELERATION = "max. dec [m/s²]";
-		public const string AVG_ENGINE_SPEED = "n_eng_avg [rpm]";
-		public const string MAX_ENGINE_SPEED = "n_eng_max [rpm]";
-		public const string NUM_GEARSHIFTS = "gear shifts [-]";
-		public const string ENGINE_FULL_LOAD_TIME_SHARE = "Engine max. Load time share [%]";
-		public const string COASTING_TIME_SHARE = "CoastingTimeShare [%]";
-		public const string BRAKING_TIME_SHARE = "BrakingTImeShare [%]";
-
-		public const string TIME_SHARE_PER_GEAR_FORMAT = "Gear {0} TimeShare [%]";
-
-		// ReSharper restore InconsistentNaming
-
-		internal readonly DataTable Table;
-		private readonly ISummaryWriter _sumWriter;
-
-
-		protected SummaryDataContainer() {}
-
-		/// <summary>
-		/// Initializes a new instance of the <see cref="SummaryDataContainer"/> class.
-		/// </summary>
-		/// <param name="writer"></param>
-		public SummaryDataContainer(ISummaryWriter writer)
-		{
-			_sumWriter = writer;
-
-			Table = new DataTable();
-
-			Table.Columns.AddRange(new[] {
-				Tuple.Create(SORT, typeof(int)),
-				Tuple.Create(JOB, typeof(string)),
-				Tuple.Create(INPUTFILE, typeof(string)),
-				Tuple.Create(CYCLE, typeof(string)),
-				Tuple.Create(STATUS, typeof(string)),
-				Tuple.Create(VEHICLE_MANUFACTURER, typeof(string)),
-				Tuple.Create(VIN_NUMBER, typeof(string)),
-				Tuple.Create(VEHICLE_MODEL, typeof(string)),
-				Tuple.Create(HDV_CO2_VEHICLE_CLASS, typeof(string)),
-				Tuple.Create(CURB_MASS, typeof(SI)),
-				Tuple.Create(LOADING, typeof(SI)),
-				Tuple.Create(TOTAL_VEHICLE_MASS, typeof(SI)),
-				Tuple.Create(ENGINE_MANUFACTURER, typeof(string)),
-				Tuple.Create(ENGINE_MODEL, typeof(string)),
-				Tuple.Create(ENGINE_FUEL_TYPE, typeof(string)),
-				Tuple.Create(ENGINE_RATED_POWER, typeof(SI)),
-				Tuple.Create(ENGINE_IDLING_SPEED, typeof(SI)),
-				Tuple.Create(ENGINE_RATED_SPEED, typeof(SI)),
-				Tuple.Create(ENGINE_DISPLACEMENT, typeof(SI)),
-				Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)),
-				Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)),
-				Tuple.Create(ENGINE_WHTC_MOTORWAY, typeof(double)),
-				Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)),
-				Tuple.Create(ENGINE_CF_REG_PER, typeof(double)),
-				Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)),
-				Tuple.Create(CD_x_A, typeof(SI)),
-				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)),
-				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)),
-				Tuple.Create(R_DYN, typeof(SI)),
-				Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)),
-				Tuple.Create(GEARBOX_MODEL, typeof(string)),
-				Tuple.Create(GEARBOX_TYPE, typeof(string)),
-				Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(SI)),
-				Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(SI)),
-				Tuple.Create(TORQUECONVERTER_MANUFACTURER, typeof(string)),
-				Tuple.Create(TORQUECONVERTER_MODEL, typeof(string)),
-				Tuple.Create(RETARDER_MANUFACTURER, typeof(string)),
-				Tuple.Create(RETARDER_MODEL, typeof(string)),
-				Tuple.Create(RETARDER_TYPE, typeof(string)),
-				Tuple.Create(ANGLEDRIVE_MANUFACTURER, typeof(string)),
-				Tuple.Create(ANGLEDRIVE_MODEL, typeof(string)),
-				Tuple.Create(ANGLEDRIVE_RATIO, typeof(string)),
-				Tuple.Create(AXLE_MANUFACTURER, typeof(string)),
-				Tuple.Create(AXLE_MODEL, typeof(string)),
-				Tuple.Create(AXLE_RATIO, typeof(SI)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.SteeringPump), typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.Fan), typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition),
-					typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.PneumaticSystem), typeof(string)),
-				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.ElectricSystem), typeof(string)),
-			}.Select(x => new DataColumn(x.Item1, x.Item2)).ToArray());
-
-			Table.Columns.AddRange(new[] {
-				CARGO_VOLUME,
-				TIME, DISTANCE,
-				SPEED, ALTITUDE_DELTA,
-				FCMAP_H, FCMAP_KM,
-				FCAUXC_H, FCAUXC_KM,
-				FCWHTCC_H, FCWHTCC_KM,
-				FCAAUX_H, FCAAUX_KM,
-				FCFINAL_H, FCFINAL_KM,
-				FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, FCFINAL_LiterPer100M3KM,
-				CO2_KM, CO2_TKM, CO2_M3KM,
-				P_WHEEL_POS, P_FCMAP_POS,
-				E_FCMAP_POS, E_FCMAP_NEG, E_POWERTRAIN_INERTIA,
-				E_AUX, E_CLUTCH_LOSS, E_TC_LOSS, E_SHIFT_LOSS, E_GBX_LOSS,
-				E_RET_LOSS, E_ANGLE_LOSS, E_AXL_LOSS, E_BRAKE, E_VEHICLE_INERTIA, E_AIR, E_ROLL, E_GRAD,
-				ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, STOP_TIMESHARE,
-				MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS,
-				ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE
-			}.Select(x => new DataColumn(x, typeof(SI))).ToArray());
-		}
-
-		/// <summary>
-		/// Finishes the summary data container (writes the data to the sumWriter).
-		/// </summary>
-		public virtual void Finish()
-		{
-			if (_sumWriter != null) {
-				var view = new DataView(Table, "", SORT, DataViewRowState.CurrentRows).ToTable();
-				var toRemove =
-					view.Columns.Cast<DataColumn>().Where(column => column.ColumnName.StartsWith(INTERNAL_PREFIX)).ToList();
-				foreach (var dataColumn in toRemove) {
-					view.Columns.Remove(dataColumn);
-				}
-				_sumWriter.WriteSumData(view);
-			}
-		}
-
-		/// <summary>
-		/// Writes the result of one run into the summary data container.
-		/// </summary>
-		[MethodImpl(MethodImplOptions.Synchronized)]
-		//public virtual void Write(IModalDataContainer modData, string jobFileName, string jobName, string cycleFileName,
-		//	Kilogram vehicleMass, Kilogram vehicleLoading, CubicMeter cargoVolume, uint gearCount)
-		public virtual void Write(IModalDataContainer modData, int jobNr, int runNr, VectoRunData runData)
-		{
-			var row = Table.NewRow();
-			Table.Rows.Add(row);
-
-			row[SORT] = jobNr * 1000 + runNr;
-			row[JOB] = string.Format("{0}-{1}", jobNr, runNr); //ReplaceNotAllowedCharacters(current);
-			row[INPUTFILE] = ReplaceNotAllowedCharacters(runData.JobName);
-			row[CYCLE] = ReplaceNotAllowedCharacters(runData.Cycle.Name + Constants.FileExtensions.CycleFile);
-
-			row[STATUS] = modData.RunStatus;
-
-			var vehicleLoading = 0.SI<Kilogram>();
-			var cargoVolume = 0.SI<CubicMeter>();
-			uint gearCount = 0u;
-			if (runData.Cycle.CycleType != CycleType.EngineOnly) {
-				row[VEHICLE_MANUFACTURER] = runData.VehicleData.Manufacturer;
-				row[VIN_NUMBER] = runData.VehicleData.VIN;
-				row[VEHICLE_MODEL] = runData.VehicleData.ModelName;
-
-				row[HDV_CO2_VEHICLE_CLASS] = runData.VehicleData.VehicleClass.GetClassNumber();
-				row[CURB_MASS] = runData.VehicleData.CurbWeight;
-				// - (runData.VehicleData.BodyAndTrailerWeight ?? 0.SI<Kilogram>());
-				row[LOADING] = runData.VehicleData.Loading;
-				row[CARGO_VOLUME] = runData.VehicleData.CargoVolume;
-
-				row[TOTAL_VEHICLE_MASS] = runData.VehicleData.TotalVehicleWeight;
-				row[ENGINE_MANUFACTURER] = runData.EngineData.Manufacturer;
-				row[ENGINE_MODEL] = runData.EngineData.ModelName;
-				row[ENGINE_FUEL_TYPE] = runData.EngineData.FuelType.GetLabel();
-				row[ENGINE_RATED_POWER] = runData.EngineData.RatedPowerDeclared != null
-					? runData.EngineData.RatedPowerDeclared.ConvertTo().Kilo.Watt
-					: runData.EngineData.FullLoadCurves[0].MaxPower.ConvertTo().Kilo.Watt;
-				row[ENGINE_IDLING_SPEED] = runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>();
-				row[ENGINE_RATED_SPEED] = runData.EngineData.RatedSpeedDeclared != null
-					? runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>()
-					: runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>();
-				row[ENGINE_DISPLACEMENT] = runData.EngineData.Displacement.ConvertTo().Cubic.Centi.Meter;
-
-				row[ENGINE_WHTC_URBAN] = runData.EngineData.WHTCUrban;
-				row[ENGINE_WHTC_RURAL] = runData.EngineData.WHTCRural;
-				row[ENGINE_WHTC_MOTORWAY] = runData.EngineData.WHTCMotorway;
-				row[ENGINE_BF_COLD_HOT] = runData.EngineData.ColdHotCorrectionFactor;
-				row[ENGINE_CF_REG_PER] = runData.EngineData.CorrectionFactorRegPer;
-				row[ENGINE_ACTUAL_CORRECTION_FACTOR] = runData.EngineData.FuelConsumptionCorrectionFactor;
-
-				row[CD_x_A] = runData.AirdragData.CrossWindCorrectionCurve.AirDragArea;
-
-				row[ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER] =
-					runData.VehicleData.RollResistanceCoefficientWithoutTrailer;
-				row[ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER] =
-					runData.VehicleData.TotalRollResistanceCoefficient;
-
-				row[R_DYN] = runData.VehicleData.DynamicTyreRadius;
-
-				row[GEARBOX_MANUFACTURER] = runData.GearboxData.Manufacturer;
-				row[GEARBOX_MODEL] = runData.GearboxData.ModelName;
-				row[GEARBOX_TYPE] = runData.GearboxData.Type;
-				if (runData.GearboxData.Type.AutomaticTransmission()) {
-					row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
-						? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio)
-							? runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>()
-							: runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>())
-						: 0.SI<Scalar>();
-					row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0
-						? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
-						: 0.SI<Scalar>();
-					row[TORQUECONVERTER_MANUFACTURER] = runData.GearboxData.TorqueConverterData.Manufacturer;
-					row[TORQUECONVERTER_MODEL] = runData.GearboxData.TorqueConverterData.ModelName;
-				} else {
-					row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
-						? runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()
-						: 0.SI<Scalar>();
-					row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0
-						? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
-						: 0.SI<Scalar>();
-					row[TORQUECONVERTER_MANUFACTURER] = "n.a.";
-					row[TORQUECONVERTER_MODEL] = "n.a.";
-				}
-				row[RETARDER_TYPE] = runData.Retarder.Type.GetLabel();
-				if (runData.Retarder.Type.IsDedicatedComponent()) {
-					row[RETARDER_MANUFACTURER] = runData.Retarder.Manufacturer;
-					row[RETARDER_MODEL] = runData.Retarder.ModelName;
-				} else {
-					row[RETARDER_MANUFACTURER] = "n.a.";
-					row[RETARDER_MODEL] = "n.a.";
-				}
-
-				if (runData.AngledriveData != null) {
-					row[ANGLEDRIVE_MANUFACTURER] = runData.AngledriveData.Manufacturer;
-					row[ANGLEDRIVE_MODEL] = runData.AngledriveData.ModelName;
-					row[ANGLEDRIVE_RATIO] = runData.AngledriveData.Angledrive.Ratio;
-				} else {
-					row[ANGLEDRIVE_MANUFACTURER] = "n.a.";
-					row[ANGLEDRIVE_MODEL] = "n.a.";
-					row[ANGLEDRIVE_RATIO] = "n.a.";
-				}
-
-				row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer;
-				row[AXLE_MODEL] = runData.AxleGearData.ModelName;
-				row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>();
-
-				foreach (var aux in runData.Aux) {
-					if (aux.ID == Constants.Auxiliaries.IDs.PTOConsumer || aux.ID == Constants.Auxiliaries.IDs.PTOTransmission) {
-						continue;
-					}
-					var colName = string.Format(AUX_TECH_FORMAT, aux.ID);
-
-					if (!Table.Columns.Contains(colName)) {
-						var col = Table.Columns.Add(colName, typeof(string));
-						// move the new column to correct position
-						col.SetOrdinal(Table.Columns[CARGO_VOLUME].Ordinal);
-					}
-
-					row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology);
-				}
-
-				cargoVolume = runData.VehicleData.CargoVolume;
-				vehicleLoading = runData.VehicleData.Loading;
-				gearCount = (uint)runData.GearboxData.Gears.Count;
-			}
-
-
-			var totalTime = modData.Duration();
-			row[TIME] = totalTime;
-
-			var distance = modData.Distance();
-			if (distance != null) {
-				row[DISTANCE] = distance.ConvertTo().Kilo.Meter;
-			}
-
-			var speed = modData.Speed();
-			if (speed != null) {
-				row[SPEED] = speed.ConvertTo().Kilo.Meter.Per.Hour;
-			}
-
-			row[ALTITUDE_DELTA] = modData.AltitudeDelta();
-
-			row[FCMAP_H] = modData.FCMapPerSecond().ConvertTo().Gramm.Per.Hour;
-			var fcMapPerMeter = modData.FCMapPerMeter();
-			if (fcMapPerMeter != null) {
-				row[FCMAP_KM] = fcMapPerMeter.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
-
-			row[FCAUXC_H] = modData.FuelConsumptionAuxStartStopPerSecond().ConvertTo().Gramm.Per.Hour;
-			var fuelConsumptionAuxStartStopCorrected = modData.FuelConsumptionAuxStartStop();
-			if (fuelConsumptionAuxStartStopCorrected != null) {
-				row[FCAUXC_KM] = fuelConsumptionAuxStartStopCorrected.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
-
-			row[FCWHTCC_H] = modData.FuelConsumptionWHTCPerSecond().ConvertTo().Gramm.Per.Hour;
-			var fuelConsumptionWHTCCorrected = modData.FuelConsumptionWHTC();
-			if (fuelConsumptionWHTCCorrected != null) {
-				row[FCWHTCC_KM] = fuelConsumptionWHTCCorrected.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
-
-			row[FCAAUX_H] = modData.FuelConsumptionAAUXPerSecond().ConvertTo().Gramm.Per.Hour;
-			var fuelConsumptionAaux = modData.FuelConsumptionAAUX();
-			if (fuelConsumptionAaux != null) {
-				row[FCAAUX_KM] = fuelConsumptionAaux.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
-
-			row[FCFINAL_H] = modData.FuelConsumptionFinalPerSecond().ConvertTo().Gramm.Per.Hour;
-			var fcfinal = modData.FuelConsumptionFinal();
-			if (fcfinal != null) {
-				row[FCFINAL_KM] = fcfinal.ConvertTo().Gramm.Per.Kilo.Meter;
-			}
-
-			var fcPer100lkm = modData.FuelConsumptionFinalLiterPer100Kilometer();
-			row[FCFINAL_LITERPER100KM] = fcPer100lkm;
-			if (vehicleLoading != null && !vehicleLoading.IsEqual(0) && fcPer100lkm != null) {
-				row[FCFINAL_LITERPER100TKM] = fcPer100lkm /
-											vehicleLoading.ConvertTo().Ton;
-			}
-			if (cargoVolume > 0 && fcPer100lkm != null) {
-				row[FCFINAL_LiterPer100M3KM] = fcPer100lkm / cargoVolume;
-			}
-
-			var kilogramPerMeter = modData.CO2PerMeter();
-			if (kilogramPerMeter != null) {
-				row[CO2_KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter;
-				if (vehicleLoading != null && !vehicleLoading.IsEqual(0)) {
-					row[CO2_TKM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton;
-				}
-				if (cargoVolume > 0) {
-					row[CO2_M3KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / cargoVolume;
-				}
-			}
-
-			row[P_WHEEL_POS] = modData.PowerWheelPositive().ConvertTo().Kilo.Watt;
-
-			row[P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertTo().Kilo.Watt;
-
-			foreach (var aux in modData.Auxiliaries) {
-				string colName;
-				if (aux.Key == Constants.Auxiliaries.IDs.PTOConsumer || aux.Key == Constants.Auxiliaries.IDs.PTOTransmission) {
-					colName = string.Format(E_FORMAT, aux.Key);
-				} else {
-					colName = string.Format(E_AUX_FORMAT, aux.Key);
-				}
-
-				if (!Table.Columns.Contains(colName)) {
-					var col = Table.Columns.Add(colName, typeof(SI));
-					// move the new column to correct position
-					col.SetOrdinal(Table.Columns[E_AUX].Ordinal);
-				}
-
-				row[colName] = modData.AuxiliaryWork(aux.Value).ConvertTo().Kilo.Watt.Hour;
-			}
-
-			row[E_FCMAP_POS] = modData.TotalEngineWorkPositive().ConvertTo().Kilo.Watt.Hour;
-			row[E_FCMAP_NEG] = -modData.TotalEngineWorkNegative().ConvertTo().Kilo.Watt.Hour;
-			row[E_POWERTRAIN_INERTIA] = modData.PowerAccelerations().ConvertTo().Kilo.Watt.Hour;
-			row[E_AUX] = modData.WorkAuxiliaries().ConvertTo().Kilo.Watt.Hour;
-			row[E_CLUTCH_LOSS] = modData.WorkClutch().ConvertTo().Kilo.Watt.Hour;
-			row[E_TC_LOSS] = modData.WorkTorqueConverter().ConvertTo().Kilo.Watt.Hour;
-			row[E_SHIFT_LOSS] = modData.WorkGearshift().ConvertTo().Kilo.Watt.Hour;
-			row[E_GBX_LOSS] = modData.WorkGearbox().ConvertTo().Kilo.Watt.Hour;
-			row[E_RET_LOSS] = modData.WorkRetarder().ConvertTo().Kilo.Watt.Hour;
-			row[E_AXL_LOSS] = modData.WorkAxlegear().ConvertTo().Kilo.Watt.Hour;
-			row[E_ANGLE_LOSS] = modData.WorkAngledrive().ConvertTo().Kilo.Watt.Hour;
-			row[E_BRAKE] = modData.WorkTotalMechanicalBrake().ConvertTo().Kilo.Watt.Hour;
-			row[E_VEHICLE_INERTIA] = modData.WorkVehicleInertia().ConvertTo().Kilo.Watt.Hour;
-			row[E_AIR] = modData.WorkAirResistance().ConvertTo().Kilo.Watt.Hour;
-			row[E_ROLL] = modData.WorkRollingResistance().ConvertTo().Kilo.Watt.Hour;
-			row[E_GRAD] = modData.WorkRoadGradientResistance().ConvertTo().Kilo.Watt.Hour;
-
-			//var acc = modData.AccelerationPer3Seconds();
-
-
-			row[ACC] = modData.AccelerationAverage();
-			row[ACC_POS] = modData.AccelerationsPositive();
-			row[ACC_NEG] = modData.AccelerationsNegative();
-			var accTimeShare = modData.AccelerationTimeShare();
-			row[ACC_TIMESHARE] = accTimeShare;
-			var decTimeShare = modData.DecelerationTimeShare();
-			row[DEC_TIMESHARE] = decTimeShare;
-			var cruiseTimeShare = modData.CruiseTimeShare();
-			row[CRUISE_TIMESHARE] = cruiseTimeShare;
-			var stopTimeShare = modData.StopTimeShare();
-			row[STOP_TIMESHARE] = stopTimeShare;
-
-			row[MAX_SPEED] = modData.MaxSpeed().AsKmph.SI<Scalar>();
-			row[MAX_ACCELERATION] = modData.MaxAcceleration();
-			row[MAX_DECELERATION] = modData.MaxDeceleration();
-			row[AVG_ENGINE_SPEED] = modData.AvgEngineSpeed().AsRPM.SI<Scalar>();
-			row[MAX_ENGINE_SPEED] = modData.MaxEngineSpeed().AsRPM.SI<Scalar>();
-
-			row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare();
-			row[COASTING_TIME_SHARE] = modData.CoastingTimeShare();
-			row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare();
-
-			if (gearCount <= 0) {
-				return;
-			}
-
-			row[NUM_GEARSHIFTS] = modData.GearshiftCount();
-			var timeSharePerGear = modData.TimeSharePerGear(gearCount);
-
-			for (uint i = 0; i <= gearCount; i++) {
-				var colName = string.Format(TIME_SHARE_PER_GEAR_FORMAT, i);
-				if (!Table.Columns.Contains(colName)) {
-					Table.Columns.Add(colName, typeof(SI));
-				}
-				row[colName] = timeSharePerGear[i];
-			}
-			if (accTimeShare != null && decTimeShare != null && cruiseTimeShare != null) {
-				var shareSum = accTimeShare + decTimeShare + cruiseTimeShare + stopTimeShare;
-				if (!shareSum.IsEqual(100)) {
-					Log.Error(
-						"Sumfile Error: driving behavior timeshares must sum up to 100%: acc: {0}%, dec: {1}%, cruise: {2}%, stop: {3}%, sum: {4}%",
-						accTimeShare.ToOutputFormat(1, null, false), decTimeShare.ToOutputFormat(1, null, false),
-						cruiseTimeShare.ToOutputFormat(1, null, false), stopTimeShare.ToOutputFormat(1, null, false),
-						shareSum.ToOutputFormat(1, null, false));
-				}
-			}
-		}
-
-		private static string ReplaceNotAllowedCharacters(string text)
-		{
-			return text.Replace('#', '_').Replace(',', '_').Replace('\n', '_').Replace('\r', '_');
-		}
-
-		public void Dispose()
-		{
-			Dispose(true);
-			GC.SuppressFinalize(this);
-		}
-
-		protected void Dispose(bool disposing)
-		{
-			if (disposing) {
-				Table.Dispose();
-			}
-		}
-	}
+using System;
+using System.Data;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.Models.Declaration;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.SimulationComponent.Data;
+
+// ReSharper disable MemberCanBePrivate.Global  -- used by API!
+
+namespace TUGraz.VectoCore.OutputData
+{
+	public delegate void WriteSumData(IModalDataContainer data);
+
+	/// <summary>
+	/// Class for the sum file in vecto.
+	/// </summary>
+	public class SummaryDataContainer : LoggingObject, IDisposable
+	{
+		// ReSharper disable InconsistentNaming
+		public const string INTERNAL_PREFIX = "INTERNAL";
+		public const string SORT = INTERNAL_PREFIX + " Sorting";
+		public const string JOB = "Job [-]";
+		public const string INPUTFILE = "Input File [-]";
+		public const string CYCLE = "Cycle [-]";
+		public const string STATUS = "Status";
+		public const string CURB_MASS = "Chassis curb mass [kg]";
+		public const string LOADING = "Loading [kg]";
+
+		public const string VEHICLE_MANUFACTURER = "Vehicle manufacturer [-]";
+		public const string VIN_NUMBER = "VIN number";
+		public const string VEHICLE_MODEL = "Vehicle model [-]";
+
+		public const string ENGINE_MANUFACTURER = "Engine manufacturer [-]";
+		public const string ENGINE_MODEL = "Engine model [-]";
+		public const string ENGINE_FUEL_TYPE = "Engine fuel type [-]";
+		public const string ENGINE_WHTC_URBAN = "Engine WHTCUrban";
+		public const string ENGINE_WHTC_RURAL = "Engine WHTCRural";
+		public const string ENGINE_WHTC_MOTORWAY = "Engine WHTCMotorway";
+		public const string ENGINE_BF_COLD_HOT = "Engine BFColdHot";
+		public const string ENGINE_CF_REG_PER = "Engine CFRegPer";
+		public const string ENGINE_ACTUAL_CORRECTION_FACTOR = "Engine actual CF";
+		public const string ENGINE_RATED_POWER = "Engine rated power [kW]";
+		public const string ENGINE_IDLING_SPEED = "Engine idling speed [rpm]";
+		public const string ENGINE_RATED_SPEED = "Engine rated speed [rpm]";
+		public const string ENGINE_DISPLACEMENT = "Engine displacement [ccm]";
+
+		public const string ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER = "total RRC [-]";
+		public const string ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER = "weighted RRC w/o trailer [-]";
+
+		public const string GEARBOX_MANUFACTURER = "Gearbox manufacturer [-]";
+		public const string GEARBOX_MODEL = "Gearbox model [-]";
+		public const string GEARBOX_TYPE = "Gearbox type [-]";
+		public const string GEAR_RATIO_FIRST_GEAR = "Gear ratio first gear [-]";
+		public const string GEAR_RATIO_LAST_GEAR = "Gear ratio last gear [-]";
+
+		public const string TORQUECONVERTER_MANUFACTURER = "Torque converter manufacturer [-]";
+		public const string TORQUECONVERTER_MODEL = "Torque converter model [-]";
+
+		public const string RETARDER_MANUFACTURER = "Retarder manufacturer [-]";
+		public const string RETARDER_MODEL = "Retarder model [-]";
+		public const string RETARDER_TYPE = "Retarder type [-]";
+
+		public const string ANGLEDRIVE_MANUFACTURER = "Angledrive manufacturer [-]";
+		public const string ANGLEDRIVE_MODEL = "Angledrive model [-]";
+		public const string ANGLEDRIVE_RATIO = "Angledrive ratio [-]";
+
+		public const string AXLE_MANUFACTURER = "Axle manufacturer [-]";
+		public const string AXLE_MODEL = "Axle model [-]";
+		public const string AXLE_RATIO = "Axle gear ratio [-]";
+
+		public const string AUX_TECH_FORMAT = "Auxiliary technology {0} [-]";
+
+		public const string HDV_CO2_VEHICLE_CLASS = "HDV CO2 vehicle class [-]";
+		public const string TOTAL_VEHICLE_MASS = "Total vehicle mass [kg]";
+		public const string CD_x_A = "CdxA [m²]";
+		//public const string ROLLING_RESISTANCE_COEFFICIENT = "weighed RRC [-]";
+		public const string R_DYN = "r_dyn [m]";
+
+		public const string CARGO_VOLUME = "Cargo Volume [m³]";
+		public const string TIME = "time [s]";
+		public const string DISTANCE = "distance [km]";
+		public const string SPEED = "speed [km/h]";
+		public const string ALTITUDE_DELTA = "altitudeDelta [m]";
+
+		public const string FCMAP_H = "FC-Map [g/h]";
+		public const string FCMAP_KM = "FC-Map [g/km]";
+		public const string FCAUXC_H = "FC-AUXc [g/h]";
+		public const string FCAUXC_KM = "FC-AUXc [g/km]";
+		public const string FCWHTCC_H = "FC-WHTCc [g/h]";
+		public const string FCWHTCC_KM = "FC-WHTCc [g/km]";
+		public const string FCAAUX_H = "FC-AAUX [g/h]";
+		public const string FCAAUX_KM = "FC-AAUX [g/km]";
+
+		public const string FCFINAL_H = "FC-Final [g/h]";
+		public const string FCFINAL_KM = "FC-Final [g/km]";
+		public const string FCFINAL_LITERPER100KM = "FC-Final [l/100km]";
+		public const string FCFINAL_LITERPER100TKM = "FC-Final [l/100tkm]";
+		public const string FCFINAL_LiterPer100M3KM = "FC-Final [l/100m³km]";
+
+		public const string CO2_KM = "CO2 [g/km]";
+		public const string CO2_TKM = "CO2 [g/tkm]";
+		public const string CO2_M3KM = "CO2 [g/m³km]";
+
+		public const string P_WHEEL_POS = "P_wheel_in_pos [kW]";
+		public const string P_FCMAP_POS = "P_fcmap_pos [kW]";
+
+		public const string E_FORMAT = "E_{0} [kWh]";
+		public const string E_AUX_FORMAT = "E_aux_{0} [kWh]";
+		public const string E_AUX = "E_aux_sum [kWh]";
+
+		public const string E_AIR = "E_air [kWh]";
+		public const string E_ROLL = "E_roll [kWh]";
+		public const string E_GRAD = "E_grad [kWh]";
+		public const string E_VEHICLE_INERTIA = "E_vehi_inertia [kWh]";
+		public const string E_POWERTRAIN_INERTIA = "E_powertrain_inertia [kWh]";
+		public const string E_BRAKE = "E_brake [kWh]";
+		public const string E_GBX_LOSS = "E_gbx_loss [kWh]";
+		public const string E_SHIFT_LOSS = "E_shift_loss [kWh]";
+		public const string E_AXL_LOSS = "E_axl_loss [kWh]";
+		public const string E_RET_LOSS = "E_ret_loss [kWh]";
+		public const string E_TC_LOSS = "E_tc_loss [kWh]";
+		public const string E_ANGLE_LOSS = "E_angle_loss [kWh]";
+		public const string E_CLUTCH_LOSS = "E_clutch_loss [kWh]";
+		public const string E_FCMAP_POS = "E_fcmap_pos [kWh]";
+		public const string E_FCMAP_NEG = "E_fcmap_neg [kWh]";
+
+		public const string ACC = "a [m/s^2]";
+		public const string ACC_POS = "a_pos [m/s^2]";
+		public const string ACC_NEG = "a_neg [m/s^2]";
+
+		public const string ACC_TIMESHARE = "AccelerationTimeShare [%]";
+		public const string DEC_TIMESHARE = "DecelerationTimeShare [%]";
+		public const string CRUISE_TIMESHARE = "CruiseTimeShare [%]";
+		public const string STOP_TIMESHARE = "StopTimeShare [%]";
+
+		public const string MAX_SPEED = "max. speed [km/h";
+		public const string MAX_ACCELERATION = "max. acc [m/s²]";
+		public const string MAX_DECELERATION = "max. dec [m/s²]";
+		public const string AVG_ENGINE_SPEED = "n_eng_avg [rpm]";
+		public const string MAX_ENGINE_SPEED = "n_eng_max [rpm]";
+		public const string NUM_GEARSHIFTS = "gear shifts [-]";
+		public const string ENGINE_FULL_LOAD_TIME_SHARE = "Engine max. Load time share [%]";
+		public const string COASTING_TIME_SHARE = "CoastingTimeShare [%]";
+		public const string BRAKING_TIME_SHARE = "BrakingTImeShare [%]";
+
+		public const string TIME_SHARE_PER_GEAR_FORMAT = "Gear {0} TimeShare [%]";
+
+		// ReSharper restore InconsistentNaming
+
+		internal readonly DataTable Table;
+		private readonly ISummaryWriter _sumWriter;
+
+
+		protected SummaryDataContainer() {}
+
+		/// <summary>
+		/// Initializes a new instance of the <see cref="SummaryDataContainer"/> class.
+		/// </summary>
+		/// <param name="writer"></param>
+		public SummaryDataContainer(ISummaryWriter writer)
+		{
+			_sumWriter = writer;
+
+			Table = new DataTable();
+
+			Table.Columns.AddRange(new[] {
+				Tuple.Create(SORT, typeof(int)),
+				Tuple.Create(JOB, typeof(string)),
+				Tuple.Create(INPUTFILE, typeof(string)),
+				Tuple.Create(CYCLE, typeof(string)),
+				Tuple.Create(STATUS, typeof(string)),
+				Tuple.Create(VEHICLE_MANUFACTURER, typeof(string)),
+				Tuple.Create(VIN_NUMBER, typeof(string)),
+				Tuple.Create(VEHICLE_MODEL, typeof(string)),
+				Tuple.Create(HDV_CO2_VEHICLE_CLASS, typeof(string)),
+				Tuple.Create(CURB_MASS, typeof(SI)),
+				Tuple.Create(LOADING, typeof(SI)),
+				Tuple.Create(TOTAL_VEHICLE_MASS, typeof(SI)),
+				Tuple.Create(ENGINE_MANUFACTURER, typeof(string)),
+				Tuple.Create(ENGINE_MODEL, typeof(string)),
+				Tuple.Create(ENGINE_FUEL_TYPE, typeof(string)),
+				Tuple.Create(ENGINE_RATED_POWER, typeof(SI)),
+				Tuple.Create(ENGINE_IDLING_SPEED, typeof(SI)),
+				Tuple.Create(ENGINE_RATED_SPEED, typeof(SI)),
+				Tuple.Create(ENGINE_DISPLACEMENT, typeof(SI)),
+				Tuple.Create(ENGINE_WHTC_URBAN, typeof(double)),
+				Tuple.Create(ENGINE_WHTC_RURAL, typeof(double)),
+				Tuple.Create(ENGINE_WHTC_MOTORWAY, typeof(double)),
+				Tuple.Create(ENGINE_BF_COLD_HOT, typeof(double)),
+				Tuple.Create(ENGINE_CF_REG_PER, typeof(double)),
+				Tuple.Create(ENGINE_ACTUAL_CORRECTION_FACTOR, typeof(double)),
+				Tuple.Create(CD_x_A, typeof(SI)),
+				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER, typeof(double)),
+				Tuple.Create(ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER, typeof(double)),
+				Tuple.Create(R_DYN, typeof(SI)),
+				Tuple.Create(GEARBOX_MANUFACTURER, typeof(string)),
+				Tuple.Create(GEARBOX_MODEL, typeof(string)),
+				Tuple.Create(GEARBOX_TYPE, typeof(string)),
+				Tuple.Create(GEAR_RATIO_FIRST_GEAR, typeof(SI)),
+				Tuple.Create(GEAR_RATIO_LAST_GEAR, typeof(SI)),
+				Tuple.Create(TORQUECONVERTER_MANUFACTURER, typeof(string)),
+				Tuple.Create(TORQUECONVERTER_MODEL, typeof(string)),
+				Tuple.Create(RETARDER_MANUFACTURER, typeof(string)),
+				Tuple.Create(RETARDER_MODEL, typeof(string)),
+				Tuple.Create(RETARDER_TYPE, typeof(string)),
+				Tuple.Create(ANGLEDRIVE_MANUFACTURER, typeof(string)),
+				Tuple.Create(ANGLEDRIVE_MODEL, typeof(string)),
+				Tuple.Create(ANGLEDRIVE_RATIO, typeof(string)),
+				Tuple.Create(AXLE_MANUFACTURER, typeof(string)),
+				Tuple.Create(AXLE_MODEL, typeof(string)),
+				Tuple.Create(AXLE_RATIO, typeof(SI)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.SteeringPump), typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.Fan), typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition),
+					typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.PneumaticSystem), typeof(string)),
+				Tuple.Create(string.Format(AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.ElectricSystem), typeof(string)),
+			}.Select(x => new DataColumn(x.Item1, x.Item2)).ToArray());
+
+			Table.Columns.AddRange(new[] {
+				CARGO_VOLUME,
+				TIME, DISTANCE,
+				SPEED, ALTITUDE_DELTA,
+				FCMAP_H, FCMAP_KM,
+				FCAUXC_H, FCAUXC_KM,
+				FCWHTCC_H, FCWHTCC_KM,
+				FCAAUX_H, FCAAUX_KM,
+				FCFINAL_H, FCFINAL_KM,
+				FCFINAL_LITERPER100KM, FCFINAL_LITERPER100TKM, FCFINAL_LiterPer100M3KM,
+				CO2_KM, CO2_TKM, CO2_M3KM,
+				P_WHEEL_POS, P_FCMAP_POS,
+				E_FCMAP_POS, E_FCMAP_NEG, E_POWERTRAIN_INERTIA,
+				E_AUX, E_CLUTCH_LOSS, E_TC_LOSS, E_SHIFT_LOSS, E_GBX_LOSS,
+				E_RET_LOSS, E_ANGLE_LOSS, E_AXL_LOSS, E_BRAKE, E_VEHICLE_INERTIA, E_AIR, E_ROLL, E_GRAD,
+				ACC, ACC_POS, ACC_NEG, ACC_TIMESHARE, DEC_TIMESHARE, CRUISE_TIMESHARE, STOP_TIMESHARE,
+				MAX_SPEED, MAX_ACCELERATION, MAX_DECELERATION, AVG_ENGINE_SPEED, MAX_ENGINE_SPEED, NUM_GEARSHIFTS,
+				ENGINE_FULL_LOAD_TIME_SHARE, COASTING_TIME_SHARE, BRAKING_TIME_SHARE
+			}.Select(x => new DataColumn(x, typeof(SI))).ToArray());
+		}
+
+		/// <summary>
+		/// Finishes the summary data container (writes the data to the sumWriter).
+		/// </summary>
+		public virtual void Finish()
+		{
+			if (_sumWriter != null) {
+				var view = new DataView(Table, "", SORT, DataViewRowState.CurrentRows).ToTable();
+				var toRemove =
+					view.Columns.Cast<DataColumn>().Where(column => column.ColumnName.StartsWith(INTERNAL_PREFIX)).ToList();
+				foreach (var dataColumn in toRemove) {
+					view.Columns.Remove(dataColumn);
+				}
+				_sumWriter.WriteSumData(view);
+			}
+		}
+
+		/// <summary>
+		/// Writes the result of one run into the summary data container.
+		/// </summary>
+		[MethodImpl(MethodImplOptions.Synchronized)]
+		//public virtual void Write(IModalDataContainer modData, string jobFileName, string jobName, string cycleFileName,
+		//	Kilogram vehicleMass, Kilogram vehicleLoading, CubicMeter cargoVolume, uint gearCount)
+		public virtual void Write(IModalDataContainer modData, int jobNr, int runNr, VectoRunData runData)
+		{
+			var row = Table.NewRow();
+			Table.Rows.Add(row);
+
+			row[SORT] = jobNr * 1000 + runNr;
+			row[JOB] = string.Format("{0}-{1}", jobNr, runNr); //ReplaceNotAllowedCharacters(current);
+			row[INPUTFILE] = ReplaceNotAllowedCharacters(runData.JobName);
+			row[CYCLE] = ReplaceNotAllowedCharacters(runData.Cycle.Name + Constants.FileExtensions.CycleFile);
+
+			row[STATUS] = modData.RunStatus;
+
+			var vehicleLoading = 0.SI<Kilogram>();
+			var cargoVolume = 0.SI<CubicMeter>();
+			uint gearCount = 0u;
+			if (runData.Cycle.CycleType != CycleType.EngineOnly) {
+				row[VEHICLE_MANUFACTURER] = runData.VehicleData.Manufacturer;
+				row[VIN_NUMBER] = runData.VehicleData.VIN;
+				row[VEHICLE_MODEL] = runData.VehicleData.ModelName;
+
+				row[HDV_CO2_VEHICLE_CLASS] = runData.VehicleData.VehicleClass.GetClassNumber();
+				row[CURB_MASS] = runData.VehicleData.CurbWeight;
+				// - (runData.VehicleData.BodyAndTrailerWeight ?? 0.SI<Kilogram>());
+				row[LOADING] = runData.VehicleData.Loading;
+				row[CARGO_VOLUME] = runData.VehicleData.CargoVolume;
+
+				row[TOTAL_VEHICLE_MASS] = runData.VehicleData.TotalVehicleWeight;
+				row[ENGINE_MANUFACTURER] = runData.EngineData.Manufacturer;
+				row[ENGINE_MODEL] = runData.EngineData.ModelName;
+				row[ENGINE_FUEL_TYPE] = runData.EngineData.FuelType.GetLabel();
+				row[ENGINE_RATED_POWER] = runData.EngineData.RatedPowerDeclared != null
+					? runData.EngineData.RatedPowerDeclared.ConvertTo().Kilo.Watt
+					: runData.EngineData.FullLoadCurves[0].MaxPower.ConvertTo().Kilo.Watt;
+				row[ENGINE_IDLING_SPEED] = runData.EngineData.IdleSpeed.AsRPM.SI<Scalar>();
+				row[ENGINE_RATED_SPEED] = runData.EngineData.RatedSpeedDeclared != null
+					? runData.EngineData.RatedSpeedDeclared.AsRPM.SI<Scalar>()
+					: runData.EngineData.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>();
+				row[ENGINE_DISPLACEMENT] = runData.EngineData.Displacement.ConvertTo().Cubic.Centi.Meter;
+
+				row[ENGINE_WHTC_URBAN] = runData.EngineData.WHTCUrban;
+				row[ENGINE_WHTC_RURAL] = runData.EngineData.WHTCRural;
+				row[ENGINE_WHTC_MOTORWAY] = runData.EngineData.WHTCMotorway;
+				row[ENGINE_BF_COLD_HOT] = runData.EngineData.ColdHotCorrectionFactor;
+				row[ENGINE_CF_REG_PER] = runData.EngineData.CorrectionFactorRegPer;
+				row[ENGINE_ACTUAL_CORRECTION_FACTOR] = runData.EngineData.FuelConsumptionCorrectionFactor;
+
+				row[CD_x_A] = runData.AirdragData.CrossWindCorrectionCurve.AirDragArea;
+
+				row[ROLLING_RESISTANCE_COEFFICIENT_WO_TRAILER] =
+					runData.VehicleData.RollResistanceCoefficientWithoutTrailer;
+				row[ROLLING_RESISTANCE_COEFFICIENT_W_TRAILER] =
+					runData.VehicleData.TotalRollResistanceCoefficient;
+
+				row[R_DYN] = runData.VehicleData.DynamicTyreRadius;
+
+				row[GEARBOX_MANUFACTURER] = runData.GearboxData.Manufacturer;
+				row[GEARBOX_MODEL] = runData.GearboxData.ModelName;
+				row[GEARBOX_TYPE] = runData.GearboxData.Type;
+				if (runData.GearboxData.Type.AutomaticTransmission()) {
+					row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
+						? (double.IsNaN(runData.GearboxData.Gears.First().Value.Ratio)
+							? runData.GearboxData.Gears.First().Value.TorqueConverterRatio.SI<Scalar>()
+							: runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>())
+						: 0.SI<Scalar>();
+					row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0
+						? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
+						: 0.SI<Scalar>();
+					row[TORQUECONVERTER_MANUFACTURER] = runData.GearboxData.TorqueConverterData.Manufacturer;
+					row[TORQUECONVERTER_MODEL] = runData.GearboxData.TorqueConverterData.ModelName;
+				} else {
+					row[GEAR_RATIO_FIRST_GEAR] = runData.GearboxData.Gears.Count > 0
+						? runData.GearboxData.Gears.First().Value.Ratio.SI<Scalar>()
+						: 0.SI<Scalar>();
+					row[GEAR_RATIO_LAST_GEAR] = runData.GearboxData.Gears.Count > 0
+						? runData.GearboxData.Gears.Last().Value.Ratio.SI<Scalar>()
+						: 0.SI<Scalar>();
+					row[TORQUECONVERTER_MANUFACTURER] = "n.a.";
+					row[TORQUECONVERTER_MODEL] = "n.a.";
+				}
+				row[RETARDER_TYPE] = runData.Retarder.Type.GetLabel();
+				if (runData.Retarder.Type.IsDedicatedComponent()) {
+					row[RETARDER_MANUFACTURER] = runData.Retarder.Manufacturer;
+					row[RETARDER_MODEL] = runData.Retarder.ModelName;
+				} else {
+					row[RETARDER_MANUFACTURER] = "n.a.";
+					row[RETARDER_MODEL] = "n.a.";
+				}
+
+				if (runData.AngledriveData != null) {
+					row[ANGLEDRIVE_MANUFACTURER] = runData.AngledriveData.Manufacturer;
+					row[ANGLEDRIVE_MODEL] = runData.AngledriveData.ModelName;
+					row[ANGLEDRIVE_RATIO] = runData.AngledriveData.Angledrive.Ratio;
+				} else {
+					row[ANGLEDRIVE_MANUFACTURER] = "n.a.";
+					row[ANGLEDRIVE_MODEL] = "n.a.";
+					row[ANGLEDRIVE_RATIO] = "n.a.";
+				}
+
+				row[AXLE_MANUFACTURER] = runData.AxleGearData.Manufacturer;
+				row[AXLE_MODEL] = runData.AxleGearData.ModelName;
+				row[AXLE_RATIO] = runData.AxleGearData.AxleGear.Ratio.SI<Scalar>();
+
+				foreach (var aux in runData.Aux) {
+					if (aux.ID == Constants.Auxiliaries.IDs.PTOConsumer || aux.ID == Constants.Auxiliaries.IDs.PTOTransmission) {
+						continue;
+					}
+					var colName = string.Format(AUX_TECH_FORMAT, aux.ID);
+
+					if (!Table.Columns.Contains(colName)) {
+						var col = Table.Columns.Add(colName, typeof(string));
+						// move the new column to correct position
+						col.SetOrdinal(Table.Columns[CARGO_VOLUME].Ordinal);
+					}
+
+					row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology);
+				}
+
+				cargoVolume = runData.VehicleData.CargoVolume;
+				vehicleLoading = runData.VehicleData.Loading;
+				gearCount = (uint)runData.GearboxData.Gears.Count;
+			}
+
+
+			var totalTime = modData.Duration();
+			row[TIME] = totalTime;
+
+			var distance = modData.Distance();
+			if (distance != null) {
+				row[DISTANCE] = distance.ConvertTo().Kilo.Meter;
+			}
+
+			var speed = modData.Speed();
+			if (speed != null) {
+				row[SPEED] = speed.ConvertTo().Kilo.Meter.Per.Hour;
+			}
+
+			row[ALTITUDE_DELTA] = modData.AltitudeDelta();
+
+			row[FCMAP_H] = modData.FCMapPerSecond().ConvertTo().Gramm.Per.Hour;
+			var fcMapPerMeter = modData.FCMapPerMeter();
+			if (fcMapPerMeter != null) {
+				row[FCMAP_KM] = fcMapPerMeter.ConvertTo().Gramm.Per.Kilo.Meter;
+			}
+
+			row[FCAUXC_H] = modData.FuelConsumptionAuxStartStopPerSecond().ConvertTo().Gramm.Per.Hour;
+			var fuelConsumptionAuxStartStopCorrected = modData.FuelConsumptionAuxStartStop();
+			if (fuelConsumptionAuxStartStopCorrected != null) {
+				row[FCAUXC_KM] = fuelConsumptionAuxStartStopCorrected.ConvertTo().Gramm.Per.Kilo.Meter;
+			}
+
+			row[FCWHTCC_H] = modData.FuelConsumptionWHTCPerSecond().ConvertTo().Gramm.Per.Hour;
+			var fuelConsumptionWHTCCorrected = modData.FuelConsumptionWHTC();
+			if (fuelConsumptionWHTCCorrected != null) {
+				row[FCWHTCC_KM] = fuelConsumptionWHTCCorrected.ConvertTo().Gramm.Per.Kilo.Meter;
+			}
+
+			row[FCAAUX_H] = modData.FuelConsumptionAAUXPerSecond().ConvertTo().Gramm.Per.Hour;
+			var fuelConsumptionAaux = modData.FuelConsumptionAAUX();
+			if (fuelConsumptionAaux != null) {
+				row[FCAAUX_KM] = fuelConsumptionAaux.ConvertTo().Gramm.Per.Kilo.Meter;
+			}
+
+			row[FCFINAL_H] = modData.FuelConsumptionFinalPerSecond().ConvertTo().Gramm.Per.Hour;
+			var fcfinal = modData.FuelConsumptionFinal();
+			if (fcfinal != null) {
+				row[FCFINAL_KM] = fcfinal.ConvertTo().Gramm.Per.Kilo.Meter;
+			}
+
+			var fcPer100lkm = modData.FuelConsumptionFinalLiterPer100Kilometer();
+			row[FCFINAL_LITERPER100KM] = fcPer100lkm;
+			if (vehicleLoading != null && !vehicleLoading.IsEqual(0) && fcPer100lkm != null) {
+				row[FCFINAL_LITERPER100TKM] = fcPer100lkm /
+											vehicleLoading.ConvertTo().Ton;
+			}
+			if (cargoVolume > 0 && fcPer100lkm != null) {
+				row[FCFINAL_LiterPer100M3KM] = fcPer100lkm / cargoVolume;
+			}
+
+			var kilogramPerMeter = modData.CO2PerMeter();
+			if (kilogramPerMeter != null) {
+				row[CO2_KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter;
+				if (vehicleLoading != null && !vehicleLoading.IsEqual(0)) {
+					row[CO2_TKM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / vehicleLoading.ConvertTo().Ton;
+				}
+				if (cargoVolume > 0) {
+					row[CO2_M3KM] = kilogramPerMeter.ConvertTo().Gramm.Per.Kilo.Meter / cargoVolume;
+				}
+			}
+
+			row[P_WHEEL_POS] = modData.PowerWheelPositive().ConvertTo().Kilo.Watt;
+
+			row[P_FCMAP_POS] = modData.TotalPowerEnginePositiveAverage().ConvertTo().Kilo.Watt;
+
+			foreach (var aux in modData.Auxiliaries) {
+				string colName;
+				if (aux.Key == Constants.Auxiliaries.IDs.PTOConsumer || aux.Key == Constants.Auxiliaries.IDs.PTOTransmission) {
+					colName = string.Format(E_FORMAT, aux.Key);
+				} else {
+					colName = string.Format(E_AUX_FORMAT, aux.Key);
+				}
+
+				if (!Table.Columns.Contains(colName)) {
+					var col = Table.Columns.Add(colName, typeof(SI));
+					// move the new column to correct position
+					col.SetOrdinal(Table.Columns[E_AUX].Ordinal);
+				}
+
+				row[colName] = modData.AuxiliaryWork(aux.Value).ConvertTo().Kilo.Watt.Hour;
+			}
+
+			row[E_FCMAP_POS] = modData.TotalEngineWorkPositive().ConvertTo().Kilo.Watt.Hour;
+			row[E_FCMAP_NEG] = -modData.TotalEngineWorkNegative().ConvertTo().Kilo.Watt.Hour;
+			row[E_POWERTRAIN_INERTIA] = modData.PowerAccelerations().ConvertTo().Kilo.Watt.Hour;
+			row[E_AUX] = modData.WorkAuxiliaries().ConvertTo().Kilo.Watt.Hour;
+			row[E_CLUTCH_LOSS] = modData.WorkClutch().ConvertTo().Kilo.Watt.Hour;
+			row[E_TC_LOSS] = modData.WorkTorqueConverter().ConvertTo().Kilo.Watt.Hour;
+			row[E_SHIFT_LOSS] = modData.WorkGearshift().ConvertTo().Kilo.Watt.Hour;
+			row[E_GBX_LOSS] = modData.WorkGearbox().ConvertTo().Kilo.Watt.Hour;
+			row[E_RET_LOSS] = modData.WorkRetarder().ConvertTo().Kilo.Watt.Hour;
+			row[E_AXL_LOSS] = modData.WorkAxlegear().ConvertTo().Kilo.Watt.Hour;
+			row[E_ANGLE_LOSS] = modData.WorkAngledrive().ConvertTo().Kilo.Watt.Hour;
+			row[E_BRAKE] = modData.WorkTotalMechanicalBrake().ConvertTo().Kilo.Watt.Hour;
+			row[E_VEHICLE_INERTIA] = modData.WorkVehicleInertia().ConvertTo().Kilo.Watt.Hour;
+			row[E_AIR] = modData.WorkAirResistance().ConvertTo().Kilo.Watt.Hour;
+			row[E_ROLL] = modData.WorkRollingResistance().ConvertTo().Kilo.Watt.Hour;
+			row[E_GRAD] = modData.WorkRoadGradientResistance().ConvertTo().Kilo.Watt.Hour;
+
+			//var acc = modData.AccelerationPer3Seconds();
+
+
+			row[ACC] = modData.AccelerationAverage();
+			row[ACC_POS] = modData.AccelerationsPositive();
+			row[ACC_NEG] = modData.AccelerationsNegative();
+			var accTimeShare = modData.AccelerationTimeShare();
+			row[ACC_TIMESHARE] = accTimeShare;
+			var decTimeShare = modData.DecelerationTimeShare();
+			row[DEC_TIMESHARE] = decTimeShare;
+			var cruiseTimeShare = modData.CruiseTimeShare();
+			row[CRUISE_TIMESHARE] = cruiseTimeShare;
+			var stopTimeShare = modData.StopTimeShare();
+			row[STOP_TIMESHARE] = stopTimeShare;
+
+			row[MAX_SPEED] = modData.MaxSpeed().AsKmph.SI<Scalar>();
+			row[MAX_ACCELERATION] = modData.MaxAcceleration();
+			row[MAX_DECELERATION] = modData.MaxDeceleration();
+			row[AVG_ENGINE_SPEED] = modData.AvgEngineSpeed().AsRPM.SI<Scalar>();
+			row[MAX_ENGINE_SPEED] = modData.MaxEngineSpeed().AsRPM.SI<Scalar>();
+
+			row[ENGINE_FULL_LOAD_TIME_SHARE] = modData.EngineMaxLoadTimeShare();
+			row[COASTING_TIME_SHARE] = modData.CoastingTimeShare();
+			row[BRAKING_TIME_SHARE] = modData.BrakingTimeShare();
+
+			if (gearCount <= 0) {
+				return;
+			}
+
+			row[NUM_GEARSHIFTS] = modData.GearshiftCount();
+			var timeSharePerGear = modData.TimeSharePerGear(gearCount);
+
+			for (uint i = 0; i <= gearCount; i++) {
+				var colName = string.Format(TIME_SHARE_PER_GEAR_FORMAT, i);
+				if (!Table.Columns.Contains(colName)) {
+					Table.Columns.Add(colName, typeof(SI));
+				}
+				row[colName] = timeSharePerGear[i];
+			}
+			if (accTimeShare != null && decTimeShare != null && cruiseTimeShare != null) {
+				var shareSum = accTimeShare + decTimeShare + cruiseTimeShare + stopTimeShare;
+				if (!shareSum.IsEqual(100)) {
+					Log.Error(
+						"Sumfile Error: driving behavior timeshares must sum up to 100%: acc: {0}%, dec: {1}%, cruise: {2}%, stop: {3}%, sum: {4}%",
+						accTimeShare.ToOutputFormat(1, null, false), decTimeShare.ToOutputFormat(1, null, false),
+						cruiseTimeShare.ToOutputFormat(1, null, false), stopTimeShare.ToOutputFormat(1, null, false),
+						shareSum.ToOutputFormat(1, null, false));
+				}
+			}
+		}
+
+		private static string ReplaceNotAllowedCharacters(string text)
+		{
+			return text.Replace('#', '_').Replace(',', '_').Replace('\n', '_').Replace('\r', '_');
+		}
+
+		public void Dispose()
+		{
+			Dispose(true);
+			GC.SuppressFinalize(this);
+		}
+
+		protected void Dispose(bool disposing)
+		{
+			if (disposing) {
+				Table.Dispose();
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs
index 5ed3af872f8f3e5b03d2f8f18c1ea0d7d75a19d0..660c3311774a1ec69c9a3647edf6765bd8c858cb 100644
--- a/VectoCore/VectoCoreTest/Reports/ModDataTest.cs
+++ b/VectoCore/VectoCoreTest/Reports/ModDataTest.cs
@@ -29,475 +29,480 @@
 *   Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology
 */
 
-using System;
-using System.Collections.Generic;
-using System.Data;
-using System.Linq;
-using NUnit.Framework;
-using TUGraz.VectoCommon.InputData;
-using TUGraz.VectoCommon.Models;
-using TUGraz.VectoCommon.Utils;
-using TUGraz.VectoCore.Configuration;
-using TUGraz.VectoCore.InputData.FileIO.JSON;
-using TUGraz.VectoCore.Models.Simulation.Data;
-using TUGraz.VectoCore.Models.Simulation.Impl;
-using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
-using TUGraz.VectoCore.Models.SimulationComponent.Impl;
-using TUGraz.VectoCore.OutputData;
-using TUGraz.VectoCore.OutputData.FileIO;
-using TUGraz.VectoCore.Tests.Integration;
-using TUGraz.VectoCore.Tests.Utils;
-using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
-
-namespace TUGraz.VectoCore.Tests.Reports
-{
-	[TestFixture]
-	public class ModDataTest
-	{
-		[TestCase()]
-		public void ModDataIntegritySimpleTest()
-		{
-			var cycleData = new[] {
-				// <s>,<v>,<grad>,<stop>
-				"  0,  20, 0,    0",
-				" 100, 60, 0,    0",
-				"1000, 60, 0,    0",
-				"1500, 40, 1,    0",
-				"2000, 50,-1,    0",
-				"2500,  0, 0,    2"
-			};
-			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
-			var sumData = new SummaryDataContainer(null);
-			var run = Truck40tPowerTrain.CreateEngineeringRun(cycle, "Truck_ModDataIntegrity.vmod");
-
-			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(Truck40tPowerTrain.EngineFile, 0);
-
-			// get a reference to the mod-data because the modaldata container clears it after simulation
-			var modData = ((ModalDataContainer)run.GetContainer().ModalData).Data;
-			var auxKeys = ((ModalDataContainer)run.GetContainer().ModalData).Auxiliaries;
-
-			run.Run();
-			Assert.IsTrue(run.FinishedWithoutErrors);
-
-			AssertModDataIntegrity(modData, auxKeys, cycle.Entries.Last().Distance, engineData.ConsumptionMap);
-		}
-
-		[TestCase(@"TestData\Integration\DeclarationMode\Class2_RigidTruck_4x2\Class2_RigidTruck_DECL.vecto")]
-		public void TestFullCycleModDataIntegrityDeclMT(string jobName)
-		{
-			RunSimulation(jobName, ExecutionMode.Declaration);
-		}
-
-		[TestCase(@"TestData\Integration\EngineeringMode\Class2_RigidTruck_4x2\Class2_RigidTruck_ENG.vecto"),
-		TestCase(@"TestData\Integration\EngineeringMode\Class5_Tractor_4x2\Class5_Tractor_ENG.vecto"),
-		TestCase(@"TestData\Integration\EngineeringMode\Class9_RigidTruck_6x2_PTO\Class9_RigidTruck_ENG_PTO.vecto"),]
-		public void TestFullCycleModDataIntegrityMT(string jobName)
-		{
-			RunSimulation(jobName, ExecutionMode.Engineering);
-		}
-
-		private static void RunSimulation(string jobName, ExecutionMode mode)
-		{
-			var fileWriter = new FileOutputWriter(jobName);
-			var sumData = new SummaryDataContainer(fileWriter);
-
-			var jobContainer = new JobContainer(sumData);
-			var inputData = JSONInputDataFactory.ReadJsonJob(jobName);
-
-			var runsFactory = new SimulatorFactory(mode, inputData, fileWriter) { WriteModalResults = true };
-
-			jobContainer.AddRuns(runsFactory);
-			var modData = new List<Tuple<ModalResults, Meter>>();
-			foreach (var run in jobContainer.Runs) {
-				modData.Add(Tuple.Create(((ModalDataContainer)run.Run.GetContainer().ModalData).Data,
-					((DistanceBasedDrivingCycle)((VehicleContainer)run.Run.GetContainer()).DrivingCycle).Data.Entries.Last()
-					.Distance));
-			}
-			var auxKeys =
-				new Dictionary<string, DataColumn>(
-					((ModalDataContainer)jobContainer.Runs.First().Run.GetContainer().ModalData).Auxiliaries);
-			jobContainer.Execute();
-			jobContainer.WaitFinished();
-
-			// mod files will be stored in e.g. 
-			// VectoCoreTest\bin\Debug\TestData\Integration\EngineeringMode\Class2_RigidTruck_4x2\Class2_RigidTruck_ENG.vecto_00.vmod
-			//fileWriter.WriteModData(Path.GetFileName(jobName), "0", "0", modData[0].Item1);
-			//fileWriter.WriteModData(Path.GetFileName(jobName), "1", "1", modData[1].Item1);
-
-			foreach (var modalResults in modData) {
-				AssertModDataIntegrity(modalResults.Item1, auxKeys, modalResults.Item2,
-					FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).EngineInputData.FuelConsumptionMap));
-			}
-
-			AssertSumDataIntegrity(sumData, mode);
-		}
-
-		private static void AssertSumDataIntegrity(SummaryDataContainer sumData, ExecutionMode mode)
-		{
-			Assert.IsTrue(sumData.Table.Rows.Count > 0);
-
-			var ptoTransmissionColumn =
-				sumData.Table.Columns.Contains(string.Format(SummaryDataContainer.E_FORMAT,
-					Constants.Auxiliaries.IDs.PTOTransmission))
-					? string.Format(SummaryDataContainer.E_FORMAT, Constants.Auxiliaries.IDs.PTOTransmission)
-					: null;
-			var ptoConsumerColumn =
-				sumData.Table.Columns.Contains(string.Format(SummaryDataContainer.E_FORMAT, Constants.Auxiliaries.IDs.PTOConsumer))
-					? string.Format(SummaryDataContainer.E_FORMAT, Constants.Auxiliaries.IDs.PTOConsumer)
-					: null;
-
-			foreach (DataRow row in sumData.Table.Rows) {
-				var inputFile = row[SummaryDataContainer.INPUTFILE].ToString();
-				var cycle = row[SummaryDataContainer.CYCLE].ToString();
-				var loading = row[SummaryDataContainer.LOADING].ToString();
-				var eFcMapPos = ((SI)row[SummaryDataContainer.E_FCMAP_POS]).Value();
-				var eFcMapNeg = ((SI)row[SummaryDataContainer.E_FCMAP_NEG]).Value();
-				var ePowertrainInertia = ((SI)row[SummaryDataContainer.E_POWERTRAIN_INERTIA]).Value();
-				var eAux = ((SI)row[SummaryDataContainer.E_AUX]).Value();
-				var eClutchLoss = ((SI)row[SummaryDataContainer.E_CLUTCH_LOSS]).Value();
-				var eTcLoss = ((SI)row[SummaryDataContainer.E_TC_LOSS]).Value();
-				//var eShiftLoss = ((SI)row[SummaryDataContainer.E_SHIFT_LOSS]).Value();
-				var eGbxLoss = ((SI)row[SummaryDataContainer.E_GBX_LOSS]).Value();
-				var eRetLoss = ((SI)row[SummaryDataContainer.E_RET_LOSS]).Value();
-				var eAngleLoss = ((SI)row[SummaryDataContainer.E_ANGLE_LOSS]).Value();
-				var eAxlLoss = ((SI)row[SummaryDataContainer.E_AXL_LOSS]).Value();
-				var eBrakeLoss = ((SI)row[SummaryDataContainer.E_BRAKE]).Value();
-				var eVehInertia = ((SI)row[SummaryDataContainer.E_VEHICLE_INERTIA]).Value();
-				var eAir = ((SI)row[SummaryDataContainer.E_AIR]).Value();
-				var eRoll = ((SI)row[SummaryDataContainer.E_ROLL]).Value();
-				var eGrad = ((SI)row[SummaryDataContainer.E_GRAD]).Value();
-				var cargoVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CARGO_VOLUME]).Value();
-
-				var loadingValue = ((SI)row[SummaryDataContainer.LOADING]).Value() / 1000;
-				var fcPer100km = ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]).Value();
-				var fcPerVolume = mode == ExecutionMode.Engineering
-					? 0
-					: ((SI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]).Value();
-				var fcPerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]).Value() : 0;
-				var co2Per100km = ((SI)row[SummaryDataContainer.CO2_KM]).Value();
-				var co2PerVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CO2_M3KM]).Value();
-				var co2PerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.CO2_TKM]).Value() : 0;
-
-				var ePTOtransm = ptoTransmissionColumn != null ? ((SI)row[ptoTransmissionColumn]).Value() : 0;
-				var ePTOconsumer = ptoConsumerColumn != null ? ((SI)row[ptoConsumerColumn]).Value() : 0;
-
-				// E_fcmap_pos = E_fcmap_neg + E_powertrain_inertia + E_aux_xxx + E_aux_sum + E_clutch_loss + E_tc_loss + E_gbx_loss + E_shift_loss + E_ret_loss + E_angle_loss + E_axl_loss + E_brake + E_vehicle_inertia + E_air + E_roll + E_grad + E_PTO_CONSUM + E_PTO_TRANSM
-				Assert.AreEqual(eFcMapPos,
-					eFcMapNeg + ePowertrainInertia + eAux + eClutchLoss + eTcLoss + eGbxLoss + eRetLoss + eAngleLoss +
-					eAxlLoss + eBrakeLoss + eVehInertia + eAir + eRoll + eGrad + ePTOconsumer + ePTOtransm, 1e-5,
-					"input file: {0}  cycle: {1} loading: {2}",
-					inputFile, cycle, loading);
-
-				var pFcmapPos = ((SI)row[SummaryDataContainer.P_FCMAP_POS]).Value();
-				var time = ((SI)row[SummaryDataContainer.TIME]).Value();
-
-				// E_fcmap_pos = P_fcmap_pos * t
-				Assert.AreEqual(eFcMapPos, pFcmapPos * (time / 3600), 1e-3, "input file: {0}  cycle: {1} loading: {2}", inputFile,
-					cycle, loading);
-
-				if (cargoVolume > 0) {
-					Assert.AreEqual(fcPerVolume, fcPer100km / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}", inputFile,
-						cycle, loading);
-
-					Assert.AreEqual(co2PerVolume, co2Per100km / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
-						inputFile,
-						cycle, loading);
-				}
-
-				if (loadingValue > 0) {
-					Assert.AreEqual(co2PerLoad, co2Per100km / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
-						inputFile, cycle, loading);
-					Assert.AreEqual(fcPerLoad, fcPer100km / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
-						inputFile, cycle, loading);
-				}
-
-				var stopTimeShare = ((SI)row[SummaryDataContainer.STOP_TIMESHARE]).Value();
-				var accTimeShare = ((SI)row[SummaryDataContainer.ACC_TIMESHARE]).Value();
-				var decTimeShare = ((SI)row[SummaryDataContainer.DEC_TIMESHARE]).Value();
-				var cruiseTimeShare = ((SI)row[SummaryDataContainer.CRUISE_TIMESHARE]).Value();
-
-				Assert.AreEqual(100, stopTimeShare + accTimeShare + decTimeShare + cruiseTimeShare, 1e-3,
-					"input file: {0}  cycle: {1} loading: {2}", inputFile, cycle, loading);
-
-				Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_POS]).Value() > 0);
-				Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_NEG]).Value() < 0);
-			}
-		}
-
-		private static void AssertModDataIntegrity(ModalResults modData, Dictionary<string, DataColumn> auxKeys,
-			Meter totalDistance, FuelConsumptionMap consumptionMap)
-		{
-			Assert.IsTrue(modData.Rows.Count > 0);
-
-			var ptoTransmissionColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOTransmission)
-				? auxKeys[Constants.Auxiliaries.IDs.PTOTransmission]
-				: null;
-			var ptoConsumerColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOConsumer)
-				? auxKeys[Constants.Auxiliaries.IDs.PTOConsumer]
-				: null;
-			foreach (DataRow row in modData.Rows) {
-				if (totalDistance.IsEqual(((Meter)row[(int)ModalResultField.dist]))) {
-					continue;
-				}
-				var gear = (uint)row[(int)ModalResultField.Gear];
-				var time = (Second)row[(int)ModalResultField.time];
-
-				var distance = (Meter)row[(int)ModalResultField.dist];
-				var tqEngFcmap = (NewtonMeter)row[(int)ModalResultField.T_eng_fcmap];
-				var nEngFcMap = (PerSecond)row[(int)ModalResultField.n_eng_avg];
-
-				// check fuel consumption interpolation
-				var fuelConsumption = (SI)row[(int)ModalResultField.FCMap];
-				Assert.AreEqual(fuelConsumption.Value(),
-					consumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value.Value(), 1E-3, "time: {0}  distance: {1}",
-					time, distance);
-
-				// check P_eng_FCmap = T_eng_fcmap * n_eng
-				var pEngFcmap = (SI)row[(int)ModalResultField.P_eng_fcmap];
-				Assert.AreEqual(pEngFcmap.Value(), (tqEngFcmap * nEngFcMap).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				var pWheelIn = (Watt)row[(int)ModalResultField.P_wheel_in];
-				var pAir = (Watt)row[(int)ModalResultField.P_air];
-				var pRoll = (Watt)row[(int)ModalResultField.P_roll];
-				var pGrad = (Watt)row[(int)ModalResultField.P_slope];
-				var pVehInertia = (Watt)row[(int)ModalResultField.P_veh_inertia];
-				var pTrac = (Watt)row[(int)ModalResultField.P_trac];
-
-				// P_eng_out = P_wheel + P_lossgearbox + P_lossaxle + P_lossretarder + P_agbx + Pa_eng + P_aux - P_brake_loss
-				var pEngOut = (Watt)row[(int)ModalResultField.P_eng_out];
-				var pLossGbx = (Watt)row[(int)ModalResultField.P_gbx_loss];
-				var pGbxIn = (Watt)row[(int)ModalResultField.P_gbx_in];
-				var pLossAxle = (Watt)row[(int)ModalResultField.P_axle_loss];
-				var pLossAngle = row[(int)ModalResultField.P_angle_loss] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[(int)ModalResultField.P_angle_loss];
-				var pAxleIn = (Watt)row[(int)ModalResultField.P_axle_in];
-				var pLossRet = (Watt)row[(int)ModalResultField.P_ret_loss];
-				var pRetIn = (Watt)row[(int)ModalResultField.P_retarder_in];
-				var pGbxInertia = (Watt)row[(int)ModalResultField.P_gbx_inertia];
-				var pShiftLoss = row[(int)ModalResultField.P_gbx_shift_loss] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[(int)ModalResultField.P_gbx_shift_loss];
-				var pEngInertia = (Watt)row[(int)ModalResultField.P_eng_inertia];
-				var pAux =
-					(Watt)(row[(int)ModalResultField.P_aux] != DBNull.Value ? row[(int)ModalResultField.P_aux] : 0.SI<Watt>());
-				var pBrakeLoss = (Watt)row[(int)ModalResultField.P_brake_loss];
-				var pBrakeIn = (Watt)row[(int)ModalResultField.P_brake_in];
-
-				var pWheelInertia = (Watt)row[(int)ModalResultField.P_wheel_inertia];
-				var pPTOconsumer = ptoConsumerColumn == null || row[ptoConsumerColumn.ColumnName] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[ptoConsumerColumn.ColumnName];
-				var pPTOtransm = ptoTransmissionColumn == null || row[ptoTransmissionColumn.ColumnName] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[ptoTransmissionColumn.ColumnName];
-				// P_trac = P_veh_inertia + P_roll + P_air + P_slope
-				Assert.AreEqual(pTrac.Value(), (pAir + pRoll + pGrad + pVehInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				// P_wheel_in = P_trac + P_wheel_inertia
-				Assert.AreEqual(pWheelIn.Value(), (pTrac + pWheelInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.AreEqual(pBrakeIn.Value(), (pWheelIn + pBrakeLoss).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.AreEqual(pAxleIn.Value(), (pBrakeIn + pLossAxle).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-
-				Assert.AreEqual(pRetIn.Value(), (pAxleIn + pLossRet).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-
-				var pClutchLoss = (Watt)(row[(int)ModalResultField.P_clutch_loss] != DBNull.Value
-					? row[(int)ModalResultField.P_clutch_loss]
-					: 0.SI<Watt>());
-
-				var pClutchOut = row[(int)ModalResultField.P_clutch_out];
-				if (pClutchOut != DBNull.Value) {
-					Assert.AreEqual(pGbxIn.Value(), (pClutchOut as Watt).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-					Assert.AreEqual(pEngOut.Value(), (pClutchOut as Watt + pClutchLoss).Value(), 1E-3, "time: {0}  distance: {1}",
-						time, distance);
-				}
-
-				var pTC_Loss = (Watt)(row[(int)ModalResultField.P_TC_loss] != DBNull.Value
-					? row[(int)ModalResultField.P_TC_loss]
-					: 0.SI<Watt>());
-
-				var pTCOut = row[(int)ModalResultField.P_clutch_out];
-				if (pTCOut != DBNull.Value) {
-					Assert.AreEqual(pGbxIn.Value(), (pTCOut as Watt).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-					//Assert.AreEqual(pEngOut.Value(), (pTCOut as Watt + pTC_Loss).Value(), 1E-3, "time: {0}  distance: {1}",
-					//	time, distance);
-				}
-
-				Assert.IsTrue(pLossGbx.IsGreaterOrEqual(pShiftLoss + pGbxInertia), "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.AreEqual(pGbxIn.Value(), (pRetIn + pLossGbx + pGbxInertia).Value(), gear != 0 ? 1E-3 : 0.5,
-					"time: {0}  distance: {1}", time,
-					distance);
-
-				// P_eng_fcmap = P_eng_out + P_AUX + P_eng_inertia ( + P_PTO_Transm + P_PTO_Consumer )
-				Assert.AreEqual(pEngFcmap.Value(), (pEngOut + pAux + pEngInertia + pPTOtransm + pPTOconsumer).Value(), 0.5,
-					"time: {0}  distance: {1}", time, distance);
-
-				// P_eng_fcmap = sum(Losses Powertrain)
-				var pLossTot = pClutchLoss + pTC_Loss + pLossGbx + pLossRet + pGbxInertia + pLossAngle + pLossAxle + pBrakeLoss +
-								pWheelInertia + pAir + pRoll + pGrad + pVehInertia + pPTOconsumer + pPTOtransm;
-				var pEngFcmapCalc = (pLossTot + pEngInertia + pAux).Value();
-				Assert.AreEqual(pEngFcmap.Value(), pEngFcmapCalc, 0.5, "time: {0}  distance: {1}", time, distance);
-
-				Assert.AreEqual(pEngFcmap.Value(),
-					(pTrac + pWheelInertia + pBrakeLoss + pLossAxle + pLossRet + pLossGbx + pGbxInertia + pEngInertia + pAux +
-					pClutchLoss + pTC_Loss + pPTOtransm + pPTOconsumer).Value(), 0.5, "time: {0}  distance: {1}", time, distance);
-			}
-		}
-
-		[
-			TestCase(@"TestData\Integration\EngineeringMode\CityBus_AT\CityBus_AT_Ser.vecto"),
-			TestCase(@"TestData\Integration\EngineeringMode\CityBus_AT\CityBus_AT_PS.vecto")]
-		public void TestFullCycleModDataIntegrityAT(string jobName)
-		{
-			var fileWriter = new FileOutputWriter(jobName);
-			var sumData = new SummaryDataContainer(fileWriter);
-
-			var jobContainer = new JobContainer(sumData);
-			var inputData = JSONInputDataFactory.ReadJsonJob(jobName);
-
-			var runsFactory =
-				new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter) { WriteModalResults = true };
-
-			jobContainer.AddRuns(runsFactory);
-			var modData = new List<Tuple<ModalResults, Meter>>();
-			foreach (var run in jobContainer.Runs) {
-				modData.Add(Tuple.Create(((ModalDataContainer)run.Run.GetContainer().ModalData).Data,
-					((DistanceBasedDrivingCycle)((VehicleContainer)run.Run.GetContainer()).DrivingCycle).Data.Entries.Last()
-					.Distance));
-			}
-			var auxKeys =
-				new Dictionary<string, DataColumn>(
-					((ModalDataContainer)jobContainer.Runs.First().Run.GetContainer().ModalData).Auxiliaries);
-			jobContainer.Execute();
-			jobContainer.WaitFinished();
-
-			foreach (var modalResults in modData) {
-				AssertModDataIntegrityAT(modalResults.Item1, auxKeys, modalResults.Item2,
-					FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).EngineInputData.FuelConsumptionMap));
-			}
-
-			AssertSumDataIntegrity(sumData, ExecutionMode.Engineering);
-		}
-
-		private static void AssertModDataIntegrityAT(ModalResults modData, Dictionary<string, DataColumn> auxKeys,
-			Meter totalDistance, FuelConsumptionMap consumptionMap)
-		{
-			Assert.IsTrue(modData.Rows.Count > 0);
-
-			var ptoTransmissionColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOTransmission)
-				? auxKeys[Constants.Auxiliaries.IDs.PTOTransmission]
-				: null;
-			var ptoConsumerColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOConsumer)
-				? auxKeys[Constants.Auxiliaries.IDs.PTOConsumer]
-				: null;
-			foreach (DataRow row in modData.Rows) {
-				if (totalDistance.IsEqual(((Meter)row[(int)ModalResultField.dist]))) {
-					continue;
-				}
-				var gear = (uint)row[(int)ModalResultField.Gear];
-				var time = (Second)row[(int)ModalResultField.time];
-
-				var distance = (Meter)row[(int)ModalResultField.dist];
-				var tqEngFcmap = (NewtonMeter)row[(int)ModalResultField.T_eng_fcmap];
-				var nEngFcMap = (PerSecond)row[(int)ModalResultField.n_eng_avg];
-
-				// check fuel consumption interpolation
-				var fuelConsumption = (SI)row[(int)ModalResultField.FCMap];
-				Assert.AreEqual(fuelConsumption.Value(),
-					consumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value.Value(), 1E-3, "time: {0}  distance: {1}",
-					time, distance);
-
-				// check P_eng_FCmap = T_eng_fcmap * n_eng
-				var pEngFcmap = (SI)row[(int)ModalResultField.P_eng_fcmap];
-				Assert.AreEqual(pEngFcmap.Value(), (tqEngFcmap * nEngFcMap).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				var pWheelIn = (Watt)row[(int)ModalResultField.P_wheel_in];
-				var pAir = (Watt)row[(int)ModalResultField.P_air];
-				var pRoll = (Watt)row[(int)ModalResultField.P_roll];
-				var pGrad = (Watt)row[(int)ModalResultField.P_slope];
-				var pVehInertia = (Watt)row[(int)ModalResultField.P_veh_inertia];
-				var pTrac = (Watt)row[(int)ModalResultField.P_trac];
-
-				// Pe_eng = P_wheel + P_lossgearbox + P_lossaxle + P_lossretarder + P_agbx + Pa_eng + P_aux - P_brake_loss
-				var pEngOut = (Watt)row[(int)ModalResultField.P_eng_out];
-				var pLossGbx = (Watt)row[(int)ModalResultField.P_gbx_loss];
-				var pGbxIn = (Watt)row[(int)ModalResultField.P_gbx_in];
-				var pLossAxle = (Watt)row[(int)ModalResultField.P_axle_loss];
-				var pLossAngle = row[(int)ModalResultField.P_angle_loss] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[(int)ModalResultField.P_angle_loss];
-				var pAxleIn = (Watt)row[(int)ModalResultField.P_axle_in];
-				var pLossRet = (Watt)row[(int)ModalResultField.P_ret_loss];
-				var pRetIn = (Watt)row[(int)ModalResultField.P_retarder_in];
-				var pGbxInertia = (Watt)row[(int)ModalResultField.P_gbx_inertia];
-				var pShiftLoss = row[(int)ModalResultField.P_gbx_shift_loss] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[(int)ModalResultField.P_gbx_shift_loss];
-				var pEngInertia = (Watt)row[(int)ModalResultField.P_eng_inertia];
-				var pAux =
-					(Watt)(row[(int)ModalResultField.P_aux] != DBNull.Value ? row[(int)ModalResultField.P_aux] : 0.SI<Watt>());
-				var pBrakeLoss = (Watt)row[(int)ModalResultField.P_brake_loss];
-				var pBrakeIn = (Watt)row[(int)ModalResultField.P_brake_in];
-				var pTcLoss = (Watt)row[(int)ModalResultField.P_TC_loss];
-				var pTcOut = (Watt)row[(int)ModalResultField.P_TC_out];
-				var pWheelInertia = (Watt)row[(int)ModalResultField.P_wheel_inertia];
-				var pPTOconsumer = ptoConsumerColumn == null || row[ptoConsumerColumn] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[ptoConsumerColumn];
-				var pPTOtransm = ptoTransmissionColumn == null || row[ptoTransmissionColumn] is DBNull
-					? 0.SI<Watt>()
-					: (Watt)row[ptoTransmissionColumn];
-				// P_trac = P_veh_inertia + P_roll + P_air + P_slope
-				Assert.AreEqual(pTrac.Value(), (pAir + pRoll + pGrad + pVehInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				// P_wheel_in = P_trac + P_wheel_inertia
-				Assert.AreEqual(pWheelIn.Value(), (pTrac + pWheelInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.AreEqual(pBrakeIn.Value(), (pWheelIn + pBrakeLoss).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.AreEqual(pAxleIn.Value(), (pBrakeIn + pLossAxle).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-
-				Assert.AreEqual(pRetIn.Value(), (pAxleIn + pLossRet).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-
-				Assert.AreEqual(pGbxIn.Value(), pTcOut.Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
-
-				Assert.AreEqual(pEngOut.Value(), (pTcOut + pTcLoss).Value(), 1E-3,
-					"time: {0}  distance: {1}", time, distance);
-
-				// P_eng_fcmap = P_eng_out + P_AUX + P_eng_inertia ( + P_PTO_Transm + P_PTO_Consumer )
-				Assert.AreEqual(pEngFcmap.Value(), (pEngOut + pAux + pEngInertia + pPTOtransm + pPTOconsumer).Value(), 1E-3,
-					"time: {0}  distance: {1}", time,
-					distance);
-
-				// P_eng_fcmap = sum(Losses Powertrain)
-				var pLossTot = pTcLoss + pLossGbx + pLossRet + pGbxInertia + pLossAngle + pLossAxle + pBrakeLoss +
-								pWheelInertia + pAir + pRoll + pGrad + pVehInertia + pPTOconsumer + pPTOtransm;
-
-				Assert.AreEqual(pEngFcmap.Value(), (pLossTot + pEngInertia + pAux).Value(), 1E-3, "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.IsTrue(pLossGbx.IsGreaterOrEqual(pShiftLoss + pGbxInertia), "time: {0}  distance: {1}", time,
-					distance);
-
-				Assert.AreEqual(pGbxIn.Value(), (pRetIn + pLossGbx + pGbxInertia).Value(), gear != 0 ? 1E-3 : 0.5,
-					"time: {0}  distance: {1}", time,
-					distance);
-				Assert.AreEqual(pEngFcmap.Value(),
-					(pTrac + pWheelInertia + pBrakeLoss + pLossAxle + pLossRet + pLossGbx + pGbxInertia + pEngInertia + pAux +
-					pTcLoss + pPTOtransm + pPTOconsumer).Value(), 0.5, "time: {0}  distance: {1}", time, distance);
-			}
-		}
-	}
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using NUnit.Framework;
+using TUGraz.VectoCommon.InputData;
+using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
+using TUGraz.VectoCore.Configuration;
+using TUGraz.VectoCore.InputData.FileIO.JSON;
+using TUGraz.VectoCore.Models.Simulation.Data;
+using TUGraz.VectoCore.Models.Simulation.Impl;
+using TUGraz.VectoCore.Models.SimulationComponent.Data.Engine;
+using TUGraz.VectoCore.Models.SimulationComponent.Impl;
+using TUGraz.VectoCore.OutputData;
+using TUGraz.VectoCore.OutputData.FileIO;
+using TUGraz.VectoCore.Tests.Integration;
+using TUGraz.VectoCore.Tests.Utils;
+using Assert = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
+
+namespace TUGraz.VectoCore.Tests.Reports
+{
+	[TestFixture]
+	public class ModDataTest
+	{
+		[TestCase()]
+		public void ModDataIntegritySimpleTest()
+		{
+			var cycleData = new[] {
+				// <s>,<v>,<grad>,<stop>
+				"  0,  20, 0,    0",
+				" 100, 60, 0,    0",
+				"1000, 60, 0,    0",
+				"1500, 40, 1,    0",
+				"2000, 50,-1,    0",
+				"2500,  0, 0,    2"
+			};
+			var cycle = SimpleDrivingCycles.CreateCycleData(cycleData);
+			var sumData = new SummaryDataContainer(null);
+			var run = Truck40tPowerTrain.CreateEngineeringRun(cycle, "Truck_ModDataIntegrity.vmod");
+
+			var engineData = MockSimulationDataFactory.CreateEngineDataFromFile(Truck40tPowerTrain.EngineFile, 0);
+
+			// get a reference to the mod-data because the modaldata container clears it after simulation
+			var modData = ((ModalDataContainer)run.GetContainer().ModalData).Data;
+			var auxKeys = ((ModalDataContainer)run.GetContainer().ModalData).Auxiliaries;
+
+			run.Run();
+			Assert.IsTrue(run.FinishedWithoutErrors);
+
+			AssertModDataIntegrity(modData, auxKeys, cycle.Entries.Last().Distance, engineData.ConsumptionMap);
+		}
+
+		[TestCase(@"TestData\Integration\DeclarationMode\Class2_RigidTruck_4x2\Class2_RigidTruck_DECL.vecto")]
+		public void TestFullCycleModDataIntegrityDeclMT(string jobName)
+		{
+			RunSimulation(jobName, ExecutionMode.Declaration);
+		}
+
+		[TestCase(@"TestData\Integration\EngineeringMode\Class2_RigidTruck_4x2\Class2_RigidTruck_ENG.vecto"),
+		TestCase(@"TestData\Integration\EngineeringMode\Class5_Tractor_4x2\Class5_Tractor_ENG.vecto"),
+		TestCase(@"TestData\Integration\EngineeringMode\Class9_RigidTruck_6x2_PTO\Class9_RigidTruck_ENG_PTO.vecto"),]
+		public void TestFullCycleModDataIntegrityMT(string jobName)
+		{
+			RunSimulation(jobName, ExecutionMode.Engineering);
+		}
+
+		private static void RunSimulation(string jobName, ExecutionMode mode)
+		{
+			var fileWriter = new FileOutputWriter(jobName);
+			var sumData = new SummaryDataContainer(fileWriter);
+
+			var jobContainer = new JobContainer(sumData);
+			var inputData = JSONInputDataFactory.ReadJsonJob(jobName);
+
+			var runsFactory = new SimulatorFactory(mode, inputData, fileWriter) { WriteModalResults = true };
+
+			jobContainer.AddRuns(runsFactory);
+			var modData = new List<Tuple<ModalResults, Meter>>();
+			foreach (var run in jobContainer.Runs) {
+				modData.Add(Tuple.Create(((ModalDataContainer)run.Run.GetContainer().ModalData).Data,
+					((DistanceBasedDrivingCycle)((VehicleContainer)run.Run.GetContainer()).DrivingCycle).Data.Entries.Last()
+						.Distance));
+			}
+			var auxKeys =
+				new Dictionary<string, DataColumn>(
+					((ModalDataContainer)jobContainer.Runs.First().Run.GetContainer().ModalData).Auxiliaries);
+			jobContainer.Execute();
+			jobContainer.WaitFinished();
+
+			// mod files will be stored in e.g. 
+			// VectoCoreTest\bin\Debug\TestData\Integration\EngineeringMode\Class2_RigidTruck_4x2\Class2_RigidTruck_ENG.vecto_00.vmod
+			//fileWriter.WriteModData(Path.GetFileName(jobName), "0", "0", modData[0].Item1);
+			//fileWriter.WriteModData(Path.GetFileName(jobName), "1", "1", modData[1].Item1);
+
+			foreach (var modalResults in modData) {
+				AssertModDataIntegrity(modalResults.Item1, auxKeys, modalResults.Item2,
+					FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).EngineInputData.FuelConsumptionMap));
+			}
+
+			AssertSumDataIntegrity(sumData, mode);
+		}
+
+		private static void AssertSumDataIntegrity(SummaryDataContainer sumData, ExecutionMode mode)
+		{
+			Assert.IsTrue(sumData.Table.Rows.Count > 0);
+
+			var ptoTransmissionColumn =
+				sumData.Table.Columns.Contains(string.Format(SummaryDataContainer.E_FORMAT,
+					Constants.Auxiliaries.IDs.PTOTransmission))
+					? string.Format(SummaryDataContainer.E_FORMAT, Constants.Auxiliaries.IDs.PTOTransmission)
+					: null;
+			var ptoConsumerColumn =
+				sumData.Table.Columns.Contains(string.Format(SummaryDataContainer.E_FORMAT, Constants.Auxiliaries.IDs.PTOConsumer))
+					? string.Format(SummaryDataContainer.E_FORMAT, Constants.Auxiliaries.IDs.PTOConsumer)
+					: null;
+
+			foreach (DataRow row in sumData.Table.Rows) {
+				var inputFile = row[SummaryDataContainer.INPUTFILE].ToString();
+				var cycle = row[SummaryDataContainer.CYCLE].ToString();
+				var loading = row[SummaryDataContainer.LOADING].ToString();
+				var eFcMapPos = ((SI)row[SummaryDataContainer.E_FCMAP_POS]).Value();
+				var eFcMapNeg = ((SI)row[SummaryDataContainer.E_FCMAP_NEG]).Value();
+				var ePowertrainInertia = ((SI)row[SummaryDataContainer.E_POWERTRAIN_INERTIA]).Value();
+				var eAux = ((SI)row[SummaryDataContainer.E_AUX]).Value();
+				var eClutchLoss = ((SI)row[SummaryDataContainer.E_CLUTCH_LOSS]).Value();
+				var eTcLoss = ((SI)row[SummaryDataContainer.E_TC_LOSS]).Value();
+				//var eShiftLoss = ((SI)row[SummaryDataContainer.E_SHIFT_LOSS]).Value();
+				var eGbxLoss = ((SI)row[SummaryDataContainer.E_GBX_LOSS]).Value();
+				var eRetLoss = ((SI)row[SummaryDataContainer.E_RET_LOSS]).Value();
+				var eAngleLoss = ((SI)row[SummaryDataContainer.E_ANGLE_LOSS]).Value();
+				var eAxlLoss = ((SI)row[SummaryDataContainer.E_AXL_LOSS]).Value();
+				var eBrakeLoss = ((SI)row[SummaryDataContainer.E_BRAKE]).Value();
+				var eVehInertia = ((SI)row[SummaryDataContainer.E_VEHICLE_INERTIA]).Value();
+				var eAir = ((SI)row[SummaryDataContainer.E_AIR]).Value();
+				var eRoll = ((SI)row[SummaryDataContainer.E_ROLL]).Value();
+				var eGrad = ((SI)row[SummaryDataContainer.E_GRAD]).Value();
+				var cargoVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CARGO_VOLUME]).Value();
+
+				var loadingValue = ((SI)row[SummaryDataContainer.LOADING]).Value() / 1000;
+				var fcPer100km = ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100KM]).Value();
+				var fcPerVolume = mode == ExecutionMode.Engineering
+					? 0
+					: ((SI)row[SummaryDataContainer.FCFINAL_LiterPer100M3KM]).Value();
+				var fcPerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.FCFINAL_LITERPER100TKM]).Value() : 0;
+				var co2Per100km = ((SI)row[SummaryDataContainer.CO2_KM]).Value();
+				var co2PerVolume = mode == ExecutionMode.Engineering ? 0 : ((SI)row[SummaryDataContainer.CO2_M3KM]).Value();
+				var co2PerLoad = loadingValue > 0 ? ((SI)row[SummaryDataContainer.CO2_TKM]).Value() : 0;
+
+				var ePTOtransm = ptoTransmissionColumn != null ? ((SI)row[ptoTransmissionColumn]).Value() : 0;
+				var ePTOconsumer = ptoConsumerColumn != null ? ((SI)row[ptoConsumerColumn]).Value() : 0;
+
+				// E_fcmap_pos = E_fcmap_neg + E_powertrain_inertia + E_aux_xxx + E_aux_sum + E_clutch_loss + E_tc_loss + E_gbx_loss + E_shift_loss + E_ret_loss + E_angle_loss + E_axl_loss + E_brake + E_vehicle_inertia + E_air + E_roll + E_grad + E_PTO_CONSUM + E_PTO_TRANSM
+				Assert.AreEqual(eFcMapPos,
+					eFcMapNeg + ePowertrainInertia + eAux + eClutchLoss + eTcLoss + eGbxLoss + eRetLoss + eAngleLoss +
+					eAxlLoss + eBrakeLoss + eVehInertia + eAir + eRoll + eGrad + ePTOconsumer + ePTOtransm, 1e-5,
+					"input file: {0}  cycle: {1} loading: {2}",
+					inputFile, cycle, loading);
+
+				var pFcmapPos = ((SI)row[SummaryDataContainer.P_FCMAP_POS]).Value();
+				var time = ((SI)row[SummaryDataContainer.TIME]).Value();
+
+				// E_fcmap_pos = P_fcmap_pos * t
+				Assert.AreEqual(eFcMapPos, pFcmapPos * (time / 3600), 1e-3, "input file: {0}  cycle: {1} loading: {2}", inputFile,
+					cycle, loading);
+
+				if (cargoVolume > 0) {
+					Assert.AreEqual(fcPerVolume, fcPer100km / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}", inputFile,
+						cycle, loading);
+
+					Assert.AreEqual(co2PerVolume, co2Per100km / cargoVolume, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
+						inputFile,
+						cycle, loading);
+				}
+
+				if (loadingValue > 0) {
+					Assert.AreEqual(co2PerLoad, co2Per100km / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
+						inputFile, cycle, loading);
+					Assert.AreEqual(fcPerLoad, fcPer100km / loadingValue, 1e-3, "input file: {0}  cycle: {1} loading: {2}",
+						inputFile, cycle, loading);
+				}
+
+				var stopTimeShare = ((SI)row[SummaryDataContainer.STOP_TIMESHARE]).Value();
+				var accTimeShare = ((SI)row[SummaryDataContainer.ACC_TIMESHARE]).Value();
+				var decTimeShare = ((SI)row[SummaryDataContainer.DEC_TIMESHARE]).Value();
+				var cruiseTimeShare = ((SI)row[SummaryDataContainer.CRUISE_TIMESHARE]).Value();
+
+				Assert.AreEqual(100, stopTimeShare + accTimeShare + decTimeShare + cruiseTimeShare, 1e-3,
+					"input file: {0}  cycle: {1} loading: {2}", inputFile, cycle, loading);
+
+				Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_POS]).Value() > 0);
+				Assert.IsTrue(((SI)row[SummaryDataContainer.ACC_NEG]).Value() < 0);
+
+				var gearshifts = ((SI)row[SummaryDataContainer.NUM_GEARSHIFTS]).Value();
+				Assert.IsTrue(gearshifts > 0);
+
+				//var acc = ((SI)row[SummaryDataContainer.ACC]).Value();
+			}
+		}
+
+		private static void AssertModDataIntegrity(ModalResults modData, Dictionary<string, DataColumn> auxKeys,
+			Meter totalDistance, FuelConsumptionMap consumptionMap)
+		{
+			Assert.IsTrue(modData.Rows.Count > 0);
+
+			var ptoTransmissionColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOTransmission)
+				? auxKeys[Constants.Auxiliaries.IDs.PTOTransmission]
+				: null;
+			var ptoConsumerColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOConsumer)
+				? auxKeys[Constants.Auxiliaries.IDs.PTOConsumer]
+				: null;
+			foreach (DataRow row in modData.Rows) {
+				if (totalDistance.IsEqual(((Meter)row[(int)ModalResultField.dist]))) {
+					continue;
+				}
+				var gear = (uint)row[(int)ModalResultField.Gear];
+				var time = (Second)row[(int)ModalResultField.time];
+
+				var distance = (Meter)row[(int)ModalResultField.dist];
+				var tqEngFcmap = (NewtonMeter)row[(int)ModalResultField.T_eng_fcmap];
+				var nEngFcMap = (PerSecond)row[(int)ModalResultField.n_eng_avg];
+
+				// check fuel consumption interpolation
+				var fuelConsumption = (SI)row[(int)ModalResultField.FCMap];
+				Assert.AreEqual(fuelConsumption.Value(),
+					consumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value.Value(), 1E-3, "time: {0}  distance: {1}",
+					time, distance);
+
+				// check P_eng_FCmap = T_eng_fcmap * n_eng
+				var pEngFcmap = (SI)row[(int)ModalResultField.P_eng_fcmap];
+				Assert.AreEqual(pEngFcmap.Value(), (tqEngFcmap * nEngFcMap).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				var pWheelIn = (Watt)row[(int)ModalResultField.P_wheel_in];
+				var pAir = (Watt)row[(int)ModalResultField.P_air];
+				var pRoll = (Watt)row[(int)ModalResultField.P_roll];
+				var pGrad = (Watt)row[(int)ModalResultField.P_slope];
+				var pVehInertia = (Watt)row[(int)ModalResultField.P_veh_inertia];
+				var pTrac = (Watt)row[(int)ModalResultField.P_trac];
+
+				// P_eng_out = P_wheel + P_lossgearbox + P_lossaxle + P_lossretarder + P_agbx + Pa_eng + P_aux - P_brake_loss
+				var pEngOut = (Watt)row[(int)ModalResultField.P_eng_out];
+				var pLossGbx = (Watt)row[(int)ModalResultField.P_gbx_loss];
+				var pGbxIn = (Watt)row[(int)ModalResultField.P_gbx_in];
+				var pLossAxle = (Watt)row[(int)ModalResultField.P_axle_loss];
+				var pLossAngle = row[(int)ModalResultField.P_angle_loss] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[(int)ModalResultField.P_angle_loss];
+				var pAxleIn = (Watt)row[(int)ModalResultField.P_axle_in];
+				var pLossRet = (Watt)row[(int)ModalResultField.P_ret_loss];
+				var pRetIn = (Watt)row[(int)ModalResultField.P_retarder_in];
+				var pGbxInertia = (Watt)row[(int)ModalResultField.P_gbx_inertia];
+				var pShiftLoss = row[(int)ModalResultField.P_gbx_shift_loss] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[(int)ModalResultField.P_gbx_shift_loss];
+				var pEngInertia = (Watt)row[(int)ModalResultField.P_eng_inertia];
+				var pAux =
+					(Watt)(row[(int)ModalResultField.P_aux] != DBNull.Value ? row[(int)ModalResultField.P_aux] : 0.SI<Watt>());
+				var pBrakeLoss = (Watt)row[(int)ModalResultField.P_brake_loss];
+				var pBrakeIn = (Watt)row[(int)ModalResultField.P_brake_in];
+
+				var pWheelInertia = (Watt)row[(int)ModalResultField.P_wheel_inertia];
+				var pPTOconsumer = ptoConsumerColumn == null || row[ptoConsumerColumn.ColumnName] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[ptoConsumerColumn.ColumnName];
+				var pPTOtransm = ptoTransmissionColumn == null || row[ptoTransmissionColumn.ColumnName] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[ptoTransmissionColumn.ColumnName];
+				// P_trac = P_veh_inertia + P_roll + P_air + P_slope
+				Assert.AreEqual(pTrac.Value(), (pAir + pRoll + pGrad + pVehInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				// P_wheel_in = P_trac + P_wheel_inertia
+				Assert.AreEqual(pWheelIn.Value(), (pTrac + pWheelInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.AreEqual(pBrakeIn.Value(), (pWheelIn + pBrakeLoss).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.AreEqual(pAxleIn.Value(), (pBrakeIn + pLossAxle).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+
+				Assert.AreEqual(pRetIn.Value(), (pAxleIn + pLossRet).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+
+				var pClutchLoss = (Watt)(row[(int)ModalResultField.P_clutch_loss] != DBNull.Value
+					? row[(int)ModalResultField.P_clutch_loss]
+					: 0.SI<Watt>());
+
+				var pClutchOut = row[(int)ModalResultField.P_clutch_out];
+				if (pClutchOut != DBNull.Value) {
+					Assert.AreEqual(pGbxIn.Value(), (pClutchOut as Watt).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+					Assert.AreEqual(pEngOut.Value(), (pClutchOut as Watt + pClutchLoss).Value(), 1E-3, "time: {0}  distance: {1}",
+						time, distance);
+				}
+
+				var pTC_Loss = (Watt)(row[(int)ModalResultField.P_TC_loss] != DBNull.Value
+					? row[(int)ModalResultField.P_TC_loss]
+					: 0.SI<Watt>());
+
+				var pTCOut = row[(int)ModalResultField.P_clutch_out];
+				if (pTCOut != DBNull.Value) {
+					Assert.AreEqual(pGbxIn.Value(), (pTCOut as Watt).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+					//Assert.AreEqual(pEngOut.Value(), (pTCOut as Watt + pTC_Loss).Value(), 1E-3, "time: {0}  distance: {1}",
+					//	time, distance);
+				}
+
+				Assert.IsTrue(pLossGbx.IsGreaterOrEqual(pShiftLoss + pGbxInertia), "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.AreEqual(pGbxIn.Value(), (pRetIn + pLossGbx + pGbxInertia).Value(), gear != 0 ? 1E-3 : 0.5,
+					"time: {0}  distance: {1}", time,
+					distance);
+
+				// P_eng_fcmap = P_eng_out + P_AUX + P_eng_inertia ( + P_PTO_Transm + P_PTO_Consumer )
+				Assert.AreEqual(pEngFcmap.Value(), (pEngOut + pAux + pEngInertia + pPTOtransm + pPTOconsumer).Value(), 0.5,
+					"time: {0}  distance: {1}", time, distance);
+
+				// P_eng_fcmap = sum(Losses Powertrain)
+				var pLossTot = pClutchLoss + pTC_Loss + pLossGbx + pLossRet + pGbxInertia + pLossAngle + pLossAxle + pBrakeLoss +
+								pWheelInertia + pAir + pRoll + pGrad + pVehInertia + pPTOconsumer + pPTOtransm;
+				var pEngFcmapCalc = (pLossTot + pEngInertia + pAux).Value();
+				Assert.AreEqual(pEngFcmap.Value(), pEngFcmapCalc, 0.5, "time: {0}  distance: {1}", time, distance);
+
+				Assert.AreEqual(pEngFcmap.Value(),
+					(pTrac + pWheelInertia + pBrakeLoss + pLossAxle + pLossRet + pLossGbx + pGbxInertia + pEngInertia + pAux +
+					pClutchLoss + pTC_Loss + pPTOtransm + pPTOconsumer).Value(), 0.5, "time: {0}  distance: {1}", time, distance);
+			}
+		}
+
+		[
+			TestCase(@"TestData\Integration\EngineeringMode\CityBus_AT\CityBus_AT_Ser.vecto"),
+			TestCase(@"TestData\Integration\EngineeringMode\CityBus_AT\CityBus_AT_PS.vecto")]
+		public void TestFullCycleModDataIntegrityAT(string jobName)
+		{
+			var fileWriter = new FileOutputWriter(jobName);
+			var sumData = new SummaryDataContainer(fileWriter);
+
+			var jobContainer = new JobContainer(sumData);
+			var inputData = JSONInputDataFactory.ReadJsonJob(jobName);
+
+			var runsFactory =
+				new SimulatorFactory(ExecutionMode.Engineering, inputData, fileWriter) { WriteModalResults = true };
+
+			jobContainer.AddRuns(runsFactory);
+			var modData = new List<Tuple<ModalResults, Meter>>();
+			foreach (var run in jobContainer.Runs) {
+				modData.Add(Tuple.Create(((ModalDataContainer)run.Run.GetContainer().ModalData).Data,
+					((DistanceBasedDrivingCycle)((VehicleContainer)run.Run.GetContainer()).DrivingCycle).Data.Entries.Last()
+						.Distance));
+			}
+			var auxKeys =
+				new Dictionary<string, DataColumn>(
+					((ModalDataContainer)jobContainer.Runs.First().Run.GetContainer().ModalData).Auxiliaries);
+			jobContainer.Execute();
+			jobContainer.WaitFinished();
+
+			foreach (var modalResults in modData) {
+				AssertModDataIntegrityAT(modalResults.Item1, auxKeys, modalResults.Item2,
+					FuelConsumptionMapReader.Create(((IEngineeringInputDataProvider)inputData).EngineInputData.FuelConsumptionMap));
+			}
+
+			AssertSumDataIntegrity(sumData, ExecutionMode.Engineering);
+		}
+
+		private static void AssertModDataIntegrityAT(ModalResults modData, Dictionary<string, DataColumn> auxKeys,
+			Meter totalDistance, FuelConsumptionMap consumptionMap)
+		{
+			Assert.IsTrue(modData.Rows.Count > 0);
+
+			var ptoTransmissionColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOTransmission)
+				? auxKeys[Constants.Auxiliaries.IDs.PTOTransmission]
+				: null;
+			var ptoConsumerColumn = auxKeys.ContainsKey(Constants.Auxiliaries.IDs.PTOConsumer)
+				? auxKeys[Constants.Auxiliaries.IDs.PTOConsumer]
+				: null;
+			foreach (DataRow row in modData.Rows) {
+				if (totalDistance.IsEqual(((Meter)row[(int)ModalResultField.dist]))) {
+					continue;
+				}
+				var gear = (uint)row[(int)ModalResultField.Gear];
+				var time = (Second)row[(int)ModalResultField.time];
+
+				var distance = (Meter)row[(int)ModalResultField.dist];
+				var tqEngFcmap = (NewtonMeter)row[(int)ModalResultField.T_eng_fcmap];
+				var nEngFcMap = (PerSecond)row[(int)ModalResultField.n_eng_avg];
+
+				// check fuel consumption interpolation
+				var fuelConsumption = (SI)row[(int)ModalResultField.FCMap];
+				Assert.AreEqual(fuelConsumption.Value(),
+					consumptionMap.GetFuelConsumption(tqEngFcmap, nEngFcMap).Value.Value(), 1E-3, "time: {0}  distance: {1}",
+					time, distance);
+
+				// check P_eng_FCmap = T_eng_fcmap * n_eng
+				var pEngFcmap = (SI)row[(int)ModalResultField.P_eng_fcmap];
+				Assert.AreEqual(pEngFcmap.Value(), (tqEngFcmap * nEngFcMap).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				var pWheelIn = (Watt)row[(int)ModalResultField.P_wheel_in];
+				var pAir = (Watt)row[(int)ModalResultField.P_air];
+				var pRoll = (Watt)row[(int)ModalResultField.P_roll];
+				var pGrad = (Watt)row[(int)ModalResultField.P_slope];
+				var pVehInertia = (Watt)row[(int)ModalResultField.P_veh_inertia];
+				var pTrac = (Watt)row[(int)ModalResultField.P_trac];
+
+				// Pe_eng = P_wheel + P_lossgearbox + P_lossaxle + P_lossretarder + P_agbx + Pa_eng + P_aux - P_brake_loss
+				var pEngOut = (Watt)row[(int)ModalResultField.P_eng_out];
+				var pLossGbx = (Watt)row[(int)ModalResultField.P_gbx_loss];
+				var pGbxIn = (Watt)row[(int)ModalResultField.P_gbx_in];
+				var pLossAxle = (Watt)row[(int)ModalResultField.P_axle_loss];
+				var pLossAngle = row[(int)ModalResultField.P_angle_loss] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[(int)ModalResultField.P_angle_loss];
+				var pAxleIn = (Watt)row[(int)ModalResultField.P_axle_in];
+				var pLossRet = (Watt)row[(int)ModalResultField.P_ret_loss];
+				var pRetIn = (Watt)row[(int)ModalResultField.P_retarder_in];
+				var pGbxInertia = (Watt)row[(int)ModalResultField.P_gbx_inertia];
+				var pShiftLoss = row[(int)ModalResultField.P_gbx_shift_loss] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[(int)ModalResultField.P_gbx_shift_loss];
+				var pEngInertia = (Watt)row[(int)ModalResultField.P_eng_inertia];
+				var pAux =
+					(Watt)(row[(int)ModalResultField.P_aux] != DBNull.Value ? row[(int)ModalResultField.P_aux] : 0.SI<Watt>());
+				var pBrakeLoss = (Watt)row[(int)ModalResultField.P_brake_loss];
+				var pBrakeIn = (Watt)row[(int)ModalResultField.P_brake_in];
+				var pTcLoss = (Watt)row[(int)ModalResultField.P_TC_loss];
+				var pTcOut = (Watt)row[(int)ModalResultField.P_TC_out];
+				var pWheelInertia = (Watt)row[(int)ModalResultField.P_wheel_inertia];
+				var pPTOconsumer = ptoConsumerColumn == null || row[ptoConsumerColumn] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[ptoConsumerColumn];
+				var pPTOtransm = ptoTransmissionColumn == null || row[ptoTransmissionColumn] is DBNull
+					? 0.SI<Watt>()
+					: (Watt)row[ptoTransmissionColumn];
+				// P_trac = P_veh_inertia + P_roll + P_air + P_slope
+				Assert.AreEqual(pTrac.Value(), (pAir + pRoll + pGrad + pVehInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				// P_wheel_in = P_trac + P_wheel_inertia
+				Assert.AreEqual(pWheelIn.Value(), (pTrac + pWheelInertia).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.AreEqual(pBrakeIn.Value(), (pWheelIn + pBrakeLoss).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.AreEqual(pAxleIn.Value(), (pBrakeIn + pLossAxle).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+
+				Assert.AreEqual(pRetIn.Value(), (pAxleIn + pLossRet).Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+
+				Assert.AreEqual(pGbxIn.Value(), pTcOut.Value(), 1E-3, "time: {0}  distance: {1}", time, distance);
+
+				Assert.AreEqual(pEngOut.Value(), (pTcOut + pTcLoss).Value(), 1E-3,
+					"time: {0}  distance: {1}", time, distance);
+
+				// P_eng_fcmap = P_eng_out + P_AUX + P_eng_inertia ( + P_PTO_Transm + P_PTO_Consumer )
+				Assert.AreEqual(pEngFcmap.Value(), (pEngOut + pAux + pEngInertia + pPTOtransm + pPTOconsumer).Value(), 1E-3,
+					"time: {0}  distance: {1}", time,
+					distance);
+
+				// P_eng_fcmap = sum(Losses Powertrain)
+				var pLossTot = pTcLoss + pLossGbx + pLossRet + pGbxInertia + pLossAngle + pLossAxle + pBrakeLoss +
+								pWheelInertia + pAir + pRoll + pGrad + pVehInertia + pPTOconsumer + pPTOtransm;
+
+				Assert.AreEqual(pEngFcmap.Value(), (pLossTot + pEngInertia + pAux).Value(), 1E-3, "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.IsTrue(pLossGbx.IsGreaterOrEqual(pShiftLoss + pGbxInertia), "time: {0}  distance: {1}", time,
+					distance);
+
+				Assert.AreEqual(pGbxIn.Value(), (pRetIn + pLossGbx + pGbxInertia).Value(), gear != 0 ? 1E-3 : 0.5,
+					"time: {0}  distance: {1}", time,
+					distance);
+				Assert.AreEqual(pEngFcmap.Value(),
+					(pTrac + pWheelInertia + pBrakeLoss + pLossAxle + pLossRet + pLossGbx + pGbxInertia + pEngInertia + pAux +
+					pTcLoss + pPTOtransm + pPTOconsumer).Value(), 0.5, "time: {0}  distance: {1}", time, distance);
+			}
+		}
+	}
 }
\ No newline at end of file