// Copyright (C) Stichting Deltares 2021. All rights reserved.
//
// This file is part of the application DAM - UI.
//
// DAM - UI is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
//
// This file is part of the application DAM - UI.
//
// DAM - UI is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using Deltares.Dam.Data;
using Deltares.Dam.Data.DamEngineIo;
using Deltares.DamEngine.Io;
using Deltares.DamEngine.Io.XmlOutput;
using Deltares.Geometry;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard.Logging;
using KellermanSoftware.CompareNetObjects;
using NUnit.Framework;
using Location = Deltares.Dam.Data.Location;
using SurfaceLine = Deltares.DamEngine.Io.XmlOutput.SurfaceLine;
using SurfaceLinePoint = Deltares.DamEngine.Io.XmlOutput.SurfaceLinePoint;
using UpliftSituation = Deltares.DamEngine.Io.XmlOutput.UpliftSituation;
namespace Deltares.Dam.Tests.DamEngineIo
{
[TestFixture]
public class FillDamUiFromXmlOutputTests
{
[Test]
public void CanWriteAndReadOutputCalculationMessagesToXmlString()
{
var expectedDamProjectData = CreateDamProjectDataWithCalculationMessages();
var output = FillXmlOutputFromDamUi.CreateOutput(expectedDamProjectData);
var outputString = DamXmlSerialization.SaveOutputAsXmlString(output);
output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
var actualDamProjectData = new DamProjectData();
actualDamProjectData = FillDamUiFromXmlOutput.AddOutputToDamProjectData(actualDamProjectData, output);
CompareDamProjectData(actualDamProjectData, expectedDamProjectData);
}
private static DamProjectData CreateDamProjectDataWithCalculationMessages()
{
DamProjectData damProjectData = new DamProjectData();
damProjectData.CalculationMessages = new List();
damProjectData.CalculationMessages.Add(new LogMessage(LogMessageType.Error, null, "Error 1"));
damProjectData.CalculationMessages.Add(new LogMessage(LogMessageType.Error, null, "Error 2"));
damProjectData.CalculationMessages.Add(new LogMessage(LogMessageType.Warning, null, "Warning 1"));
FillOutputTimeSeries(damProjectData);
return damProjectData;
}
private static void FillOutputTimeSeries(DamProjectData damProjectData)
{
const int timeSeriesCount = 2;
const int timeEntriesCount = 3;
const string idPipingBligh = "PipingFactorBligh";
const string idStabilityInsideFactor = "StabilityInsideFactor";
damProjectData.OutputTimeSerieCollection = new TimeSerieCollection();
for (int i = 0; i < timeSeriesCount; i++)
{
string locationId = String.Format("location{0}", i);
var timeSerie = damProjectData.OutputTimeSerieCollection.AddNewSeries(locationId);
timeSerie.ParameterId = (i % 2 == 0) ? idPipingBligh : idStabilityInsideFactor;
timeSerie.ForecastDateTime = DateTime.Now;
timeSerie.Type = "instantaneous";
timeSerie.StartDateTime = new DateTime(2012, 12, 31);
timeSerie.EndDateTime = new DateTime(2012, 12, 31, 1, 0, 0);
timeSerie.MissVal = -9999.0;
timeSerie.LongName = timeSerie.LocationId + "long";
timeSerie.StationName = String.Format("station{0}", i);
timeSerie.Units = "m";
timeSerie.SourceOrganisation = String.Format("organisation{0}", i);
timeSerie.SourceSystem = String.Format("system{0}", i);
timeSerie.FileDescription = String.Format("filedescription{0}", i);
timeSerie.Region = String.Format("region{0}", i);
timeSerie.TimeStep.Multiplier = 3600;
timeSerie.TimeStep.Unit = TimeStepUnit.Second;
for (int j = 0; j < timeEntriesCount; j++)
{
timeSerie.Entries.Add(new TimeSerieEntry
{
DateTime = new DateTime(2012, 12, 31, 1, j * 10, 0),
Value = 1 + j * 0.1,
Flag = 1,
BasisFileName = String.Format("BasisFileName{0}", i)
});
}
}
}
[Test]
public void SimpleTestPiping()
{
var inputProjectData = CreateInputProjectDataForPiping();
var output = CreateTestOutputForPiping();
const string inputFilename = "OutputFilePiping.xml";
var combinedDamProjectData = FillDamUiFromXmlOutput.AddOutputToDamProjectData(inputProjectData, output);
Assert.AreEqual(4, combinedDamProjectData.DesignCalculations.Count);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[0].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[1].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[2].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[3].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[0].ProfileName);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[0].ProfileName);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[0].Calculation);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[0].Calculation);
Assert.AreEqual(PipingModelType.Bligh, combinedDamProjectData.DesignCalculations[0].PipingModel);
Assert.AreEqual(0, combinedDamProjectData.DesignCalculations[0].SafetyFactor);
Assert.AreEqual(34.21, combinedDamProjectData.DesignCalculations[0].PipingExitPointX);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[0].PipingExitPointY);
Assert.AreEqual(100.0, combinedDamProjectData.DesignCalculations[0].PipingEntryPointX);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[0].PipingEntryPointY);
Assert.AreEqual(100, combinedDamProjectData.DesignCalculations[0].DikeToeAtRiverXrd);
Assert.AreEqual(null, combinedDamProjectData.DesignCalculations[0].PipingToeAtPolderZ);
StringAssert.Contains(combinedDamProjectData.DesignCalculations[0].BaseFileName + ".prxml", combinedDamProjectData.DesignCalculations[0].PipingResultFile);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[1].ProfileName);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[1].ProfileName);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[1].Calculation);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[1].Calculation);
Assert.AreEqual(PipingModelType.Bligh, combinedDamProjectData.DesignCalculations[1].PipingModel);
Assert.AreEqual(1.03, combinedDamProjectData.DesignCalculations[1].SafetyFactor);
Assert.AreEqual(34.21, combinedDamProjectData.DesignCalculations[1].PipingExitPointX);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[1].PipingExitPointY);
Assert.AreEqual(100.0, combinedDamProjectData.DesignCalculations[1].PipingEntryPointX);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[1].PipingEntryPointY);
Assert.AreEqual(null, combinedDamProjectData.DesignCalculations[1].PipingToeAtPolderX);
Assert.AreEqual(null, combinedDamProjectData.DesignCalculations[1].PipingToeAtPolderZ);
Assert.AreEqual(0.2, combinedDamProjectData.DesignCalculations[1].Pl3HeadAdjusted);
Assert.AreEqual(0.7, combinedDamProjectData.DesignCalculations[1].Pl3MinUplift);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[1].Pl3LocationYMinUplift);
StringAssert.Contains(combinedDamProjectData.DesignCalculations[1].BaseFileName + ".prxml", combinedDamProjectData.DesignCalculations[1].PipingResultFile);
DamXmlSerialization.SaveOutputAsXmlFile(inputFilename, output);
output = DamXmlSerialization.LoadOutputFromXmlFile(inputFilename);
DamProjectData actualDamProjectData = FillDamUiFromXmlOutput.AddOutputToDamProjectData(inputProjectData, output);
CompareDamProjectData(actualDamProjectData, combinedDamProjectData);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].CalculationResult, actualDamProjectData.DesignCalculations[0].CalculationResult);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].SafetyFactor, actualDamProjectData.DesignCalculations[0].SafetyFactor);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].LocationName, actualDamProjectData.DesignCalculations[0].LocationName);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].StabilityModel, actualDamProjectData.DesignCalculations[0].StabilityModel);
Assert.IsNotNull(actualDamProjectData.DesignCalculations[0].RedesignedSurfaceLine2);
}
[Test]
[TestCase(MStabModelType.Bishop, "OutputFileStabilityBishop.xml")]
[TestCase(MStabModelType.UpliftVan, "OutputFileStabilityUpliftVan.xml")]
public void SimpleTestStabilityInside(MStabModelType mStabModelType, string inputFilename)
{
var inputProjectData = CreateInputProjectDataForStability(mStabModelType);
var output = CreateTestOutputForStability(mStabModelType);
var combinedDamProjectData = FillDamUiFromXmlOutput.AddOutputToDamProjectData(inputProjectData, output);
Assert.AreEqual(4, combinedDamProjectData.DesignCalculations.Count);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[0].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[1].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[2].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[3].Scenario);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[0].ProfileName);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[0].ProfileName);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[0].Calculation);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[0].Calculation);
Assert.AreEqual(mStabModelType, combinedDamProjectData.DesignCalculations[0].StabilityModel);
Assert.AreEqual(0, combinedDamProjectData.DesignCalculations[0].SafetyFactor);
Assert.AreEqual(null, combinedDamProjectData.DesignCalculations[0].StabilityShoulderHeight);
Assert.AreEqual(null, combinedDamProjectData.DesignCalculations[0].DikeLength);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[0].Pl3HeadAdjusted);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[0].Pl3MinUplift);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[0].Pl3LocationYMinUplift);
Assert.AreEqual(0, combinedDamProjectData.DesignCalculations[0].NumberOfIterations);
StringAssert.Contains(combinedDamProjectData.DesignCalculations[0].BaseFileName + ".rsxml", combinedDamProjectData.DesignCalculations[0].DesignResultFile);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[1].ProfileName);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[1].ProfileName);
Assert.AreNotEqual(null, combinedDamProjectData.DesignCalculations[1].Calculation);
Assert.AreNotEqual("", combinedDamProjectData.DesignCalculations[1].Calculation);
Assert.AreEqual(mStabModelType, combinedDamProjectData.DesignCalculations[1].StabilityModel);
Assert.AreEqual(1.2, combinedDamProjectData.DesignCalculations[1].SafetyFactor);
Assert.AreEqual(null, combinedDamProjectData.DesignCalculations[1].StabilityShoulderHeight);
Assert.AreEqual(0.2, combinedDamProjectData.DesignCalculations[1].Pl3HeadAdjusted);
Assert.AreEqual(0.7, combinedDamProjectData.DesignCalculations[1].Pl3MinUplift);
Assert.AreEqual(0.0, combinedDamProjectData.DesignCalculations[1].Pl3LocationYMinUplift);
Assert.AreEqual(1, combinedDamProjectData.DesignCalculations[1].NumberOfIterations);
StringAssert.Contains(combinedDamProjectData.DesignCalculations[1].BaseFileName + ".rsxml", combinedDamProjectData.DesignCalculations[1].DesignResultFile);
DamXmlSerialization.SaveOutputAsXmlFile(inputFilename, output);
output = DamXmlSerialization.LoadOutputFromXmlFile(inputFilename);
DamProjectData actualDamProjectData = FillDamUiFromXmlOutput.AddOutputToDamProjectData(inputProjectData, output);
CompareDamProjectData(actualDamProjectData, combinedDamProjectData);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].CalculationResult, actualDamProjectData.DesignCalculations[0].CalculationResult);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].SafetyFactor, actualDamProjectData.DesignCalculations[0].SafetyFactor);
Assert.AreEqual(combinedDamProjectData.DesignCalculations[0].LocationName, actualDamProjectData.DesignCalculations[0].LocationName);
Assert.IsNotNull(actualDamProjectData.DesignCalculations[0].RedesignedSurfaceLine2);
}
private DamProjectData CreateInputProjectDataForPiping()
{
var spec = new DamFailureMechanismeCalculationSpecification
{
FailureMechanismSystemType = FailureMechanismSystemType.Piping,
PipingModelType = PipingModelType.Bligh
};
return CreateInputProjectData(spec);
}
private DamProjectData CreateInputProjectDataForStability(MStabModelType mStabModelType)
{
var spec = new DamFailureMechanismeCalculationSpecification
{
FailureMechanismSystemType = FailureMechanismSystemType.StabilityInside,
CalculationModel = mStabModelType
};
return CreateInputProjectData(spec);
}
private static DamProjectData CreateInputProjectData(DamFailureMechanismeCalculationSpecification spec)
{
var project = new DamProjectData
{
DamProjectCalculationSpecification =
{
CurrentSpecification = spec
}
};
project.WaterBoard.Dikes.Add(new Dike());
var surfaceline = CreateSurfaceLine2();
Location location1 = new Location();
location1.Name = "Location 1";
location1.SurfaceLine2 = surfaceline;
var scenario1 = new Scenario();
scenario1.LocationScenarioID = "Scenario 1";
scenario1.Location = location1;
location1.Scenarios.Add(scenario1);
project.Locations.Add(location1);
var location2 = new Location("Location 2");
location2.SurfaceLine2 = surfaceline;
var scenario2 = new Scenario();
scenario2.LocationScenarioID = "Scenario 2";
scenario2.Location = location2;
location2.Scenarios.Add(scenario2);
project.Locations.Add(location2);
var location3 = new Location("Location 3");
location3.SurfaceLine2 = surfaceline;
var scenario3 = new Scenario();
scenario3.LocationScenarioID = "Scenario 3";
scenario3.Location = location3;
location3.Scenarios.Add(scenario3);
project.Locations.Add(location3);
var location4 = new Location("Location 4");
location4.SurfaceLine2 = surfaceline;
var scenario4 = new Scenario();
scenario4.LocationScenarioID = "Scenario 4";
scenario4.Location = location4;
location4.Scenarios.Add(scenario4);
project.Locations.Add(location4);
return project;
}
private Output CreateTestOutputForPiping()
{
var output = CreateTestOutput();
for (int i = 0; i < 4; i++)
{
var surfaceline = CreateSurfaceLine();
var upliftSituation = CreateUpliftSituation(i);
var pipingdesignResults = CreateDesignResultPiping(i, surfaceline, upliftSituation);
output.Results.CalculationResults[i].PipingDesignResults = pipingdesignResults;
}
return output;
}
private Output CreateTestOutputForStability(MStabModelType mStabModelType)
{
var output = CreateTestOutput();
for (int i = 0; i < 4; i++)
{
var surfaceLine = CreateSurfaceLine();
var upliftSituation = CreateUpliftSituation(i);
var stabilityResults = CreateDesignResultStability(i, surfaceLine, upliftSituation, mStabModelType);
output.Results.CalculationResults[i].StabilityDesignResults = stabilityResults;
}
return output;
}
private Output CreateTestOutput()
{
var output = new Output();
output.Results = new OutputResults();
output.Results.CalculationResults = new DesignResult[4];
for (int i = 0; i < 4; i++)
{
var desResult = new DesignResult
{
BaseFileName = "Basefilename" + (i + 1).ToString(),
CalculationSubDir = "Subdir" + (i + 1).ToString(),
LocationName = "Location " + (i + 1).ToString(),
ScenarioName = "Scenario " + (i + 1).ToString(),
ProfileName = "Profile " + (i + 1).ToString(),
CalculationResult = 1 * i
};
output.Results.CalculationResults[i] = desResult;
}
return output;
}
private static UpliftSituation CreateUpliftSituation(int i)
{
var upliftSituation = new UpliftSituation
{
IsUplift = true,
Pl3HeadAdjusted = 0.2 * i,
Pl3LocationXMinUplift = 2.2 * i,
Pl3MinUplift = 0.7 * i,
Pl4HeadAdjusted = 0.4 * i,
Pl4LocationXMinUplift = 4.4 * i,
Pl4MinUplift = 4.7 * i
};
return upliftSituation;
}
private static DesignResultPipingDesignResults CreateDesignResultPiping(int i, SurfaceLine surfaceline, UpliftSituation upliftSituation)
{
var pipingdesignResults = new DesignResultPipingDesignResults
{
ResultMessage = "no run made",
UpliftFactorSpecified = true,
UpliftFactor = 1.3 * i,
HeaveFactorSpecified = true,
HeaveFactor = 1.1 * i,
BlighFactorSpecified = true,
BlighFactor = 1.03 * i,
BlighHcriticalSpecified = true,
BlighHcritical = 0.4,
ExitPointXSpecified = true,
ExitPointX = 34.21,
RedesignedSurfaceLine = surfaceline,
UpliftSituation = upliftSituation
};
return pipingdesignResults;
}
private static DesignResultStabilityDesignResults CreateDesignResultStability(int i, SurfaceLine surfaceline, UpliftSituation upliftSituation, MStabModelType mStabModelType)
{
var stabilityResults = new DesignResultStabilityDesignResults
{
ResultMessage = "aok",
SafetyFactor = 1.2 * i,
SafetyFactorSpecified = true,
NumberOfIterationsSpecified = true,
NumberOfIterations = 1 * i,
RedesignedSurfaceLine = surfaceline,
UpliftSituation = upliftSituation,
StabilityModelTypeSpecified = true,
StabilityModelType = ConversionHelper.ConvertToOutputStabilityModelType(mStabModelType)
};
switch (mStabModelType)
{
case MStabModelType.Bishop:
var sl = new SlidingCircleMinimumSafetyCurveType();
sl.Center = new Point2DType()
{
X = 10.1 * (i + 1),
Z = 11.1 * (i + 1)
};
sl.Radius = 101.1 * (i + 1);
stabilityResults.SlipCircleDefinition = sl;
break;
case MStabModelType.UpliftVan:
var dsl = new DualSlidingCircleMinimumSafetyCurveType();
dsl.ActiveCircleCenter = new Point2DType()
{
X = 20.2 * (i + 1),
Z = 22.2 * (i + 1)
};
dsl.ActiveCircleRadius = 202.2 * (i + 1);
dsl.PassiveCircleCenter = new Point2DType()
{
X = 30.3 * (i + 1),
Z = 33.3 * (i + 1)
};
dsl.PassiveCircleRadius = 303.3 * (i + 1);
stabilityResults.SlipCircleDefinition = dsl;
break;
}
var slices = new List();
var slice1 = new MinimumSafetyCurveBaseTypeSlice
{
TopLeftPoint = new Point2DType { X = 11.1, Z = 12.1 },
TopRightPoint = new Point2DType { X = 21.1, Z = 22.1 },
BottomLeftPoint = new Point2DType { X = 31.1, Z = 32.1 },
BottomRightPoint = new Point2DType { X = 41.1, Z = 42.1 },
};
slices.Add(slice1);
var slice2 = new MinimumSafetyCurveBaseTypeSlice
{
TopLeftPoint = new Point2DType { X = 11.2, Z = 12.2 },
TopRightPoint = new Point2DType { X = 21.2, Z = 22.2 },
BottomLeftPoint = new Point2DType { X = 31.2, Z = 32.2 },
BottomRightPoint = new Point2DType { X = 41.2, Z = 42.2 },
};
slices.Add(slice2);
stabilityResults.SlipCircleDefinition.Slices = slices.ToArray();
return stabilityResults;
}
private static SurfaceLine CreateSurfaceLine()
{
var surfaceline = new SurfaceLine
{
Name = "Surfaceline 1",
Points = new SurfaceLinePoint[3]
};
var p1 = new SurfaceLinePoint
{
PointType = 0,
X = 0,
Z = 0
};
surfaceline.Points[0] = p1;
var p2 = new SurfaceLinePoint
{
PointType = 5,
X = 100,
Z = 10
};
surfaceline.Points[1] = p2;
var p3 = new SurfaceLinePoint
{
PointType = 25,
X = 120,
Z = 2
};
surfaceline.Points[2] = p3;
return surfaceline;
}
private static SurfaceLine2 CreateSurfaceLine2()
{
var surfaceline = new SurfaceLine2
{
Name = "Surfaceline 1"
};
surfaceline.CharacteristicPoints.Geometry = surfaceline.Geometry;
var p1 = new CharacteristicPoint
{
CharacteristicPointType = CharacteristicPointType.SurfaceLevelOutside,
GeometryPoint = new GeometryPoint(),
X = 0,
Z = 0
};
surfaceline.CharacteristicPoints.Add(p1);
var p2 = new CharacteristicPoint
{
CharacteristicPointType = CharacteristicPointType.DikeToeAtRiver,
GeometryPoint = new GeometryPoint(),
X = 100,
Z = 10
};
surfaceline.CharacteristicPoints.Add(p2);
var p3 = new CharacteristicPoint
{
CharacteristicPointType = CharacteristicPointType.SurfaceLevelInside,
GeometryPoint = new GeometryPoint(),
X = 120,
Z = 2
};
surfaceline.CharacteristicPoints.Add(p3);
return surfaceline;
}
private void CompareDamProjectData(DamProjectData actual, DamProjectData expected)
{
var compare = new CompareLogic
{
Config =
{
MaxDifferences = 100
}
};
compare.Config.MembersToIgnore = new List
{
"SheetPilePoint",
"SheetPilePointX",
"SheetPilePointY",
"SheetPilePointZ",
"LocalXZSheetPilePoint",
"SoilbaseDB",
"SurfaceLine",
"LocalXZSurfaceLine",
"SoilLayer1D",
"SoildatabaseName",
"MapForSoilGeometries2D"
};
var result = compare.Compare(expected, actual);
Assert.AreEqual(0, result.Differences.Count, "Differences found read/write Input object");
}
}
}