diff --git a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs
index 980076d4b3ef602c83603e652c6ff3db2f7b0b68..1cd19c094f10a4cb4c799316b837e918e72ed6ab 100644
--- a/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs
+++ b/VectoCommon/VectoCommon/Models/HybridStrategyResponse.cs
@@ -82,9 +82,8 @@ namespace TUGraz.VectoCommon.Models {
 			return ToString().Equals(other.ToString(), StringComparison.InvariantCultureIgnoreCase);
 		}
 
-		public override string ToString()
-		{
-			var setting = string.Join(", ", Setting.MechanicalAssistPower.Select(x => $"{x.Key}, {x.Value}"));
+		public override string ToString() {
+			var setting = Setting.MechanicalAssistPower.Select(x => $"{x.Key}, {x.Value}").Join();
 			return $"{U}: {setting} {Score} G{Gear}";
 		}
 	}
@@ -155,7 +154,7 @@ namespace TUGraz.VectoCommon.Models {
 				}
 			}
 
-			return string.Join("/", retVal);
+			return retVal.Join("/");
 		}
 
 		public static bool InvalidEngineSpeed(this HybridConfigurationIgnoreReason x)
diff --git a/VectoCommon/VectoCommon/Models/IResponse.cs b/VectoCommon/VectoCommon/Models/IResponse.cs
index ad0e0d1d5dafd24c4492303d86cc9d0f3dab5e0c..d3e3e6e18b0d918e89c6f704b9ccbe1f053e9e0a 100644
--- a/VectoCommon/VectoCommon/Models/IResponse.cs
+++ b/VectoCommon/VectoCommon/Models/IResponse.cs
@@ -44,7 +44,7 @@ namespace TUGraz.VectoCommon.Models
 		public override string ToString()
 		{
 			var t = GetType();
-			return $"{t.Name}{{{string.Join(", ", t.GetProperties().Select(p => $"{p.Name}: {p.GetValue(this)}"))}}}";
+			return $"{t.Name}{{{t.GetProperties().Select(p => $"{p.Name}: {p.GetValue(this)}").Join()}}}";
 		}
 	}
 
diff --git a/VectoCommon/VectoCommon/Models/WHRType.cs b/VectoCommon/VectoCommon/Models/WHRType.cs
index 9b4f8158cb633f0bccdc96dab1fc6505eecb4c49..b6f260f8c68cef31cf5450f6268b0aff893afc53 100644
--- a/VectoCommon/VectoCommon/Models/WHRType.cs
+++ b/VectoCommon/VectoCommon/Models/WHRType.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using TUGraz.VectoCommon.Utils;
 
 namespace TUGraz.VectoCommon.Models {
 
@@ -27,7 +28,7 @@ namespace TUGraz.VectoCommon.Models {
 				options.Add("electrical output");
 			}
 
-			return options.Count == 0 ? "none" : string.Join(", ", options);
+			return options.Count == 0 ? "none" : options.Join();
 		}
 		
 		public static bool IsElectrical(this WHRType whrType)
diff --git a/VectoCommon/VectoCommon/Utils/Validation.cs b/VectoCommon/VectoCommon/Utils/Validation.cs
index ebfe5f6b5d21df369c3ba563e091211e249aaae4..459464c82f3e244205c5aa11c0231682ccc1ce05 100644
--- a/VectoCommon/VectoCommon/Utils/Validation.cs
+++ b/VectoCommon/VectoCommon/Utils/Validation.cs
@@ -206,8 +206,7 @@ namespace TUGraz.VectoCommon.Utils
 								if (kvResults.Any()) {
 									return new ValidationResult(
 										string.Format("{1}[{0}] in {1} invalid: {2}", valueType.GetProperty("Key").GetValue(element),
-											validationContext.DisplayName,
-											string.Join("\n", kvResults)));
+											validationContext.DisplayName, kvResults.Join("\n")));
 								}
 							}
 						}
@@ -215,8 +214,7 @@ namespace TUGraz.VectoCommon.Utils
 						var results = element.Validate(mode, jobType, emPos, gbxType, isEmsCycle);
 						if (results.Any()) {
 							return new ValidationResult(
-								string.Format("{1}[{0}] in {1} invalid: {2}", i, validationContext.DisplayName,
-									string.Join("\n", results)));
+								$"{validationContext.DisplayName}[{i}] in {validationContext.DisplayName} invalid: {results.Join("\n")}");
 						}
 					}
 					i++;
@@ -226,12 +224,12 @@ namespace TUGraz.VectoCommon.Utils
 				if (!results.Any()) {
 					return ValidationResult.Success;
 				}
-				var messages = results.Select(r => String.Join(", ", r.MemberNames.Distinct()));
+				var messages = results.Select(r => r.MemberNames.Distinct().Join());
 				if (validationContext.MemberName == "Container" || validationContext.MemberName == "RunData") {
-					return new ValidationResult(string.Join("\n", results), messages);
+					return new ValidationResult(results.Join("\n"), messages);
 				}
 				return new ValidationResult(
-					$"{{{validationContext.DisplayName}}} invalid: {string.Join("\n", results)}", messages);
+					$"{{{validationContext.DisplayName}}} invalid: {results.Join("\n")}", messages);
 			}
 
 			return ValidationResult.Success;
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Common/AbstractXMLType.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Common/AbstractXMLType.cs
index 9d38cd19524c8f11fb0e9f269bca4ed9c60a2c97..a4c38f960ef474cdf54032b579a02c0b1a333960 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Common/AbstractXMLType.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Common/AbstractXMLType.cs
@@ -83,7 +83,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Common {
 			var node = GetNode(nodePath, required: fallbackValue == null);
 
 			if (node == null && fallbackValue == null) {
-				throw new VectoException("Node {0} not found in input data", string.Join("/", nodePath));
+				throw new VectoException("Node {0} not found in input data", nodePath.Join("/"));
 			}
 
 			return node?.InnerText.ToDouble() ?? fallbackValue.Value;
diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs
index 933c79281c63f3b2dc2819ab5db2e336505ccffc..2fd94d18f454dedbceda1186f149dff795b03804 100644
--- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs
+++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/DataProvider/XMLDeclarationEngineDataProvider.cs
@@ -110,7 +110,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
 			public virtual FuelType FuelType
 			{
 				get {
-					var value = GetString(XMLNames.Engine_FuelType).Replace(" ","");
+					var value = GetString(XMLNames.Engine_FuelType).Replace(" ", "");
 					if ("LPG".Equals(value, StringComparison.InvariantCultureIgnoreCase)) {
 						return FuelType.LPGPI;
 					}
@@ -164,7 +164,8 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
 
 		public XMLDeclarationEngineDataProviderV20(
 			IXMLDeclarationVehicleData vehicle, XmlNode componentNode, string sourceFile) : base(
-			vehicle, componentNode, sourceFile) { }
+			vehicle, componentNode, sourceFile)
+		{ }
 
 		protected override XNamespace SchemaNamespace => NAMESPACE_URI;
 	}
@@ -336,13 +337,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration.DataProvider
 					var missing = GetNodes(
 							new[] { XMLNames.Engine_FuelConsumptionMap, XMLNames.Engine_FuelConsumptionMap_Entry }, whrFuelNode)
 						.Cast<XmlNode>().Where(x => x.Attributes?[fcMapAttr] == null);
-					throw new VectoException(
-						"WHRData has to be provided for every entry in the FC-Map! {0}",
-						string.Join(
-							"; ",
-							missing.Select(
-								x => $"n: {x.Attributes?[XMLNames.Engine_FuelConsumptionMap_EngineSpeed_Attr]?.Value}, " +
-									$"T: {x.Attributes?[XMLNames.Engine_FuelConsumptionMap_Torque_Attr]?.Value}")));
+					throw new VectoException("WHRData has to be provided for every entry in the FC-Map! {0}",
+						missing.Select(x => $"n: {x.Attributes?[XMLNames.Engine_FuelConsumptionMap_EngineSpeed_Attr]?.Value}, " +
+											$"T: {x.Attributes?[XMLNames.Engine_FuelConsumptionMap_Torque_Attr]?.Value}").Join("; "));
 				}
 
 				if (correctionFactorNodes[0].ParentNode.ParentNode != whrFuelNode) {
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/ActuationsMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/ActuationsMapReader.cs
index d4ada09049eedb141632363a38c8b278f9ccb2cf..150243d53db7a24e56afd37945a8709e7378117a 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/ActuationsMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/ActuationsMapReader.cs
@@ -31,8 +31,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 		{
 			if (!HeaderIsValid(data.Columns)) {
 				throw new VectoException("Invalid header for pneumatic actuations. expected: {0}, got: {1}",
-					string.Join(", ", Header),
-					string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
+					Header.Join(), data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
 			}
 
 			var retVal = new Dictionary<MissionType, IActuations>();
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/AlternatorReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/AlternatorReader.cs
index 7919b1bd19d0a85bcfb5caba3f58b4634bcbdc87..e9108102edccf2d4a462b24c8e4d61402ee36c6b 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/AlternatorReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/AlternatorReader.cs
@@ -76,7 +76,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 			if (g.Any(x => x.Count() < 2)) {
 				throw new ArgumentException(
 					"Insufficient rows in csv to build a usable map for alternator {0}",
-					string.Join(", ", g.Where(x => x.Count() < 2).Select(x => x.Key)));
+					g.Where(x => x.Count() < 2).Select(x => x.Key).Join());
 			}
 			return new CombinedAlternator(map, source);
 		}
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryInternalResistanceReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryInternalResistanceReader.cs
index 51f34949584695a0cb0fdb0afe60a6ff6153f924..6c765c12bcb531232c4a8d9325dfca8e7a91bebf 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryInternalResistanceReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryInternalResistanceReader.cs
@@ -27,12 +27,13 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 
 			if (data.Columns.Count == 2) {
 				if (!data.Columns.Contains(Fields.StateOfCharge) || !data.Columns.Contains(Fields.InternalResistance)) {
-					data.Columns[0].ColumnName = Fields.StateOfCharge;
-					data.Columns[1].ColumnName = Fields.InternalResistance;
 					LoggingObject.Logger<InternalResistanceMap>().Warn(
 						"Internal Resistance Map Header is invalid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
-						Fields.StateOfCharge, Fields.InternalResistance,
-						string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
+						Fields.StateOfCharge, 
+						Fields.InternalResistance,
+						data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
+					data.Columns[0].ColumnName = Fields.StateOfCharge;
+					data.Columns[1].ColumnName = Fields.InternalResistance;
 				}
 
 				return new InternalResistanceMap(data.Rows.Cast<DataRow>().Select(row => {
@@ -78,8 +79,8 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 				}
 				LoggingObject.Logger<InternalResistanceMap>().Warn(
 					"Internal Resistance Map Header is invalid. Expected: '{0}', Got: '{1}'. Falling back to column index.",
-					string.Join(", ", col1.Select(x => x.Item2)),
-					string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
+					col1.Select(x => x.Item2).Join(),
+					data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
 			}
 
 			
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryMaxCurrentReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryMaxCurrentReader.cs
index 5747491d5a31f6057510232f28f0b3051fcafd7a..612baa24643cb1b85945ac6619705acae9960117 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryMaxCurrentReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatteryMaxCurrentReader.cs
@@ -22,11 +22,15 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 			}
 
 			if (!data.Columns.Contains(Fields.StateOfCharge) || !data.Columns.Contains(Fields.MaxDischargeCurrent) || !data.Columns.Contains(Fields.MaxChargeCurrent)) {
+				LoggingObject.Logger<InternalResistanceMap>().Warn(
+					"Max Current  Map Header is invalid. Expected: '{0}, {1}, {2}', Got: '{3}'. Falling back to column index.",
+					Fields.StateOfCharge,
+					Fields.MaxChargeCurrent,
+					Fields.MaxDischargeCurrent,
+					data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
 				data.Columns[0].ColumnName = Fields.StateOfCharge;
 				data.Columns[1].ColumnName = Fields.MaxChargeCurrent;
 				data.Columns[2].ColumnName = Fields.MaxDischargeCurrent;
-				LoggingObject.Logger<InternalResistanceMap>().Warn("Max Current  Map Header is invalid. Expected: '{0}, {1}, {2}', Got: '{3}'. Falling back to column index.",
-					Fields.StateOfCharge, Fields.MaxChargeCurrent, Fields.MaxDischargeCurrent, string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
 			}
 			return new MaxCurrentMap(data.Rows.Cast<DataRow>().Select(row => new MaxCurrentMap.MaxCurrentEntry() {
 				SoC = row.ParseDouble(Fields.StateOfCharge) / 100,
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs
index 3c6f5bd0159d49a882e0daa5110fe439a320df7b..ac3b230f9ed4ad3710a0cc62dbfce276a1595ebc 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/BatterySOCReader.cs
@@ -30,8 +30,11 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData {
 			{
 				data.Columns[0].ColumnName = Fields.StateOfCharge;
 				data.Columns[1].ColumnName = Fields.BatteryVoltage;
-				LoggingObject.Logger<SOCMap>().Warn("SoC-Map Header is invalid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
-					Fields.StateOfCharge, Fields.BatteryVoltage, string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
+				LoggingObject.Logger<SOCMap>().Warn(
+					"SoC-Map Header is invalid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
+					Fields.StateOfCharge, 
+					Fields.BatteryVoltage,
+					data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
 			}
 			return new SOCMap(data.Rows.Cast<DataRow>().Select(row => new SOCMap.SOCMapEntry
 			{
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/CompressorMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/CompressorMapReader.cs
index 93e7c02fdd71d1ad678047abbbb770c3af85847d..98ff4d9dcc5eec61c850de7ff9a9debcfa9cae14 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/CompressorMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/CompressorMapReader.cs
@@ -12,7 +12,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 {
 	public class CompressorMapReader
 	{
-		public static readonly string[] Header = new[] { Fields.RPM, Fields.FlowRate, Fields.PowerOn, Fields.PowerOff };
+		public static readonly string[] Header = { Fields.RPM, Fields.FlowRate, Fields.PowerOn, Fields.PowerOff };
 
 		public static ICompressorMap ReadFile(string filename, double dragCurveFactorClutch, string technology)
 		{
@@ -27,10 +27,9 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 		public static IList<CompressorMapValues> Create(DataTable data, double dragCurveFactorClutch)
 		{
 			if (!HeaderIsValid(data.Columns)) {
-				throw new VectoException(
-					"Invalid column header. expected: {0}, got: {1}", 
-					string.Join(", ", data.Columns.Cast<DataColumn>().Select(x => x.ColumnName)),
-					string.Join(", ", Header));
+				throw new VectoException("Invalid column header. Expected: {0}, Got: {1}",
+					Header.Join(),
+					data.Columns.Cast<DataColumn>().Select(x => x.ColumnName).Join());
 			}
 
 			if (data.Rows.Count < 3) {
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/DrivingCycleDataReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/DrivingCycleDataReader.cs
index 0e902e94c8df2de7d716e25bda085dc62453dc7d..fad460b71b359dd74fe91657b3595b5fbf526057 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/DrivingCycleDataReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/DrivingCycleDataReader.cs
@@ -388,7 +388,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 				var diff = headerStr.GroupBy(c => c).Where(g => g.Count() > 2).SelectMany(g => g).ToList();
 				if (diff.Any()) {
 					if (throwExceptions) {
-						throw new VectoException("Column(s) defined more than once: " + string.Join(", ", diff.OrderBy(x => x)));
+						throw new VectoException($"Column(s) defined more than once: {diff.OrderBy(x => x).Join()}");
 					}
 
 					return false;
@@ -401,7 +401,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 				diff = headerStr.Except(allowedCols.Select(x => x.ToLowerInvariant())).ToList();
 				if (diff.Any()) {
 					if (throwExceptions) {
-						throw new VectoException("Column(s) not allowed: " + string.Join(", ", diff));
+						throw new VectoException($"Column(s) not allowed: {diff.Join()}");
 					}
 
 					return false;
@@ -410,7 +410,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 				diff = requiredCols.Select(x => x.ToLowerInvariant()).Except(headerStr).ToList();
 				if (diff.Any()) {
 					if (throwExceptions) {
-						throw new VectoException("Column(s) required: " + string.Join(", ", diff));
+						throw new VectoException($"Column(s) required: {diff.Join()}");
 					}
 
 					return false;
@@ -427,7 +427,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 
 				if (colCount != 0 && colCount != cols.Length) {
 					if (throwExceptions) {
-						throw new VectoException("Either all columns have to be defined or none of them: {0}", string.Join(", ", cols));
+						throw new VectoException("Either all columns have to be defined or none of them: {0}", cols.Join());
 					}
 
 					return false;
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricConsumerReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricConsumerReader.cs
index 5e8bb8f525d361054e6f1a1c5352dc0c23f725d6..adf8c13612a9f96851fa5c3ee47f3ff2d519ff0f 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricConsumerReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricConsumerReader.cs
@@ -28,14 +28,14 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 		public static ElectricalConsumerList Create(TableData data)
 		{
 			if (!HeaderValid(data.Columns)) {
-				throw new VectoException("Invalid header. Expected: {0}, got: {1}",
-					string.Join(", ", Header),
-					string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
+				throw new VectoException("Invalid header. Expected: {0}, Got: {1}",
+					Header.Join(),
+					data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
 			}
 
 			var retVal = new List<ElectricalConsumer>();
 			foreach (DataRow row in data.Rows) {
-				var consumer = new ElectricalConsumer() {
+				var consumer = new ElectricalConsumer {
 					Category = row.Field<string>(Fields.Category),
 					ConsumerName = row.Field<string>(Fields.Consumer),
 					BaseVehicle = row.ParseBoolean(Fields.BaseVehicle),
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs
index 87ce14fdeded1a6213944426cbd71d422731da7e..7b819b5d8a8deb2ef6724dfbc58c88fd5b2c6bed 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/ElectricMotorMapReader.cs
@@ -24,7 +24,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData {
 			if (!headerValid)
 			{
 				LoggingObject.Logger<FuelConsumptionMap>().Warn(
-					"Efficiency Map: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: {3}. Falling back to default names.",
+					"Efficiency Map: Header Line is not valid. Expected: '{0}, {1}, {2}', Got: {3}. Falling back to column index.",
 					Fields.MotorSpeed, 
 					Fields.Torque, 
 					Fields.PowerElectrical,
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/EnvironmentalContidionsMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/EnvironmentalContidionsMapReader.cs
index f7dd3ee0922a8a6cece5b3dcd544b8e627fc8732..ee81cf6cdd239abccca46b1f0b31953d1957bbae 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/EnvironmentalContidionsMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/EnvironmentalContidionsMapReader.cs
@@ -39,9 +39,9 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 
 			if (!HeaderIsValid(data.Columns)) {
 				throw new VectoException(
-					"Invalid Header for environmental conditions. Got: {0}, expected: {1}",
-					string.Join(", ", data.Columns.Cast<DataColumn>().Select(x => x.ColumnName)), 
-					string.Join(", ", Header));
+					"Invalid Header for environmental conditions. Expected: {0}, Got: {1}",
+					Header.Join(),
+					data.Columns.Cast<DataColumn>().Select(x => x.ColumnName).Join());
 			}
 
 			foreach (DataRow row in data.Rows) {
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/FullLoadCurveReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/FullLoadCurveReader.cs
index f7f914d3ef5115d6b0f59de1189a742c9152d5e7..f816b8fdbb624e17bd3e315c6b8bc7db20187b4b 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/FullLoadCurveReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/FullLoadCurveReader.cs
@@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 										.Select(g => g.Key).ToList();
 			if (duplicates.Count > 0) {
 				throw new VectoException(
-					"Error reading full-load curve: multiple entries for engine speeds {0}", string.Join(", ", duplicates));
+					"Error reading full-load curve: multiple entries for engine speeds {0}", duplicates.Join());
 			}
 			return new EngineFullLoadCurve(entriesFld, tmp);
 		}
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs
index 86c7d840e748e4a84c275f5ef7d634bb151139d1..e6f051bc78a337c81934fc0635384f8f02aaf11c 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/PTOIdleLossMapReader.cs
@@ -69,7 +69,7 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 
 			if (!(data.Columns.Contains(Fields.EngineSpeed) && data.Columns.Contains(Fields.PTOTorque))) {
 				LoggingObject.Logger<RetarderLossMap>().Warn(
-					"PTO Idle LossMap: Header Line is not valid. Expected: '{0}, {1}', Got: '{2}'. Falling back to default names.",
+					"PTO Idle LossMap: Header Line is not valid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
 					Fields.EngineSpeed, 
 					Fields.PTOTorque, 
 					data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs
index be825fece992cea14d8d9bd891605a42a5e1bb51..b4f60d00680a1aad33d832321e46afcfe73eb741 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/RetarderLossMapReader.cs
@@ -70,10 +70,10 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 
 			if (!data.Columns.Contains(Fields.RetarderSpeed) || !data.Columns.Contains(Fields.TorqueLoss)) {
 				LoggingObject.Logger<RetarderLossMap>().Warn(
-					"RetarderLossMap: Header Line is not valid. Expected: '{0}, {1}', Got: '{2}'. Falling back to default names.",
+					"RetarderLossMap: Header Line is not valid. Expected: '{0}, {1}', Got: '{2}'. Falling back to column index.",
 					Fields.RetarderSpeed,
 					Fields.TorqueLoss,
-					string.Join(", ", data.Columns.Cast<DataColumn>().Select(c => c.ColumnName)));
+					data.Columns.Cast<DataColumn>().Select(c => c.ColumnName).Join());
 				data.Columns[0].ColumnName = Fields.RetarderSpeed;
 				data.Columns[1].ColumnName = Fields.TorqueLoss;
 			}
diff --git a/VectoCore/VectoCore/InputData/Reader/ComponentData/SSMTechnologiesReader.cs b/VectoCore/VectoCore/InputData/Reader/ComponentData/SSMTechnologiesReader.cs
index 6e9cc83ea5d9a43a5fdfc56f7604a1e2a1eca2b4..ace65ad980bb95ed67a27576129dfee528a66ceb 100644
--- a/VectoCore/VectoCore/InputData/Reader/ComponentData/SSMTechnologiesReader.cs
+++ b/VectoCore/VectoCore/InputData/Reader/ComponentData/SSMTechnologiesReader.cs
@@ -4,6 +4,7 @@ using System.IO;
 using System.Linq;
 using TUGraz.VectoCommon.BusAuxiliaries;
 using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Models.BusAuxiliaries.DownstreamModules.Impl.HVAC;
 using TUGraz.VectoCore.Models.Declaration;
 using TUGraz.VectoCore.Utils;
@@ -34,9 +35,9 @@ namespace TUGraz.VectoCore.InputData.Reader.ComponentData
 		public static List<SSMTechnology> Create(DataTable data, string fileName)
 		{
 			if (!HeaderIsValid(data.Columns)) {
-				throw new VectoException("invalid header for techlist file. expected: {0} got: {1}",
-					string.Join(", ", headerCols), string.Join(", ",  data.Columns)
-					);
+				throw new VectoException("invalid header for techlist file. Expected: {0}, Got: {1}",
+					headerCols.Join(),
+					data.Columns.Cast<DataColumn>().Join());
 			}
 
 			var retVal = new List<SSMTechnology>();
diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs
index 9c9675d60b1d65d6307e275f1fb3efd95b45a7c0..a64d9ad9801f8d15824061f93ee3f7d9f6a1b76f 100644
--- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs
+++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/BatteryResponse.cs
@@ -89,7 +89,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 		public override string ToString()
 		{
 			var t = GetType();
-			return $"{t.Name}{{{string.Join(", ", t.GetProperties().Select(p => $"{p.Name}: {p.GetValue(this)}"))}}}";
+			return $"{t.Name}{{{t.GetProperties().Select(p => $"{p.Name}: {p.GetValue(this)}").Join()}}}";
 		}
 	}
 
diff --git a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs
index ab6c8ffcfd41a629788dcaddc54fc12d683463b1..1953ba8a193cfd6baa92efef29ea02fc21dee929 100644
--- a/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs
+++ b/VectoCore/VectoCore/Models/Connector/Ports/Impl/Response.cs
@@ -110,7 +110,7 @@ namespace TUGraz.VectoCore.Models.Connector.Ports.Impl
 		public override string ToString()
 		{
 			var t = GetType();
-			return $"{t.Name}{{{string.Join(", ", t.GetProperties().Select(p => $"{p.Name}: {p.GetValue(this)}"))}}}";
+			return $"{t.Name}{{{t.GetProperties().Select(p => $"{p.Name}: {p.GetValue(this)}").Join()}}}";
 		}
 	}
 
diff --git a/VectoCore/VectoCore/Models/Declaration/WeightingGroups.cs b/VectoCore/VectoCore/Models/Declaration/WeightingGroups.cs
index c09199e027e0fb5a16f8f903691317649ac5e718..ba02d6eb54d14f50e44b1380da8dd994d2d0579f 100644
--- a/VectoCore/VectoCore/Models/Declaration/WeightingGroups.cs
+++ b/VectoCore/VectoCore/Models/Declaration/WeightingGroups.cs
@@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.Models.Declaration
 				case WeightingGroup.Group9LH:
 				case WeightingGroup.Group10RD:
 				case WeightingGroup.Group10LH:
-					return string.Join("-", Regex.Split(group.ToString().Replace(Prefix, ""), @"(\d+|\w+)").Where(x => !string.IsNullOrWhiteSpace(x)));
+					return Regex.Split(group.ToString().Replace(Prefix, ""), @"(\d+|\w+)").Where(x => !string.IsNullOrWhiteSpace(x)).Join("-");
 				default:
 					return Constants.NOT_AVAILABLE;
 			}
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/PCCSegmentPreprocessor.cs b/VectoCore/VectoCore/Models/Simulation/Impl/PCCSegmentPreprocessor.cs
index 0362e869ec363b4d9153af13a857cd7d87522825..fa963140e55e0e9b7c89840e8bdcd8a7592f2877 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/PCCSegmentPreprocessor.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/PCCSegmentPreprocessor.cs
@@ -34,7 +34,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			var preProcessor = new PCCEcoRollEngineStopPreprocessor(Container, slopes, PCCDriverData.MinSpeed, maxSpeed);
 			preProcessor.RunPreprocessing();
 
-			DebugWriteLine("Slopes:\n" + string.Join("\n", slopes.Select(p => $"{p.Key.AsKmph:F}\t{p.Value.ToInclinationPercent():P}")));
+			DebugWriteLine($"Slopes:\n{slopes.Select(p => $"{p.Key.AsKmph:F}\t{p.Value.ToInclinationPercent():P}").Join("\n")}");
 
 			var runData = Container.RunData;
 
diff --git a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs
index a92f711d82288a5ce7eb467fdef8c9869d42b514..6b902d12c2bccb46d3e3fcf0cec2ec38fc8122ec 100644
--- a/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs
+++ b/VectoCore/VectoCore/Models/Simulation/Impl/SimulatorFactory.cs
@@ -288,7 +288,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Impl
 			var validationErrors = run.Validate(_mode, jobType, emPosition, gearboxtype, isEms);
 			if (validationErrors.Any()) {
 				throw new VectoException("Validation of Run-Data Failed: " +
-										string.Join("\n", validationErrors.Select(r => r.ErrorMessage + string.Join("; ", r.MemberNames))));
+										$"{validationErrors.Select(r => r.ErrorMessage + r.MemberNames.Join("; ")).Join("\n")}");
 			}
 		}
 
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs b/VectoCore/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs
index 784b775cc30020e7c5ae10b567035a5997d42a51..6807e36b06539670cb2518fc5241481f5d245eb5 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Data/AccelerationCurve.cs
@@ -49,7 +49,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Data
 			if (smallValues.Count >= 2) {
 				Log.Error(
 					"Found small velocity entries in Driver-Acceleration/Deceleration file. Values dismissed:" +
-					string.Join(", ", smallValues.Skip(1).Select(e => e.Key.AsKmph.ToString("F1"))));
+					smallValues.Skip(1).Select(e => e.Key.AsKmph.ToString("F1")).Join());
 				foreach (var kv in smallValues.Skip(1)) {
 					_entries.Remove(kv);
 				}
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
index 87a05b118fdb2fa0392125f3b1a4b313b2d8743b..34bb373eafef900e5f9eb611155e3825b824ada3 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/ATShiftStrategy.cs
@@ -83,7 +83,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 			EngineInertia = dataBus.RunData.EngineData?.Inertia ?? 0.SI<KilogramSquareMeter>();
 
 			if (Gears.Any(x => !x.TorqueConverterLocked.HasValue)) {
-				throw new VectoException("Gear list must have TC info for all gears! {0}", string.Join(", ", Gears));
+				throw new VectoException("Gear list must have TC info for all gears! {0}", Gears.Join());
 			}
 
 			MaxStartGear = Gears.Any() ? Gears.First() : new GearshiftPosition(0);
diff --git a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatterySystem.cs b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatterySystem.cs
index 8ea633a720e7c4af99780591fb4075cf72cc0747..638a043f1ae2cf4dfda8118b28d417ad9abd53bd 100644
--- a/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatterySystem.cs
+++ b/VectoCore/VectoCore/Models/SimulationComponent/Impl/BatterySystem.cs
@@ -283,7 +283,7 @@ namespace TUGraz.VectoCore.Models.SimulationComponent.Impl
 				}
 
 				if (limitBB.Count > 0) {
-					Log.Debug($"BB ${string.Join(", ", limitBB.Keys)} are at max - recalculating power distribution");
+					Log.Debug($"BB ${limitBB.Keys.Join()} are at max - recalculating power distribution");
 				}
 			} while (!(distributedPower + (limitBB.Sum(x => x.Value) ?? 0.SI<Watt>())) .IsEqual(powerDemand, 1e-3.SI<Watt>()));
 
diff --git a/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs b/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs
index 5f0645b84e2936063fb9d69dc6a138c7b984c6bd..c43e7a352ccbd2882152a0e557a9d4f76cf851b7 100644
--- a/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs
+++ b/VectoCore/VectoCore/OutputData/ModalDataPostprocessingCorrection.cs
@@ -181,8 +181,8 @@ namespace TUGraz.VectoCore.OutputData
 				// case C3a
 				if (runData.ElectricMachinesData.Count != 1) {
 					throw new VectoException("exactly 1 electric machine is required. got {0} ({1})",
-						runData.ElectricMachinesData.Count,
-						string.Join(",", runData.ElectricMachinesData.Select(x => x.Item1.ToString())));
+						runData.ElectricMachinesData.Count, 
+						runData.ElectricMachinesData.Select(x => x.Item1.ToString()).Join());
 				}
 
 				var emPos = runData.ElectricMachinesData.First().Item1;
@@ -269,7 +269,7 @@ namespace TUGraz.VectoCore.OutputData
 					if (runData.ElectricMachinesData.Count != 1) {
 						throw new VectoException("exactly 1 electric machine is required. got {0} ({1})",
 							runData.ElectricMachinesData.Count,
-							string.Join(",", runData.ElectricMachinesData.Select(x => x.Item1.ToString())));
+							runData.ElectricMachinesData.Select(x => x.Item1.ToString()).Join());
 					}
 
 					var emPos = runData.ElectricMachinesData.First().Item1;
diff --git a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
index 6a49ebb3f49ddc598119212175aed4791ae98e14..9cb330b27c6afcf5c54ee5cd0ebbbdbdc8f39b53 100644
--- a/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
+++ b/VectoCore/VectoCore/OutputData/SummaryDataContainer.cs
@@ -310,7 +310,7 @@ namespace TUGraz.VectoCore.OutputData
 				passengerCount = runData.VehicleData.PassengerCount;
 			}
 
-			row[Fields.VEHICLE_FUEL_TYPE] = string.Join(", ", modData.FuelData.Select(x => x.GetLabel()));
+			row[Fields.VEHICLE_FUEL_TYPE] = modData.FuelData.Select(x => x.GetLabel().Join());
 
 			var totalTime = modData.Duration;
 			row[Fields.TIME] = (ConvertedSI)totalTime;
@@ -347,7 +347,7 @@ namespace TUGraz.VectoCore.OutputData
 											fuel => modData.TimeIntegral<Kilogram>(modData.GetColumnName(fuel.FuelData, ModalResultField.FCWHTCc)) /
 													modData.TimeIntegral<Kilogram>(modData.GetColumnName(fuel.FuelData, ModalResultField.FCMap)))
 										.Select(dummy => (double)dummy).ToArray();
-				row[Fields.ENGINE_ACTUAL_CORRECTION_FACTOR] = string.Join(" / ", fuelsWhtc);
+				row[Fields.ENGINE_ACTUAL_CORRECTION_FACTOR] = fuelsWhtc.Join(" / ");
 			}
 
 			row[Fields.P_WHEEL_POS] = modData.PowerWheelPositive().ConvertToKiloWatt();
@@ -840,7 +840,7 @@ namespace TUGraz.VectoCore.OutputData
 			row[Fields.ENGINE_MANUFACTURER] = data.Manufacturer;
 			row[Fields.ENGINE_MODEL] = data.ModelName;
 			row[Fields.ENGINE_CERTIFICATION_NUMBER] = data.CertificationNumber;
-			row[Fields.ENGINE_FUEL_TYPE] = string.Join(" / ", data.Fuels.Select(x => x.FuelData.GetLabel()));
+			row[Fields.ENGINE_FUEL_TYPE] = data.Fuels.Select(x => x.FuelData.GetLabel()).Join(" / ");
 			row[Fields.ENGINE_RATED_POWER] = data.RatedPowerDeclared != null && data.RatedPowerDeclared > 0
 				? data.RatedPowerDeclared.ConvertToKiloWatt()
 				: data.FullLoadCurves[0].MaxPower.ConvertToKiloWatt();
@@ -850,12 +850,12 @@ namespace TUGraz.VectoCore.OutputData
 				: (ConvertedSI)data.FullLoadCurves[0].RatedSpeed.AsRPM.SI<Scalar>();
 			row[Fields.ENGINE_DISPLACEMENT] = data.Displacement.ConvertToCubicCentiMeter();
 
-			row[Fields.ENGINE_WHTC_URBAN] = string.Join(" / ", data.Fuels.Select(x => x.WHTCUrban));
-			row[Fields.ENGINE_WHTC_RURAL] = string.Join(" / ", data.Fuels.Select(x => x.WHTCRural));
-			row[Fields.ENGINE_WHTC_MOTORWAY] = string.Join(" / ", data.Fuels.Select(x => x.WHTCMotorway));
-			row[Fields.ENGINE_BF_COLD_HOT] = string.Join(" / ", data.Fuels.Select(x => x.ColdHotCorrectionFactor));
-			row[Fields.ENGINE_CF_REG_PER] = string.Join(" / ", data.Fuels.Select(x => x.CorrectionFactorRegPer));
-			row[Fields.ENGINE_ACTUAL_CORRECTION_FACTOR] = string.Join(" / ", data.Fuels.Select(x => x.FuelConsumptionCorrectionFactor));
+			row[Fields.ENGINE_WHTC_URBAN] = data.Fuels.Select(x => x.WHTCUrban).Join(" / ");
+			row[Fields.ENGINE_WHTC_RURAL] = data.Fuels.Select(x => x.WHTCRural).Join(" / ");
+			row[Fields.ENGINE_WHTC_MOTORWAY] = data.Fuels.Select(x => x.WHTCMotorway).Join(" / ");
+			row[Fields.ENGINE_BF_COLD_HOT] = data.Fuels.Select(x => x.ColdHotCorrectionFactor).Join(" / ");
+			row[Fields.ENGINE_CF_REG_PER] = data.Fuels.Select(x => x.CorrectionFactorRegPer).Join(" / ");
+			row[Fields.ENGINE_ACTUAL_CORRECTION_FACTOR] = data.Fuels.Select(x => x.FuelConsumptionCorrectionFactor).Join(" / ");
 		}
 
 		private static void WriteAxleWheelsData(List<Axle> data, DataRow row)
@@ -913,7 +913,7 @@ namespace TUGraz.VectoCore.OutputData
 						col.SetOrdinal(Table.Columns[Fields.CARGO_VOLUME].Ordinal);
 					}
 
-				row[colName] = aux.Technology == null ? "" : string.Join("; ", aux.Technology);
+				row[colName] = aux.Technology == null ? "" : aux.Technology.Join("; ");
 			}
 
 			if (busAux == null) {
@@ -923,7 +923,7 @@ namespace TUGraz.VectoCore.OutputData
 			row[string.Format(Fields.AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.HeatingVentilationAirCondition)] =
 				busAux.SSMInputs is ISSMDeclarationInputs inputs ? inputs.HVACTechnology : "engineering mode";
 			row[string.Format(Fields.AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.ElectricSystem)] =
-				string.Join("/", busAux.ElectricalUserInputsConfig.AlternatorType.GetLabel());
+				busAux.ElectricalUserInputsConfig.AlternatorType.GetLabel().Join("/");
 			row[string.Format(Fields.AUX_TECH_FORMAT, Constants.Auxiliaries.IDs.PneumaticSystem)] = runData.JobType == VectoSimulationJobType.BatteryElectricVehicle ? "-" :
 				busAux.PneumaticUserInputsConfig.CompressorMap.Technology;
 		}
diff --git a/VectoCore/VectoCore/OutputData/XML/Engineering/XMLEngineeringWriter.cs b/VectoCore/VectoCore/OutputData/XML/Engineering/XMLEngineeringWriter.cs
index 523c1d2bbdfc035be37483b20397a3920ee24eac..7a264233edcb4550215c763921976fdbc3a37e38 100644
--- a/VectoCore/VectoCore/OutputData/XML/Engineering/XMLEngineeringWriter.cs
+++ b/VectoCore/VectoCore/OutputData/XML/Engineering/XMLEngineeringWriter.cs
@@ -38,6 +38,7 @@ using Ninject;
 using TUGraz.VectoCommon.Exceptions;
 using TUGraz.VectoCommon.InputData;
 using TUGraz.VectoCommon.Resources;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.OutputData.XML.Engineering.Factory;
 using TUGraz.VectoCore.OutputData.XML.Engineering.Interfaces;
 using TUGraz.VectoCore.Utils;
@@ -127,10 +128,8 @@ namespace TUGraz.VectoCore.OutputData.XML.Engineering
 		private XAttribute GetSchemaLocations()
 		{
 			var xsns = RegisterNamespace(XMLDefinitions.XML_SCHEMA_NAMESPACE);
-
-			return new XAttribute(
-				xsns + "schemaLocation",
-				string.Join(" ", NamespaceLocationMap.Where(x => _namespaces.ContainsKey(x.Key)).Select(x => $"{x.Key} {x.Value}")));
+			return new XAttribute(xsns + "schemaLocation", 
+				NamespaceLocationMap.Where(x => _namespaces.ContainsKey(x.Key)).Select(x => $"{x.Key} {x.Value}").Join(" "));
 		}
 
 		public WriterConfiguration Configuration { get; set; }
diff --git a/VectoCore/VectoCore/Utils/DataIntegrityHelper.cs b/VectoCore/VectoCore/Utils/DataIntegrityHelper.cs
index edc9e98a1ea4aa3be9d37ae88e47430358216b33..2c02bc0442bee3d7e835d49ce8aa47a8343e9a66 100644
--- a/VectoCore/VectoCore/Utils/DataIntegrityHelper.cs
+++ b/VectoCore/VectoCore/Utils/DataIntegrityHelper.cs
@@ -31,6 +31,7 @@
 
 using System.Security.Cryptography;
 using System.Text;
+using TUGraz.VectoCommon.Utils;
 
 namespace TUGraz.VectoCore.Utils
 {
@@ -38,8 +39,7 @@ namespace TUGraz.VectoCore.Utils
 	{
 		public static string ComputeDigestValue(string[] lines)
 		{
-			var hash = System.Convert.ToBase64String(GetHash(string.Join("\n", lines)));
-
+			var hash = System.Convert.ToBase64String(GetHash(lines.Join("\n")));
 			return $"SHA256: {hash}";
 		}
 
diff --git a/VectoCore/VectoCore/Utils/DebugData.cs b/VectoCore/VectoCore/Utils/DebugData.cs
index e1c69f24b982bfd9ae15920e008c313fce2a83cc..59b053efe03ac035793f167c20a741370af74659 100644
--- a/VectoCore/VectoCore/Utils/DebugData.cs
+++ b/VectoCore/VectoCore/Utils/DebugData.cs
@@ -31,6 +31,7 @@
 
 using System.Collections.Generic;
 using System.Diagnostics;
+using TUGraz.VectoCommon.Utils;
 
 namespace TUGraz.VectoCore.Utils
 {
@@ -54,7 +55,7 @@ namespace TUGraz.VectoCore.Utils
 		public override string ToString()
 		{
 #if DEBUG
-			return string.Join("\n", Data);
+			return Data.Join("\n");
 #else
 				return "-";
 			#endif
diff --git a/VectoCore/VectoCore/Utils/DelaunayMap.cs b/VectoCore/VectoCore/Utils/DelaunayMap.cs
index 15555fb7e99f9091164c6216a66443b049732360..84afb4eb9280fd5495dc2bfbcd741f8520734d4d 100644
--- a/VectoCore/VectoCore/Utils/DelaunayMap.cs
+++ b/VectoCore/VectoCore/Utils/DelaunayMap.cs
@@ -163,7 +163,7 @@ namespace TUGraz.VectoCore.Utils
 			}
 			if (duplicates.Any()) {
 				throw new VectoException("{0}: Input Data for Delaunay map contains duplicates! \n{1}", _mapName,
-					string.Join("\n", duplicates.Select(pt => $"{pt.Key.X} / {pt.Key.Y}")));
+					duplicates.Select(pt => $"{pt.Key.X} / {pt.Key.Y}").Join("\n"));
 			}
 		}
 
@@ -220,8 +220,8 @@ namespace TUGraz.VectoCore.Utils
 				var frame = new StackFrame(2);
 				var method = frame.GetMethod();
 				System.Diagnostics.Debug.Assert(method.DeclaringType != null, "method.DeclaringType != null");
-				var type = string.Join("", method.DeclaringType.Name.Split(Path.GetInvalidFileNameChars()));
-				var methodName = string.Join("", method.Name.Split(Path.GetInvalidFileNameChars()));
+				var type = method.DeclaringType.Name.Split(Path.GetInvalidFileNameChars()).Join("");
+				var methodName = method.Name.Split(Path.GetInvalidFileNameChars()).Join("");
 				Directory.CreateDirectory("delaunay");
 				chart.SaveImage($"delaunay\\{type}_{methodName}_{superTriangle.GetHashCode()}_{i}.png",
 					ChartImageFormat.Png);
diff --git a/VectoCore/VectoCore/Utils/VectoCSVFile.cs b/VectoCore/VectoCore/Utils/VectoCSVFile.cs
index e4974252dbcb3c43c966eb21bdad52a54f8667f3..3f7928e12af4795b86e01068036b608398452719 100644
--- a/VectoCore/VectoCore/Utils/VectoCSVFile.cs
+++ b/VectoCore/VectoCore/Utils/VectoCSVFile.cs
@@ -208,7 +208,7 @@ namespace TUGraz.VectoCore.Utils
 				}
 			}
 			var header = table.Columns.Cast<DataColumn>().Select(col => col.Caption ?? col.ColumnName);
-			entries.Add(string.Join(Delimiter, header));
+			entries.Add(header.Join(Delimiter));
 
 			var columnFormatter = new Func<ConvertedSI, string>[table.Columns.Count];
 			for (var i = 0; i < table.Columns.Count; i++) {
@@ -241,7 +241,7 @@ namespace TUGraz.VectoCore.Utils
 						formattedList[i] = $"\"{formattedList[i]}\"";
 					}
 				}
-				entries.Add(string.Join(Delimiter, formattedList));
+				entries.Add(formattedList.Join(Delimiter));
 			}
 
 			if (addDigest) {
diff --git a/VectoCore/VectoCore/Utils/XMLHelper.cs b/VectoCore/VectoCore/Utils/XMLHelper.cs
index 49d6fff697cf95f5e99990f585ccfb94b57c375f..d9cdfdd8aa9bf8a654750b20d1c227fd0bc04094 100644
--- a/VectoCore/VectoCore/Utils/XMLHelper.cs
+++ b/VectoCore/VectoCore/Utils/XMLHelper.cs
@@ -187,7 +187,7 @@ namespace TUGraz.VectoCore.Utils
 
 		public static string QueryLocalName(params string[] nodePath)
 		{
-			return "./" + string.Join("/", nodePath.Where(x => x != null).Select(x => $"/*[local-name()='{x}']").ToArray());
+			return "./" + nodePath.Where(x => x != null).Select(x => $"/*[local-name()='{x}']").Join("/");
 		}
 
 
diff --git a/VectoCore/VectoCore/Utils/XMLValidator.cs b/VectoCore/VectoCore/Utils/XMLValidator.cs
index e477b6710b975e434f4599ea60b54ae0b4879c5f..2fc93738b9ec68c14b76972371ff72cf69aefa8b 100644
--- a/VectoCore/VectoCore/Utils/XMLValidator.cs
+++ b/VectoCore/VectoCore/Utils/XMLValidator.cs
@@ -99,7 +99,7 @@ namespace TUGraz.VectoCore.Utils
 			_validationErrorAction(args?.Severity ?? XmlSeverityType.Error, new ValidationEvent { ValidationEventArgs = args });
 		}
 
-		public string ValidationError => _validationErrors.Any() ? string.Join(Environment.NewLine, _validationErrors) : null;
+		public string ValidationError => _validationErrors.Any() ? _validationErrors.Join(Environment.NewLine) : null;
 
 		public static void CallBackExceptionOnError(XmlSeverityType severity, ValidationEvent evt)
 		{
diff --git a/VectoCore/VectoCore/Utils/XPathHelper.cs b/VectoCore/VectoCore/Utils/XPathHelper.cs
index 3f18f3a79d84279eaad183e20bb2807d41a899b2..a9177e08ce06749d05c13d0a746e4244491b554e 100644
--- a/VectoCore/VectoCore/Utils/XPathHelper.cs
+++ b/VectoCore/VectoCore/Utils/XPathHelper.cs
@@ -32,6 +32,7 @@
 using System.Linq;
 using System.Xml;
 using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Configuration;
 
 namespace TUGraz.VectoCore.Utils
@@ -49,12 +50,9 @@ namespace TUGraz.VectoCore.Utils
 				: Constants.XML.EngineeringNSPrefix;
 		}
 
-		public string Query(params string[] xpathSections)
-		{
-			return string.Join("/",
-				xpathSections.Select(
-					x => string.IsNullOrWhiteSpace(x) || x.StartsWith("..") || x.Contains(":") || x.StartsWith("@") ? x : NSPrefix(x)))
-				;
+		public string Query(params string[] xpathSections) {
+			return xpathSections.Select(
+				x => string.IsNullOrWhiteSpace(x) || x.StartsWith("..") || x.Contains(":") || x.StartsWith("@") ? x : NSPrefix(x)).Join("/");
 		}
 
 		public string QueryConstraint(string elementName, string name, string value,
diff --git a/VectoCore/VectoCoreTest/Algorithms/MeanShiftClusteringTest.cs b/VectoCore/VectoCoreTest/Algorithms/MeanShiftClusteringTest.cs
index 8bc4baba600bf587ab0e380aa6cc29510c04cbca..2ddaed78ae81533cd3424a7b57eeb9f130b0b319 100644
--- a/VectoCore/VectoCoreTest/Algorithms/MeanShiftClusteringTest.cs
+++ b/VectoCore/VectoCoreTest/Algorithms/MeanShiftClusteringTest.cs
@@ -33,6 +33,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using NUnit.Framework;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.Utils;
 
 namespace TUGraz.VectoCore.Tests.Algorithms
@@ -60,14 +61,14 @@ namespace TUGraz.VectoCore.Tests.Algorithms
 
 			//Console.WriteLine(string.Join(", ", entries));
 
-			var clusterer = new MeanShiftClustering() {
+			var clusterer = new MeanShiftClustering {
 				ClusterCount = 8
 			};
 			var clusters = clusterer.FindClusters(entries.ToArray(), 10);
 
 			//Console.WriteLine(clusterer.IterationCount);
-			Console.WriteLine(string.Join(", ", centers));
-			Console.WriteLine(string.Join(", ", clusters));
+			Console.WriteLine(centers.Join());
+			Console.WriteLine(clusters.Join());
 
 			Assert.AreEqual(centers.Length, clusters.Length);
 			foreach (var center in centers) {
@@ -87,7 +88,7 @@ namespace TUGraz.VectoCore.Tests.Algorithms
 			var clusterer = new MeanShiftClustering();
 			var clusters = clusterer.FindClusters(entries.ToArray(), 0.1);
 
-			Console.WriteLine(string.Join(", ", clusters));
+			Console.WriteLine(clusters.Join());
 		}
 	}
 }
diff --git a/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs b/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs
index 92b1d4a78c19b1324982ed3842f95d7ef37f956d..5a1ef168831f8a958b1e6c6589cbf8cd51d7cbe6 100644
--- a/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs
+++ b/VectoCore/VectoCoreTest/Integration/TorqueLimitsTest.cs
@@ -262,7 +262,7 @@ namespace TUGraz.VectoCore.Tests.Integration
 
 			Assert.IsTrue(jobContainer.Runs.All(r => r.Success), string.Concat(jobContainer.Runs.Select(r => r.ExecException)));
 			var view = new DataView(sumData.Table, "", SummaryDataContainer.Fields.SORT, DataViewRowState.CurrentRows).ToTable();
-			Console.WriteLine(string.Join("; ", view.AsEnumerable().Select(x => x[string.Format(SummaryDataContainer.Fields.FCMAP_KM, "")].ToString().ToDouble())));
+			Console.WriteLine(view.AsEnumerable().Select(x => x[string.Format(SummaryDataContainer.Fields.FCMAP_KM, "")].ToString().ToDouble()).Join("; "));
 			Assert.AreEqual(203.978084968944, view.Rows[0][string.Format(SummaryDataContainer.Fields.FCMAP_KM, "")].ToString().ToDouble(), 1e-3);
 			Assert.AreEqual(243.590313650134, view.Rows[1][string.Format(SummaryDataContainer.Fields.FCMAP_KM, "")].ToString().ToDouble(), 1e-3);
 			Assert.AreEqual(174.648229443338, view.Rows[2][string.Format(SummaryDataContainer.Fields.FCMAP_KM, "")].ToString().ToDouble(), 1e-3);
diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs
index 255c280cec46a2ce71ce3acdbeb32a865f1be010..5719c0f557702d7b5f36f2b8aa9bad7d8f440933 100644
--- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationDataTest.cs
@@ -2022,11 +2022,11 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
             Assert.AreEqual(missionType, m.MissionType);
             Assert.AreEqual(cosswindCorrection, m.CrossWindCorrectionParameters);
             CollectionAssert.AreEqual(axleWeightDistribution, m.AxleWeightDistribution,
-                "Axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", axleWeightDistribution),
-                string.Join(",", m.AxleWeightDistribution));
+                "Axle distribution not equal.\nexpected: {0}\nactual: {1}", axleWeightDistribution.Join(),
+                m.AxleWeightDistribution.Join());
             CollectionAssert.AreEqual(trailerAxleWeightDistribution, m.Trailer.Select(t => t.TrailerAxleWeightShare),
-                "Trailer axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", trailerAxleWeightDistribution),
-                string.Join(",", m.Trailer.Select(t => t.TrailerAxleWeightShare)));
+                "Trailer axle distribution not equal.\nexpected: {0}\nactual: {1}", trailerAxleWeightDistribution.Join(),
+                m.Trailer.Select(t => t.TrailerAxleWeightShare).Join());
             Assert.AreEqual(bodyCurbWeight.SI<Kilogram>(), m.BodyCurbWeight);
             CollectionAssert.AreEqual(trailerCurbWeight, m.Trailer.Select(t => t.TrailerCurbWeight.Value()));
             CollectionAssert.AreEqual(trailerType, m.Trailer.Select(t => t.TrailerType));
diff --git a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationSegmentHeavyBusesTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationSegmentHeavyBusesTest.cs
index c3c33b3ec2e8f52f664eaf1b905818559b3185a9..82a3184342d45b4a026f0749cc96f08cb5de70d8 100644
--- a/VectoCore/VectoCoreTest/Models/Declaration/DeclarationSegmentHeavyBusesTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Declaration/DeclarationSegmentHeavyBusesTest.cs
@@ -691,8 +691,8 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 			Assert.AreEqual(lowLoad, m.LowLoad.Value(), 1e-9);
 			foreach (var tuple in axleWeightDistribution.ZipAll(m.AxleWeightDistribution, Tuple.Create))
 			{
-				Assert.AreEqual(tuple.Item1, tuple.Item2, 1e-0, "Axle distribution not equal.\nexpected: {0}\nactual: {1}", string.Join(",", axleWeightDistribution),
-					string.Join(",", m.AxleWeightDistribution));
+				Assert.AreEqual(tuple.Item1, tuple.Item2, 1e-0, "Axle distribution not equal.\nexpected: {0}\nactual: {1}", 
+					axleWeightDistribution.Join(), m.AxleWeightDistribution.Join());
 			}
 
 			foreach (var entry in expVehicleEquipment) {
diff --git a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
index 44b0a43b6ac6726bf8df11e32b6e54ff7962b3fa..903e9647042fbe3c496db25bff2c83829bac18be 100644
--- a/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
+++ b/VectoCore/VectoCoreTest/Models/Declaration/ShiftPolygonTest.cs
@@ -842,7 +842,7 @@ namespace TUGraz.VectoCore.Tests.Models.Declaration
 						InputDataHelper.InputDataAsStream("engine torque,downshift rpm [rpm],upshift rpm [rpm]	", vgbs)));
 
 			var results = shiftPolygon.Validate(ExecutionMode.Engineering, VectoSimulationJobType.ConventionalVehicle, null, GearboxType.MT, false);
-			Assert.IsFalse(results.Any(), string.Join("\n", results.Select(r => r.ErrorMessage)));
+			Assert.IsFalse(results.Any(), results.Select(r => r.ErrorMessage).Join("\n"));
 		}
 
 		[
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponent/BatterySystemTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponent/BatterySystemTest.cs
index 85cd34b222187ff93ef7467c77c533a509673bc0..e513e94a440b4aa7eab2f3fe06ec21d4a9504f73 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponent/BatterySystemTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponent/BatterySystemTest.cs
@@ -166,7 +166,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 			}
 
 			var socs = bat.Batteries.SelectMany(x => x.Value.Batteries.Select(y => y.StateOfCharge)).ToArray();
-			Console.WriteLine(string.Join(", ", socs));
+			Console.WriteLine(socs.Join());
 			for (var i = 0; i < socs.Length; i++) {
 				Assert.AreEqual(expectedSoC[i], socs[i], 1e-9, $"Bat_{i} SoC");
 			}
@@ -234,7 +234,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 			}
 
 			var socs = bat.Batteries.SelectMany(x => x.Value.Batteries.Select(y => y.StateOfCharge)).ToArray();
-			Console.WriteLine(string.Join(", ", socs));
+			Console.WriteLine(socs.Join());
 			Console.WriteLine(bat.StateOfCharge);
 			for (var i = 0; i < socs.Length; i++) {
 				Assert.AreEqual(expectedSoC[i], socs[i], 1e-9, $"Bat_{i} SoC");
@@ -303,7 +303,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponent
 			}
 
 			var socs = bat.Batteries.SelectMany(x => x.Value.Batteries.Select(y => y.StateOfCharge)).ToArray();
-			Console.WriteLine(string.Join(", ", socs));
+			Console.WriteLine(socs.Join());
 			Console.WriteLine(bat.StateOfCharge);
 			for (var i = 0; i < socs.Length; i++) {
 				Assert.AreEqual(expectedSoC[i], socs[i], 1e-9, $"Bat_{i} SoC");
diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
index 16602da9dbe35b5e12238133fd183d234bb87e5b..2857d8a00c0d5542be77ea0d7d6a5a3fc90068e3 100644
--- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
+++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs
@@ -108,7 +108,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 			data.FullLoadCurves[0].EngineData = data;
 
 			var results = data.Validate(ExecutionMode.Declaration, VectoSimulationJobType.ConventionalVehicle, null, null, false);
-			Assert.IsFalse(results.Any(), "Validation Failed: " + string.Join("; ", results.Select(r => r.ErrorMessage)));
+			Assert.IsFalse(results.Any(), "Validation Failed: " + results.Select(r => r.ErrorMessage).Join("; "));
 			Assert.IsTrue(data.IsValid());
 		}
 
@@ -144,7 +144,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 			var engineData = dao.CreateEngineData(data, data.EngineModes.First());
 
 			var results = engineData.Validate(ExecutionMode.Engineering, VectoSimulationJobType.ConventionalVehicle, null, null, false);
-			Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage)));
+			Assert.IsFalse(results.Any(), "Validation failed: " + results.Select(r => r.ErrorMessage).Join("; "));
 			Assert.IsTrue(engineData.IsValid());
 		}
 
@@ -190,7 +190,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 			var engineData = dao.CreateEngineData(vehicle, data.EngineModes.First(), new Mission() {MissionType = MissionType.LongHaul});
 
 			var results = engineData.Validate(ExecutionMode.Declaration, VectoSimulationJobType.ConventionalVehicle, null, null, false);
-			Assert.IsFalse(results.Any(), "Validation failed: " + string.Join("; ", results.Select(r => r.ErrorMessage)));
+			Assert.IsFalse(results.Any(), "Validation failed: " + results.Select(r => r.ErrorMessage).Join("; "));
 
 			Assert.IsTrue(engineData.IsValid());
 		}
@@ -360,8 +360,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData
 
 			// every field and property should be tested except private parent fields and properties and 
 			// (4*4+1) * 2 = 17*2= 34 - 4 private parent fields (+2 public field and property which are tested twice) = 32
-			Assert.AreEqual(32, results.Count,
-				"Validation Error: " + string.Join("\n_eng_avg", results.Select(r => r.ErrorMessage)));
+			Assert.AreEqual(32, results.Count, "Validation Error: " + results.Select(r => r.ErrorMessage).Join("\n_eng_avg"));
 		}
 
 		[TestCase]
diff --git a/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs b/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs
index 0f36502f3b8efbee0ad36d1a5def5c7588bf7733..1502ea3b16f11c38cd862afb1315dc73abd8879a 100644
--- a/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs
+++ b/VectoCore/VectoCoreTest/Utils/ResultFileHelper.cs
@@ -107,10 +107,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 				}
 
 				CollectionAssert.AreEqual(expectedCols, actualCols,
-					string.Format("Moddata {3}: Columns differ:\nExpected: {0}\nMissing:{1},\nToo Much:{2}",
-						string.Join(", ", expectedCols),
-						string.Join(", ", expectedCols.Except(actualCols)),
-						string.Join(", ", actualCols.Except(expectedCols)), result.actualFile));
+					"Moddata {0}: Columns differ:\nExpected: {1}\nMissing:{2},\nToo Much:{3}",
+					result.actualFile,
+					expectedCols.Join(),
+					expectedCols.Except(actualCols).Join(),
+					actualCols.Except(expectedCols).Join());
 
 				for (var i = 0; testRowcount && i < expected.Rows.Count; i++) {
 					var expectedRow = expected.Rows[i];
@@ -138,11 +139,11 @@ namespace TUGraz.VectoCore.Tests.Utils
 			var expectedCols = expected.Columns.Cast<DataColumn>().Select(x => x.ColumnName).OrderBy(x => x).ToList();
 
 			CollectionAssert.AreEqual(expectedCols, actualCols,
-				string.Format("SUM FILE {3}: Columns differ:\nExpected: {0}\nMissing:{1},\nToo Much:{2}",
-					string.Join(", ", expectedCols),
-					string.Join(", ", expectedCols.Except(actualCols)),
-					string.Join(", ", actualCols.Except(expectedCols)),
-					actualFile));
+				"SUM FILE {0}: Columns differ:\nExpected: {1}\nMissing:{2},\nToo Much:{3}",
+				actualFile,
+				expectedCols.Join(),
+				expectedCols.Except(actualCols).Join(),
+				actualCols.Except(expectedCols).Join());
 
 			for (var i = 0; i < expected.Rows.Count; i++) {
 				var expectedRow = expected.Rows[i];
diff --git a/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs b/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs
index 2d7f9c6d95b31809e94156acf6b966d23889ec42..630a838fffdf4b504afecfbdc546bb7f2c53ab13 100644
--- a/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs
+++ b/VectoCore/VectoCoreTest/Utils/VectoMathTest.cs
@@ -119,7 +119,7 @@ namespace TUGraz.VectoCore.Tests.Utils
 		{
 			var results = VectoMath.Polynom4Solver(a, b, c, d, e);
 
-			Console.WriteLine(string.Join(", ", results));
+			Console.WriteLine(results.Join());
 
 			Assert.AreEqual(expected.Length, results.Length);
 
diff --git a/VectoCore/VectoCoreTest/XML/XMLReportTest.cs b/VectoCore/VectoCoreTest/XML/XMLReportTest.cs
index d88ce535c17b527c5cc484ba83803e2f8543feb9..7f595f7ff669ceee478fa43a87c1ccb87ba0812c 100644
--- a/VectoCore/VectoCoreTest/XML/XMLReportTest.cs
+++ b/VectoCore/VectoCoreTest/XML/XMLReportTest.cs
@@ -35,6 +35,7 @@ using System.Xml;
 using Ninject;
 using NUnit.Framework;
 using TUGraz.VectoCommon.Models;
+using TUGraz.VectoCommon.Utils;
 using TUGraz.VectoCore.InputData.FileIO.XML;
 using TUGraz.VectoCore.Models.Simulation.Impl;
 using TUGraz.VectoCore.OutputData;
@@ -96,13 +97,13 @@ namespace TUGraz.VectoCore.Tests.XML
 			var validator1 = new XMLValidator(XmlReader.Create(customerRecord), validationErrorAction: (s,e) => {
 				validationMsg1.Add(e?.ValidationEventArgs?.Message ?? "no schema found?");
 			});
-			Assert.IsTrue(validator1.ValidateXML(XmlDocumentType.CustomerReport), string.Join("\n", validationMsg1));
+			Assert.IsTrue(validator1.ValidateXML(XmlDocumentType.CustomerReport), validationMsg1.Join("\n"));
 
 			var validationMsg2 = new List<string> {manufacturerRecord};
 			var validator2 = new XMLValidator(XmlReader.Create(manufacturerRecord), validationErrorAction: (s,e) => {
 				validationMsg2.Add(e?.ValidationEventArgs?.Message ?? "no schema found");
 			});
-			Assert.IsTrue(validator2.ValidateXML(XmlDocumentType.ManufacturerReport), string.Join("\n", validationMsg2));
+			Assert.IsTrue(validator2.ValidateXML(XmlDocumentType.ManufacturerReport), validationMsg2.Join("\n"));
 		}
 	}
 }
\ No newline at end of file