Example #1
0
		public void Init()
		{
			TestComponent sourceComponent = new TestComponent();
			ElementSet sourceElementSet = new ElementSet("SourceElementSet",
				"SourceElementSetID",ElementType.XYPoint,new SpatialReference("SourceRef"));
			
			TestComponent targetComponent = new TestComponent2();
			ElementSet targetElementSet = new ElementSet("TargetElementSet",
				"TargetElementSetID",ElementType.XYPoint,new SpatialReference("TargetRef"));

			ArrayList dataOperations = new ArrayList();
			dataOperations.Add(new DataOperation("dataOperation"));

			link1 = new Link(sourceComponent,sourceElementSet,new Quantity("SourceQuantity"),
				targetComponent,targetElementSet,new Quantity("TargetQuantity"),"Link description","Link1",
				dataOperations);
			link2 = new Link();
			link2.SourceComponent = sourceComponent;
			link2.SourceElementSet = sourceElementSet;
			link2.SourceQuantity = new Quantity("SourceQuantity");
			link2.TargetComponent = targetComponent;
			link2.TargetElementSet = targetElementSet;
			link2.TargetQuantity = new Quantity("TargetQuantity");
			link2.Description = "Link description";
			link2.ID = "Link2";
			link2.AddDataOperation(new DataOperation("dataOperation"));
		}
		public void Init()
		{
			eventSent = false;
			testComponent1 = new TestComponent();

			testComponent2 = new TestComponent2();

			Link link1 = new Link();
			link1.ID ="Link1";
			link1.SourceComponent = testComponent1;
			link1.TargetComponent = testComponent2;
			Link link2 = new Link();
			link2.ID ="Link2";
			link2.SourceComponent = testComponent2;
			link2.TargetComponent = testComponent1;
			Link link3 = new Link();
			link3.ID = "Link3";
			link3.SourceComponent = link3.TargetComponent = testComponent1;

			testComponent1.AddLink(link1);
			testComponent1.AddLink(link2);
			testComponent1.AddLink(link3);
			testComponent2.AddLink(link1);
			testComponent2.AddLink(link2);
			testComponent1.RemoveLink("Link3");

			testComponent1.Subscribe(this,EventType.Informative);

			Quantity q = new Quantity("Q");
			ElementSet elementSet = new ElementSet();
			elementSet.ID = "ES";

			InputExchangeItem inputExchangeItem = new InputExchangeItem();
			inputExchangeItem.Quantity = q;
			inputExchangeItem.ElementSet = elementSet;
			testComponent1.AddInputExchangeItem(inputExchangeItem);

			OutputExchangeItem outputExchangeItem = new OutputExchangeItem();
			outputExchangeItem.Quantity = new Quantity("Q2");
			ElementSet elementSet2 = new ElementSet();
			elementSet2.ID = "ES2";
			outputExchangeItem.ElementSet = elementSet;
			testComponent1.AddOutputExchangeItem(outputExchangeItem);
		}
		public void GetValues()
		{
			HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();
			TimeSeriesComponent ts = new TimeSeriesComponent();

			ts.Initialize(new Argument[0]);
			Link triggerLink = new Link();

			triggerLink.ID				 = "TriggerLink";
			triggerLink.SourceComponent  = ts;
			triggerLink.SourceElementSet = ts.GetOutputExchangeItem(0).ElementSet;
			triggerLink.SourceQuantity   = ts.GetOutputExchangeItem(0).Quantity;
			triggerLink.TargetComponent  = trigger;
			triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
			triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;

			trigger.AddLink(triggerLink);
			ts.AddLink(triggerLink);

			double tt = ts.TimeHorizon.Start.ModifiedJulianDay;
			TimeStamp[] triggerTimes = new TimeStamp[4];
			triggerTimes[0] = new TimeStamp(tt + 0.5);
			triggerTimes[1] = new TimeStamp(tt + 1.5);
			triggerTimes[2] = new TimeStamp(tt + 1.9);
			triggerTimes[3] = new TimeStamp(tt + 2.1);

			trigger.Run(triggerTimes);
			Assert.AreEqual(0,((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0));
			Assert.AreEqual(1,((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0));
			Assert.AreEqual(1,((IScalarSet)trigger.ResultsBuffer.GetValuesAt(2)).GetScalar(0));
			Assert.AreEqual(2,((IScalarSet)trigger.ResultsBuffer.GetValuesAt(3)).GetScalar(0));

			//Teting with timespans
			Assert.AreEqual(2.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt+2),new TimeStamp(tt + 2.0 + 1.0/24.0)),"TriggerLink")).GetScalar(0));
			Assert.AreEqual(2.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt + 2.0 + 1.0/24.0),new TimeStamp(tt + 2.0 + 2.0/24.0)),"TriggerLink")).GetScalar(0));
			Assert.AreEqual(2.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt + 2.0 + 2.0/24.0),new TimeStamp(tt + 2.0 + 3.0/24.0)),"TriggerLink")).GetScalar(0));
			Assert.AreEqual(2.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt + 2.0 + 5.0/24.0),new TimeStamp(tt + 2.0 + 6.0/24.0)),"TriggerLink")).GetScalar(0));
			Assert.AreEqual(2.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt + 2.0 + 15.0/24.0),new TimeStamp(tt + 2.0 + 16.0/24.0)),"TriggerLink")).GetScalar(0));
			Assert.AreEqual(2.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt + 2.0 + 23.0/24.0),new TimeStamp(tt + 2.0 + 24.0/24.0)),"TriggerLink")).GetScalar(0));
			Assert.AreEqual(3.0,((ScalarSet) ts.GetValues(new HydroNumerics.OpenMI.Sdk.Backbone.TimeSpan(new TimeStamp(tt + 3.0 ),new TimeStamp(tt + 3.0 + 1.0/24.0)),"TriggerLink")).GetScalar(0));
		
		}
		public void Validate()
		{
			ILinkableComponent upperRiver = new RiverModelLC();
			ILinkableComponent lowerRiver = new RiverModelLC();
			HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger     = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();

			// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
			Argument[] upperRiverArguments = new Argument[1];
			upperRiverArguments[0] = new Argument("ModelID","upperRiverModel",true,"argument");
			upperRiver.Initialize(upperRiverArguments);

			// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
			Argument[] lowerRiverArguments = new Argument[1];
			lowerRiverArguments[0] = new Argument("ModelID","lowerRiverModel",true,"argument");
			lowerRiver.Initialize(lowerRiverArguments);
			trigger.Initialize(new Argument[0]);

			Assert.AreEqual("upperRiverModel",upperRiver.ModelID);
			Assert.AreEqual("lowerRiverModel",lowerRiver.ModelID);

			Dimension wrongDimension = new Dimension();
			wrongDimension.SetPower(DimensionBase.Mass,1);
			Quantity wrongQuantity = new Quantity(new Unit("dummy",0.0,0.0,"dummy"),"test","qid",global::OpenMI.Standard.ValueType.Vector,wrongDimension);
			ElementSet wrongElementSet = new ElementSet("Wrong ElementSet","BadID",ElementType.XYPolyLine,new SpatialReference("no ref"));
			Element element = new Element("dum Element");
			element.AddVertex(new Vertex(4,5,0));
			wrongElementSet.AddElement(element);

			Link link = new Link();
			link.ID = "RiverToRiverLink";
			link.SourceComponent  = upperRiver;
			link.SourceElementSet = upperRiver.GetOutputExchangeItem(2).ElementSet; //last branch in the river
			link.SourceQuantity   = upperRiver.GetOutputExchangeItem(2).Quantity;
			link.TargetComponent  = lowerRiver;
			link.TargetElementSet = lowerRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
			link.TargetQuantity   = wrongQuantity;
//			link.AddDataOperation(upperRiver.GetOutputExchangeItem(6).GetDataOperation(0)); // bad data Operation

			Link triggerLink = new Link();

			triggerLink.ID				 = "TriggerLink";
			triggerLink.SourceComponent  = lowerRiver;
			triggerLink.SourceElementSet = wrongElementSet;
			triggerLink.SourceQuantity   = wrongQuantity;
			triggerLink.TargetComponent  = trigger;
			triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
			triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;
		
			upperRiver.AddLink(link);
			lowerRiver.AddLink(link);

			lowerRiver.AddLink(triggerLink);
			trigger.AddLink(triggerLink);

			bool isSilent = false;
			if (!isSilent)
			{
				Console.WriteLine(lowerRiver.Validate());

				foreach (string str in ((RiverModelLC) upperRiver).ValidationErrorMessages)
				{
					Console.WriteLine("Error upperRiver: " + str);
				}
				foreach (string str in ((RiverModelLC) lowerRiver).ValidationErrorMessages)
				{
					Console.WriteLine("Error lowerRiver: " + str);
				}
				foreach (string str in ((RiverModelLC) upperRiver).ValidationWarningMessages)
				{
					Console.WriteLine("Warning upperRiver: " + str);
				}
				foreach (string str in ((RiverModelLC) lowerRiver).ValidationWarningMessages)
				{
					Console.WriteLine("Warning lowerRiver: " + str);
				}
			}

			Assert.AreEqual(0,((RiverModelLC) upperRiver).ValidationErrorMessages.Count);
			Assert.AreEqual(4,((RiverModelLC) lowerRiver).ValidationErrorMessages.Count);

			Assert.AreEqual(0,((RiverModelLC) upperRiver).ValidationWarningMessages.Count);
			Assert.AreEqual(2,((RiverModelLC) lowerRiver).ValidationWarningMessages.Count);
			
			
		}
        public void GetValues_AsProvider()
        {
            LinkableTimeSeriesGroup linkableTimeSeriesGroup = new LinkableTimeSeriesGroup();
            linkableTimeSeriesGroup.Initialize(arguments);

            InputExchangeItem targetExchangeItem = new InputExchangeItem();
            Quantity targetQuantity = new Quantity();
            targetQuantity.ID = "Water Level";
            targetQuantity.Unit = new HydroNumerics.OpenMI.Sdk.Backbone.Unit("meter", 1, 0, "meter");
            ElementSet targetElementSet = new ElementSet("inputLocation", "Location", ElementType.IDBased, new SpatialReference(""));
            targetElementSet.AddElement(new Element("E1"));

            Link link = new Link();
            link.SourceComponent = linkableTimeSeriesGroup;
            link.SourceQuantity = linkableTimeSeriesGroup.GetOutputExchangeItem(1).Quantity;
            link.SourceElementSet = linkableTimeSeriesGroup.GetOutputExchangeItem(1).ElementSet;
            link.TargetComponent = null;
            link.TargetQuantity = targetQuantity;
            link.TargetElementSet = targetElementSet;
            link.ID = "Link001";

            linkableTimeSeriesGroup.AddLink(link);
            linkableTimeSeriesGroup.Prepare();

            IValueSet valueSet = linkableTimeSeriesGroup.GetValues(new TimeStamp(new System.DateTime(2010, 1, 5)), "Link001");
            Assert.AreEqual(0.063, ((IScalarSet)valueSet).GetScalar(0)); 

            linkableTimeSeriesGroup.Finish();
            linkableTimeSeriesGroup.Dispose();
        }
Example #6
0
		public void Constructor()
		{
			Link link3 = new Link(link1);
			Assert.AreEqual(link1,link3);
		}
		public void GetValues4A()
		{
			//This test is: RiverModel --> GWModel --> Trigger
			//Testing: Georeferenced links
			RiverModelLC riverModel = new RiverModelLC();
			GWModelLC    gWModel    = new GWModelLC();
			Trigger      trigger    = new Trigger();

			riverModel.Initialize(new Argument[0]);
			gWModel.Initialize(new Argument[0]);

			Link riverGWLink = new Link();
			riverGWLink.ID = "RiverGWLink";
			riverGWLink.SourceComponent = riverModel;
			riverGWLink.SourceElementSet = riverModel.GetOutputExchangeItem(6).ElementSet;
			riverGWLink.SourceQuantity   = riverModel.GetOutputExchangeItem(0).Quantity;
			riverGWLink.TargetComponent  = gWModel;
			riverGWLink.TargetElementSet = gWModel.GetInputExchangeItem(0).ElementSet;
			riverGWLink.TargetQuantity   = gWModel.GetInputExchangeItem(0).Quantity;

			int dataOperationIndex = -9;
			for (int i = 0; i < riverModel.GetOutputExchangeItem(6).DataOperationCount; i++)
			{
				if (riverModel.GetOutputExchangeItem(6).GetDataOperation(i).ID == "ElementMapper501")
				{
					dataOperationIndex = i;
				}
			}

			if (dataOperationIndex < 0)
			{
				throw new Exception("failed to find dataOperation");
			}
			
			riverGWLink.AddDataOperation(riverModel.GetOutputExchangeItem(6).GetDataOperation(dataOperationIndex));

			Link triggerLink = new Link();
			triggerLink.ID = "RiverGWLink";
			triggerLink.SourceComponent = gWModel;
			triggerLink.SourceElementSet = gWModel.GetOutputExchangeItem(0).ElementSet;
			triggerLink.SourceQuantity   = gWModel.GetOutputExchangeItem(0).Quantity;
			triggerLink.TargetComponent  = trigger;
			triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
			triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;

			riverModel.AddLink(riverGWLink);
			gWModel.AddLink(riverGWLink);
			gWModel.AddLink(triggerLink);
			trigger.AddLink(triggerLink);

			riverModel.Prepare();
			gWModel.Prepare();

			double firstTriggerGetValuesTime = riverModel.TimeHorizon.Start.ModifiedJulianDay;
			TimeStamp[] triggerTimes = new TimeStamp[2];
			triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 12.1);
			triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 16.7);
	
			trigger.Run(triggerTimes);

			double x0 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
			Assert.AreEqual(0.0,x0);

			double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(1);
			Assert.AreEqual(105.0/16.0,x1);

			double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(2);
			Assert.AreEqual(7.5,x2);

			double x3 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(3);
			Assert.AreEqual(5.0+35.0/16.0,x3);

			riverModel.Finish();
			gWModel.Finish();

			riverModel.Dispose();
			gWModel.Dispose();

		}
		public void GetValues2B()
		{
			// This is a variation of GetValues2A. In this test the timeSeries is linked ID based to the 
			// top node of the upperRiver. The last upperRiver branch of the upperRiver is ID based connected
			// to the top node of the lowerRiver. The last branch in the lowerRiver is linked to the trigger.
			// The timeSeries provides data that changes over time. This is what makes this test different from
			// GetValues2A, where everytning is the same for every time step.
			
			try
			{
				ILinkableComponent timeSeries = new TimeSeriesComponent();
				ILinkableComponent upperRiver = new RiverModelLC();
				ILinkableComponent lowerRiver = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger     = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();

				timeSeries.Initialize(new Argument[0]);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] upperRiverArguments = new Argument[1];
				upperRiverArguments[0] = new Argument("ModelID","upperRiverModel",true,"argument");
				upperRiver.Initialize(upperRiverArguments);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] lowerRiverArguments = new Argument[1];
				lowerRiverArguments[0] = new Argument("ModelID","lowerRiverModel",true,"argument");
				lowerRiver.Initialize(lowerRiverArguments);
				trigger.Initialize(new Argument[0]);

				Assert.AreEqual("upperRiverModel",upperRiver.ModelID);
				Assert.AreEqual("lowerRiverModel",lowerRiver.ModelID);

				Link timeSeriesToUpperRiverLink = new Link();
				timeSeriesToUpperRiverLink.ID = "timeSeriesToUpperRiverLink";
				timeSeriesToUpperRiverLink.SourceComponent  = timeSeries;
				timeSeriesToUpperRiverLink.SourceElementSet = timeSeries.GetOutputExchangeItem(0).ElementSet; //last branch in the river
				timeSeriesToUpperRiverLink.SourceQuantity   = timeSeries.GetOutputExchangeItem(0).Quantity;
				timeSeriesToUpperRiverLink.TargetComponent  = upperRiver;
				timeSeriesToUpperRiverLink.TargetElementSet = upperRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				timeSeriesToUpperRiverLink.TargetQuantity   = upperRiver.GetInputExchangeItem(0).Quantity;
				
				Link link = new Link();
				link.ID = "RiverToRiverLink";
				link.SourceComponent  = upperRiver;
				link.SourceElementSet = upperRiver.GetOutputExchangeItem(2).ElementSet; //last branch in the river
				link.SourceQuantity   = upperRiver.GetOutputExchangeItem(2).Quantity;
				link.TargetComponent  = lowerRiver;
				link.TargetElementSet = lowerRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				link.TargetQuantity   = lowerRiver.GetInputExchangeItem(0).Quantity;

				Link triggerLink = new Link();

				triggerLink.ID				 = "TriggerLink";
				triggerLink.SourceComponent  = lowerRiver;
				triggerLink.SourceElementSet = lowerRiver.GetOutputExchangeItem(2).ElementSet;
				triggerLink.SourceQuantity   = lowerRiver.GetOutputExchangeItem(2).Quantity;
				triggerLink.TargetComponent  = trigger;
				triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
				triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;
		
				timeSeries.AddLink(timeSeriesToUpperRiverLink);
				upperRiver.AddLink(timeSeriesToUpperRiverLink);

				upperRiver.AddLink(link);
				lowerRiver.AddLink(link);

				lowerRiver.AddLink(triggerLink);
				trigger.AddLink(triggerLink);

				timeSeries.Prepare();
				upperRiver.Prepare();
				lowerRiver.Prepare();
				trigger.Prepare();

				double firstTriggerGetValuesTime = lowerRiver.TimeHorizon.Start.ModifiedJulianDay;
				TimeStamp[] triggerTimes = new TimeStamp[2];
				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 12.5);
				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 16.2);

				trigger.Run(triggerTimes);

				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(315.0/32.0 + 13.0/64.0,x1);

				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
				Assert.AreEqual(315.0/32.0 + 17.0/64.0,x2);

				upperRiver.Finish();
				lowerRiver.Finish();

				upperRiver.Dispose();
				lowerRiver.Dispose();

			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void GetValues1B()
		{
			// Running with one instances of riverModelLC linked ID-based to trigger and to 
			// an instance of the TimeSeriesComponent.
			try
			{
				ILinkableComponent timeSeries = new TimeSeriesComponent();
				ILinkableComponent riverModelLC = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();
	
				timeSeries.Initialize(new Argument[0]);

				Argument[] riverArguments = new Argument[2];
				riverArguments[0] = new Argument("ModelID","upperRiverModel",true,"argument");
				riverArguments[1] = new Argument("TimeStepLength","3600",true,"A time step length of 1 day");

				riverModelLC.Initialize(riverArguments);
				trigger.Initialize(new Argument[0]);

				Link timeSeriesToRiverLink = new Link();
				timeSeriesToRiverLink.ID = "timeSeriesToUpperRiverLink";
				timeSeriesToRiverLink.SourceComponent  = timeSeries;
				timeSeriesToRiverLink.SourceElementSet = timeSeries.GetOutputExchangeItem(0).ElementSet; //last branch in the river
				timeSeriesToRiverLink.SourceQuantity   = timeSeries.GetOutputExchangeItem(0).Quantity;
				timeSeriesToRiverLink.TargetComponent  = riverModelLC;
				timeSeriesToRiverLink.TargetElementSet = riverModelLC.GetInputExchangeItem(0).ElementSet;  //first node in the river
				timeSeriesToRiverLink.TargetQuantity   = riverModelLC.GetInputExchangeItem(0).Quantity;
				

				Link link = new Link(riverModelLC, riverModelLC.GetOutputExchangeItem(2).ElementSet,riverModelLC.GetOutputExchangeItem(2).Quantity,trigger,trigger.GetInputExchangeItem(0).ElementSet,trigger.GetInputExchangeItem(0).Quantity,"LinkID");
				
                timeSeries.AddLink(timeSeriesToRiverLink);
				riverModelLC.AddLink(timeSeriesToRiverLink);

				riverModelLC.AddLink(link);
				trigger.AddLink(link);

				riverModelLC.Prepare();
				
				double firstTriggerGetValuesTime = riverModelLC.TimeHorizon.Start.ModifiedJulianDay;
				TimeStamp[] triggerTimes = new TimeStamp[2];
				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 12.1);
				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 16.7);
	
				trigger.Run(triggerTimes);
				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(35.0/4.0 + 13.0/8.0,x1);

				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
				Assert.AreEqual(35.0/4.0 + 17.0/8.0,x2);

				riverModelLC.Finish();
				riverModelLC.Dispose();
				
			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void SmartBufferDataOperationTest()
		{
			// Running with one instances of riverModelLC linked ID-based to trigger
			// using the SmartBufferDataOperation.

			try
			{
				ILinkableComponent riverModelLC = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();
	
				Argument[] riverArguments = new Argument[2];
				riverArguments[0] = new Argument("ModelID","RiverModel",true,"argument");
				riverArguments[1] = new Argument("TimeStepLength","3600",true,"A time step length of 1 hour");

				riverModelLC.Initialize(riverArguments);
				trigger.Initialize(new Argument[0]);

				Link link = new Link(riverModelLC, riverModelLC.GetOutputExchangeItem(2).ElementSet,riverModelLC.GetOutputExchangeItem(2).Quantity,trigger,trigger.GetInputExchangeItem(0).ElementSet,trigger.GetInputExchangeItem(0).Quantity,"LinkID");

				//add linear conversion data operation
				bool dataOperationWasFound = false;
				int dataOperationIndex = -9;
				for (int i = 0; i < riverModelLC.GetOutputExchangeItem(2).DataOperationCount; i++)
				{
					if (riverModelLC.GetOutputExchangeItem(2).GetDataOperation(i).ID == new SmartBufferDataOperation().ID)
					{
						dataOperationWasFound = true;
						dataOperationIndex = i;
					}
				}
				Assert.AreEqual(true,dataOperationWasFound);
				IDataOperation smartBufferDataOperation = riverModelLC.GetOutputExchangeItem(2).GetDataOperation(dataOperationIndex);
				bool key_A_WasFound = false;
				bool key_B_WasFound = false;
				bool key_Type_WasFound = false;

				for (int i = 0; i < smartBufferDataOperation.ArgumentCount; i++)
				{
					if ( smartBufferDataOperation.GetArgument(i).Key == "Relaxation Factor")
					{
						smartBufferDataOperation.GetArgument(i).Value = "0.7";
						key_A_WasFound = true;
						Assert.AreEqual(false,smartBufferDataOperation.GetArgument(i).ReadOnly);
					}
					if ( smartBufferDataOperation.GetArgument(i).Key == "Do Extended Data Validation")
					{
						smartBufferDataOperation.GetArgument(i).Value = "False";
						key_B_WasFound = true;
						Assert.AreEqual(false,smartBufferDataOperation.GetArgument(i).ReadOnly);
					}

					if ( smartBufferDataOperation.GetArgument(i).Key == "Type")
					{
						key_Type_WasFound = true;
						Assert.AreEqual(true,smartBufferDataOperation.GetArgument(i).ReadOnly);
					}
				}

				Assert.AreEqual(true,key_A_WasFound);
				Assert.AreEqual(true,key_B_WasFound);
				Assert.AreEqual(true,key_Type_WasFound);
				Assert.AreEqual("Buffering and temporal extrapolation",smartBufferDataOperation.ID);

				link.AddDataOperation(smartBufferDataOperation);

				riverModelLC.AddLink(link);
				trigger.AddLink(link);

				riverModelLC.Prepare();

				Assert.AreEqual(0.7,((SmartOutputLink)((RiverModelLC) riverModelLC).SmartOutputLinks[0]).SmartBuffer.RelaxationFactor);
				Assert.AreEqual(false,((SmartOutputLink)((RiverModelLC) riverModelLC).SmartOutputLinks[0]).SmartBuffer.DoExtendedDataVerification);

				riverModelLC.Finish();
				riverModelLC.Dispose();
				
			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void LinearConvertionDataOperation()
		{
			// Running with one instances of riverModelLC linked ID-based to trigger
			// using the linearConversionDataOperation.

			try
			{
				ILinkableComponent riverModelLC = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();
	
				Argument[] riverArguments = new Argument[2];
				riverArguments[0] = new Argument("ModelID","RiverModel",true,"argument");
				riverArguments[1] = new Argument("TimeStepLength","3600",true,"A time step length of 1 hour");

				riverModelLC.Initialize(riverArguments);
				trigger.Initialize(new Argument[0]);

				Link link = new Link(riverModelLC, riverModelLC.GetOutputExchangeItem(2).ElementSet,riverModelLC.GetOutputExchangeItem(2).Quantity,trigger,trigger.GetInputExchangeItem(0).ElementSet,trigger.GetInputExchangeItem(0).Quantity,"LinkID");

				//add linear conversion data operation
				bool dataOperationWasFound = false;
				int dataOperationIndex = -9;
				for (int i = 0; i < riverModelLC.GetOutputExchangeItem(2).DataOperationCount; i++)
				{
					if (riverModelLC.GetOutputExchangeItem(2).GetDataOperation(i).ID == "Linear Conversion")
					{
						dataOperationWasFound = true;
						dataOperationIndex = i;
					}
				}
				Assert.AreEqual(true,dataOperationWasFound);
				IDataOperation linearConvertionDataOperation = riverModelLC.GetOutputExchangeItem(2).GetDataOperation(dataOperationIndex);
				bool key_A_WasFound = false;
				bool key_B_WasFound = false;
				bool key_Type_WasFound = false;

				for (int i = 0; i < linearConvertionDataOperation.ArgumentCount; i++)
				{
					if ( linearConvertionDataOperation.GetArgument(i).Key == "A")
					{
						linearConvertionDataOperation.GetArgument(i).Value = "2.5";
						key_A_WasFound = true;
						Assert.AreEqual(false,linearConvertionDataOperation.GetArgument(i).ReadOnly);
					}
					if ( linearConvertionDataOperation.GetArgument(i).Key == "B")
					{
						linearConvertionDataOperation.GetArgument(i).Value = "3.5";
						key_B_WasFound = true;
						Assert.AreEqual(false,linearConvertionDataOperation.GetArgument(i).ReadOnly);
					}

					if ( linearConvertionDataOperation.GetArgument(i).Key == "Type")
					{
						key_Type_WasFound = true;
						Assert.AreEqual(true,linearConvertionDataOperation.GetArgument(i).ReadOnly);
					}
				}

				Assert.AreEqual(true,key_A_WasFound);
				Assert.AreEqual(true,key_B_WasFound);
				Assert.AreEqual(true,key_Type_WasFound);
				Assert.AreEqual("Linear Conversion",linearConvertionDataOperation.ID);

				link.AddDataOperation(linearConvertionDataOperation);

				riverModelLC.AddLink(link);
				trigger.AddLink(link);

				riverModelLC.Prepare();
				
				double firstTriggerGetValuesTime = riverModelLC.TimeHorizon.Start.ModifiedJulianDay;
				TimeStamp[] triggerTimes = new TimeStamp[2];
				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 2);
				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 4.3);
	
				trigger.Run(triggerTimes);
				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(2.5*(35.0/4.0) + 3.5, x1);

				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
				Assert.AreEqual(2.5 * (35.0/4.0) + 3.5, x2);

				riverModelLC.Finish();
				riverModelLC.Dispose();
				
			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void Links()
		{
			Link link1 = new Link();
			link1.ID ="Link1";
			Link link2 = new Link();
			link2.ID ="Link2";
			Assert.AreEqual(2,testComponent1.LinkCount);
			Assert.AreEqual(2,testComponent2.LinkCount);
			Assert.AreEqual(link2,testComponent1.GetAcceptingLinks()[0]);
			Assert.AreEqual(link1,testComponent1.GetProvidingLinks()[0]);
		}
		public void TestNoneCloneableDataOperation()
		{
			lastEvent = null;

			testComponent1.Subscribe(this, EventType.Warning);

			IDataOperation nonCloneableDataOperation = new NoneCloneableDataOperation("nonCloneableDataOperation");

			Link link_a = new Link();
			link_a.ID ="Link a with NoneCloneableDataOperations";
			link_a.SourceComponent = testComponent1;
			link_a.TargetComponent = testComponent2;
			link_a.AddDataOperation(nonCloneableDataOperation);
			testComponent1.AddLink(link_a);
			testComponent2.AddLink(link_a);

			Link link_b = new Link();
			link_b.ID = "Link b with NoneCloneableDataOperations";
			link_b.SourceComponent = testComponent1;
			link_b.TargetComponent = testComponent2;
			link_b.AddDataOperation(nonCloneableDataOperation);

			lastEvent = null;
			testComponent2.AddLink(link_b);
			Assert.IsTrue(lastEvent == null, "lastEvent==null");
			testComponent1.AddLink(link_b);
			Assert.IsTrue(lastEvent != null, "lastEvent!=null");
			Assert.IsTrue(lastEvent.Type == EventType.Warning, "EventType.Warning");
			Assert.IsTrue(lastEvent.Description.ToLower().Contains("clone"), "clone");
		}
        /// <summary>
        /// Loads composition from XML document.
        /// </summary>
        /// <param name="omiRelativeDirectory">Directory the OMI files are relative to.</param>
        /// <param name="xmlDocument">XML document</param>
        private void LoadFromXmlDocument(string omiRelativeDirectory, XmlDocument xmlDocument)
        {
            // once you choose to load new file, all previously opened models are closed
            Release();

            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = new CultureInfo("");
            

            XmlElement xmlRoot = (XmlElement)xmlDocument.ChildNodes[0];
            XmlElement xmlModels = (XmlElement)xmlRoot.ChildNodes[0];
            XmlElement xmlLinks = (XmlElement)xmlRoot.ChildNodes[1];

            // run properties aren't mandatory
            XmlElement xmlRunProperties = null;
            if (xmlRoot.ChildNodes.Count > 2)
                xmlRunProperties = (XmlElement)xmlRoot.ChildNodes[2];

            // check
            if (xmlRoot.GetAttribute("version") != "1.0")
                throw (new FormatException("Version of file not supported. Currently supported only version '1.0'"));
            if (xmlModels.Name != "models"
                || xmlLinks.Name != "links")
                throw (new FormatException("Unknown file format ('models' or 'links' tag not present where expected)."));
            if (xmlRunProperties != null)
                if (xmlRunProperties.Name != "runproperties")
                    throw (new FormatException("Unknown file format ('runproperties' tag not present where expected)."));

            // read UIModels
            foreach (XmlElement xmlUiModel in xmlModels.ChildNodes)
            {
                try
                {
                    UIModel uiModel = AddModel(omiRelativeDirectory, xmlUiModel.GetAttribute("omi"));

                    uiModel.Rect.X = Int32.Parse(xmlUiModel.GetAttribute("rect_x"));
                    uiModel.Rect.Y = Int32.Parse(xmlUiModel.GetAttribute("rect_y"));
                    uiModel.Rect.Width = Int32.Parse(xmlUiModel.GetAttribute("rect_width"));
                    uiModel.Rect.Height = Int32.Parse(xmlUiModel.GetAttribute("rect_height"));
                }
                catch (Exception e)
                {
                    throw (new Exception(
                        "Model cannot be added to composition due to exception.\n" +
                        "OMI filename: " + xmlUiModel.GetAttribute("omi") + "\n" +
                        "Exception: " + e.ToString()));
                }
            }

            // read UILinks
            foreach (XmlElement xmlUiLink in xmlLinks.ChildNodes)
            {
                // find models corresponding to this UIConnection
                UIModel providingModel = null, acceptingModel = null;
                foreach (UIModel uiModel in _models)
                    if (uiModel.ModelID == xmlUiLink.GetAttribute("model_providing"))
                    {
                        providingModel = uiModel;
                        break;
                    }
                foreach (UIModel uiModel in _models)
                    if (uiModel.ModelID == xmlUiLink.GetAttribute("model_accepting"))
                    {
                        acceptingModel = uiModel;
                        break;
                    }

                if (providingModel == null || acceptingModel == null)
                {
                    throw (new Exception(
                        "One model (or both) corresponding to this link cannot be found...\n" +
                        "Providing model: " + xmlUiLink.GetAttribute("model_providing") + "\n" +
                        "Accepting model: " + xmlUiLink.GetAttribute("model_accepting")));
                }

                // construct UIConnection
                UIConnection uiLink = new UIConnection(providingModel, acceptingModel);

                // read OpenMI Links
                foreach (XmlElement xmlLink in xmlUiLink.ChildNodes)
                {
                    // find corresponding exchange items
                    IOutputExchangeItem outputExchangeItem = null;
                    IInputExchangeItem inputExchangeItem = null;

                    int count = providingModel.LinkableComponent.OutputExchangeItemCount;
                    string sourceElementSetID = xmlLink.GetAttribute("source_elementset");
                    string sourceQuantityID = xmlLink.GetAttribute("source_quantity");
                    for (int i = 0; i < count; i++)
                        if (sourceElementSetID == providingModel.LinkableComponent.GetOutputExchangeItem(i).ElementSet.ID
                            && sourceQuantityID == providingModel.LinkableComponent.GetOutputExchangeItem(i).Quantity.ID)
                        {
                            outputExchangeItem = providingModel.LinkableComponent.GetOutputExchangeItem(i);
                            break;
                        }

                    for (int i = 0; i < acceptingModel.LinkableComponent.InputExchangeItemCount; i++)
                        if (xmlLink.GetAttribute("target_elementset") == acceptingModel.LinkableComponent.GetInputExchangeItem(i).ElementSet.ID
                            && xmlLink.GetAttribute("target_quantity") == acceptingModel.LinkableComponent.GetInputExchangeItem(i).Quantity.ID)
                        {
                            inputExchangeItem = acceptingModel.LinkableComponent.GetInputExchangeItem(i);
                            break;
                        }

                    if (outputExchangeItem == null || inputExchangeItem == null)
                        throw (new Exception(
                            "Cannot find exchange item\n" +
                            "Providing model: " + providingModel.ModelID + "\n" +
                            "Accepting model: " + acceptingModel.ModelID + "\n" +
                            "Source ElementSet: " + xmlLink.GetAttribute("source_elementset") + "\n" +
                            "Source Quantity: " + xmlLink.GetAttribute("source_quantity") + "\n" +
                            "Target ElementSet: " + xmlLink.GetAttribute("target_elementset") + "\n" +
                            "Target Quantity: " + xmlLink.GetAttribute("target_quantity")));


                    // read selected DataOperation's IDs, find their equivalents
                    // in outputExchangeItem, and add these to link
                    ArrayList dataOperationsToAdd = new ArrayList();

                    foreach (XmlElement xmlDataOperation in xmlLink.ChildNodes)
                        for (int i = 0; i < outputExchangeItem.DataOperationCount; i++)
                        {
                            IDataOperation dataOperation = outputExchangeItem.GetDataOperation(i);
                            if (dataOperation.ID == xmlDataOperation.GetAttribute("id"))
                            {
                                // set data operation's arguments if any
                                foreach (XmlElement xmlArgument in xmlDataOperation.ChildNodes)
                                {
                                    string argumentKey = xmlArgument.GetAttribute("key");
                                    for (int j = 0; j < dataOperation.ArgumentCount; j++)
                                    {
                                        IArgument argument = dataOperation.GetArgument(j);
                                        if (argument.Key == argumentKey && !argument.ReadOnly)
                                            argument.Value = xmlArgument.GetAttribute("value");
                                    }
                                }

                                dataOperationsToAdd.Add(dataOperation);
                                break;
                            }
                        }

                    // now construct the Link...
                    Link link = new Link(
                        providingModel.LinkableComponent,
                        outputExchangeItem.ElementSet,
                        outputExchangeItem.Quantity,
                        acceptingModel.LinkableComponent,
                        inputExchangeItem.ElementSet,
                        inputExchangeItem.Quantity,
                        "No description available.",
                        xmlLink.GetAttribute("id"),
                        dataOperationsToAdd);


                    // ...add the link to the list
                    uiLink.Links.Add(link);

                    // and add it to both LinkableComponents
                    uiLink.AcceptingModel.LinkableComponent.AddLink(link);
                    uiLink.ProvidingModel.LinkableComponent.AddLink(link);
                }

                // add new UIConnection to list of connections
                _connections.Add(uiLink);
            }

            // read run properties (if present)
            if (xmlRunProperties != null)
            {
                string str = xmlRunProperties.GetAttribute("listenedeventtypes");
                if (str.Length != (int)EventType.NUM_OF_EVENT_TYPES)
                    throw (new FormatException("Invalid number of event types in 'runproperties' tag, expected " + EventType.NUM_OF_EVENT_TYPES + ", but only " + str.Length + " found."));
                for (int i = 0; i < (int)EventType.NUM_OF_EVENT_TYPES; i++)
                    switch (str[i])
                    {
                        case '1': _listenedEventTypes[i] = true; break;
                        case '0': _listenedEventTypes[i] = false; break;
                        default: throw (new FormatException("Unknown format of 'listenedeventtypes' attribute in 'runproperties' tag."));
                    }
                _triggerInvokeTime = DateTime.Parse(xmlRunProperties.GetAttribute("triggerinvoke"));

                _logFileName = xmlRunProperties.GetAttribute("logfilename");
                if (_logFileName != null)
                {
                    _logFileName = _logFileName.Trim();
                    if (_logFileName == "")
                        _logFileName = null; // if not set, logfile isn't used
                }


                str = xmlRunProperties.GetAttribute("showeventsinlistbox");
                if (str == null || str == "" || str == "1")
                    _showEventsInListbox = true; // if not set, value is true
                else
                    _showEventsInListbox = false;

                str = xmlRunProperties.GetAttribute("runinsamethread");
                if (str == "1")
                    _runInSameThread = true;
            }


            Thread.CurrentThread.CurrentCulture = currentCulture;
        }
        public void GetValues_AsAcceptor()
        {
            filename = "HydroNumerics.Time.OpenMI.UnitTest.LinkableTimeSeriesGroupTest.GetValues_AsAcceptor.xts";
            string acceptorOutputFilename = "HydroNumerics.Time.OpenMI.UnitTest.LinkableTimeSeriesGroupTest.GetValues_AsAcceptor.out.xts";

            TimespanSeries timespanSeries = new TimespanSeries("Flow", new System.DateTime(2010, 1, 1), 10, 2, TimestepUnit.Days, 10.2);
            timespanSeries.Unit = new HydroNumerics.Core.Unit("Liters pr. sec", 0.001, 0.0, "Liters pr second");
            timespanSeries.Unit.Dimension.Length = 3;
            timespanSeries.Unit.Dimension.Time = -1;
            timespanSeries.Description = "Measured Flow";
            TimestampSeries timestampSeries = new TimestampSeries("Water Level", new System.DateTime(2010, 1, 1), 6, 2, TimestepUnit.Days, 12.2);
            timestampSeries.Unit = new HydroNumerics.Core.Unit("cm", 0.01, 0.0, "centimeters");
            timestampSeries.Unit.Dimension.Length = 1;
            timestampSeries.Description = "Measured Head";

            TimeSeriesGroup tsg = new TimeSeriesGroup();
            tsg.Name = "Acceptor";
            tsg.Items.Add(timespanSeries);
            tsg.Items.Add(timestampSeries);
            tsg.Save(filename);

            Argument filenameArgument = new Argument("Filename", filename, true, "someDescription");
            Argument outputFilenameArgument = new Argument("OutputFilename", acceptorOutputFilename, true, "someDescription");
            Argument[] acceptorArguments = new Argument[2] { filenameArgument, outputFilenameArgument };

            LinkableTimeSeriesGroup acceptorTs = new LinkableTimeSeriesGroup();
            acceptorTs.Initialize(acceptorArguments);
            acceptorTs.WriteOmiFile(filename);

            LinkableTimeSeriesGroup linkableTimeSeriesGroup = new LinkableTimeSeriesGroup();
            linkableTimeSeriesGroup.Initialize(arguments);


            Link ts2tsLink1 = new Link();
            ts2tsLink1.SourceComponent = linkableTimeSeriesGroup;
            ts2tsLink1.TargetComponent = acceptorTs;
            ts2tsLink1.SourceQuantity = linkableTimeSeriesGroup.GetOutputExchangeItem(0).Quantity;
            ts2tsLink1.SourceElementSet = linkableTimeSeriesGroup.GetOutputExchangeItem(0).ElementSet;
            ts2tsLink1.TargetQuantity = acceptorTs.GetInputExchangeItem(0).Quantity;
            ts2tsLink1.TargetElementSet = acceptorTs.GetInputExchangeItem(0).ElementSet;
            ts2tsLink1.ID = "ts2ts1";
            linkableTimeSeriesGroup.AddLink(ts2tsLink1);
            acceptorTs.AddLink(ts2tsLink1);

            Link ts2tsLink2 = new Link();
            ts2tsLink2.SourceComponent = linkableTimeSeriesGroup;
            ts2tsLink2.TargetComponent = acceptorTs;
            ts2tsLink2.SourceQuantity = linkableTimeSeriesGroup.GetOutputExchangeItem(1).Quantity;
            ts2tsLink2.SourceElementSet = linkableTimeSeriesGroup.GetOutputExchangeItem(1).ElementSet;
            ts2tsLink2.TargetQuantity = acceptorTs.GetInputExchangeItem(1).Quantity;
            ts2tsLink2.TargetElementSet = acceptorTs.GetInputExchangeItem(1).ElementSet;
            ts2tsLink2.ID = "ts2ts2";
            linkableTimeSeriesGroup.AddLink(ts2tsLink2);
            acceptorTs.AddLink(ts2tsLink2);


            //setting up the work arround type of trigger
            InputExchangeItem targetExchangeItem = new InputExchangeItem();
            Quantity targetQuantity = new Quantity();
            targetQuantity.ID = "Water Level";
            targetQuantity.Unit = new HydroNumerics.OpenMI.Sdk.Backbone.Unit("meter", 1, 0, "meter");
            ElementSet targetElementSet = new ElementSet("inputLocation", "Location", ElementType.IDBased, new SpatialReference(""));

            Link triggerLink = new Link();
            triggerLink.SourceComponent = acceptorTs;
            triggerLink.TargetComponent = null;
            triggerLink.SourceQuantity = acceptorTs.GetOutputExchangeItem(0).Quantity;
            triggerLink.SourceElementSet = acceptorTs.GetOutputExchangeItem(0).ElementSet;
            triggerLink.TargetQuantity = targetQuantity;
            triggerLink.TargetElementSet = targetElementSet;
            triggerLink.ID = "TriggerLink";

            acceptorTs.AddLink(triggerLink);

            TimespanSeries tss1 = (TimespanSeries)acceptorTs.TimeSeriesGroup.Items[0];
            TimestampSeries tss2 = (TimestampSeries)acceptorTs.TimeSeriesGroup.Items[1];
            Assert.AreEqual(10.2, tss1.Items[0].Value);
            Assert.AreEqual(12.2, tss2.Items[0].Value);

            acceptorTs.GetValues(new TimeStamp(new System.DateTime(2010, 1, 3)), triggerLink.ID);

            Assert.AreEqual(4.3, tss1.Items[0].Value);
            Assert.AreEqual(6.3, tss2.Items[0].Value);

            linkableTimeSeriesGroup.Finish(); //save file
            acceptorTs.Finish(); //save file

        }
		public void Prepare()
		{
			try
			{
				ILinkableComponent riverModelLC = new RiverModelLC();
				ILinkableComponent trigger = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();
				
				riverModelLC.Initialize(new Argument[0]);
				trigger.Initialize(new Argument[0]);

				Link link = new Link(riverModelLC, riverModelLC.GetOutputExchangeItem(0).ElementSet,riverModelLC.GetOutputExchangeItem(0).Quantity,trigger,trigger.GetInputExchangeItem(0).ElementSet,trigger.GetInputExchangeItem(0).Quantity,"LinkID");
				riverModelLC.AddLink(link);
				trigger.AddLink(link);

				Assert.AreEqual(false, ((RiverModelLC) riverModelLC).PrepareForCompotationWasInvoked);
				riverModelLC.Prepare();
				Assert.AreEqual(true, ((RiverModelLC) riverModelLC).PrepareForCompotationWasInvoked);

				double x = ((IScalarSet)((SmartOutputLink)((RiverModelLC) riverModelLC).SmartOutputLinks[0]).SmartBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(7,x); //test if the initial state variables (e.g. flow) is copied to the buffer.

				double t = ((ITimeSpan)((SmartOutputLink)((RiverModelLC) riverModelLC).SmartOutputLinks[0]).SmartBuffer.GetTimeAt(0)).Start.ModifiedJulianDay;
				Assert.AreEqual(riverModelLC.TimeHorizon.Start.ModifiedJulianDay, t); //test if the initial time is copied to the buffer

				riverModelLC.Finish();
				riverModelLC.Dispose();
			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void GetValues1A()
		{
			// Running with one instances of riverModelLC linked ID-based to trigger

			try
			{
				ILinkableComponent riverModelLC = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();
	
				Argument[] riverArguments = new Argument[2];
				riverArguments[0] = new Argument("ModelID","RiverModel",true,"argument");
				riverArguments[1] = new Argument("TimeStepLength","3600",true,"A time step length of 1 hour");

				riverModelLC.Initialize(riverArguments);
				trigger.Initialize(new Argument[0]);

				Link link = new Link(riverModelLC, riverModelLC.GetOutputExchangeItem(2).ElementSet,riverModelLC.GetOutputExchangeItem(2).Quantity,trigger,trigger.GetInputExchangeItem(0).ElementSet,trigger.GetInputExchangeItem(0).Quantity,"LinkID");
				riverModelLC.AddLink(link);
				trigger.AddLink(link);

				riverModelLC.Prepare();
				
				double firstTriggerGetValuesTime = riverModelLC.TimeHorizon.Start.ModifiedJulianDay;
				TimeStamp[] triggerTimes = new TimeStamp[2];
				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 2);
				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 4.3);
	
				trigger.Run(triggerTimes);
				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(35.0/4.0,x1);

				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
				Assert.AreEqual(35.0/4.0,x2);

				riverModelLC.Finish();
				riverModelLC.Dispose();
				
			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void EarliestInputTime()
		{
			TestEngineLC testEngineLC = new TestEngineLC();
			Trigger trigger = new Trigger();

			testEngineLC.Initialize(new Argument[0]);

			Link triggerLink = new Link();
			triggerLink.ID = "TargetToTriggerLink";
			triggerLink.SourceComponent  = testEngineLC;
			triggerLink.SourceElementSet = testEngineLC.GetOutputExchangeItem(0).ElementSet; //last branch in the river
			triggerLink.SourceQuantity   = testEngineLC.GetOutputExchangeItem(0).Quantity;
			triggerLink.TargetComponent  = trigger;
			triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;  
			triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;

			testEngineLC.AddLink(triggerLink);
			testEngineLC.Prepare();
			Assert.AreEqual(testEngineLC.TimeHorizon.Start,testEngineLC.EarliestInputTime);

		}
		public void GetValues2A()
		{
			// == Running with two instances of riverModelLC ==
			// 
			// - The Two river are running with the same timestepping.
			//
			// - The link is ID Based link with flow from last branch of the source river to the top
			//   node of the target river.
			//
			// - The time argument in the GetValues from rive to river is of type ITimeSpan
			//
			//TODO: 1: The RiverModelEngine should change the inflow over time. As it is now the inflow is the same
			//         in all time steps. Another idea would be to have a output exchange item that hold the accumulated
			//         inflow, this could be useful when testing the manage state interface.
			//
			//       2: Make this test run with the two river using different timesteps and with the source river
			//          starting ealier that the target river.
			//
			//       3: In this test also events could be tested. Simply test if all the required events are
			//          thrown during the simulations.
			try
			{
				ILinkableComponent upperRiver = new RiverModelLC();
				ILinkableComponent lowerRiver = new RiverModelLC();
                HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger     = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] upperRiverArguments = new Argument[1];
				upperRiverArguments[0] = new Argument("ModelID","upperRiverModel",true,"argument");
				upperRiver.Initialize(upperRiverArguments);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] lowerRiverArguments = new Argument[1];
				lowerRiverArguments[0] = new Argument("ModelID","lowerRiverModel",true,"argument");
				lowerRiver.Initialize(lowerRiverArguments);
				trigger.Initialize(new Argument[0]);

				Assert.AreEqual("upperRiverModel",upperRiver.ModelID);
				Assert.AreEqual("lowerRiverModel",lowerRiver.ModelID);

				Link link = new Link();
				link.ID = "RiverToRiverLink";
				link.SourceComponent  = upperRiver;
				link.SourceElementSet = upperRiver.GetOutputExchangeItem(2).ElementSet; //last branch in the river
				link.SourceQuantity   = upperRiver.GetOutputExchangeItem(2).Quantity;
				link.TargetComponent  = lowerRiver;
				link.TargetElementSet = lowerRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				link.TargetQuantity   = lowerRiver.GetInputExchangeItem(0).Quantity;

				Link triggerLink = new Link();

				triggerLink.ID				 = "TriggerLink";
				triggerLink.SourceComponent  = lowerRiver;
				triggerLink.SourceElementSet = lowerRiver.GetOutputExchangeItem(2).ElementSet;
				triggerLink.SourceQuantity   = lowerRiver.GetOutputExchangeItem(2).Quantity;
				triggerLink.TargetComponent  = trigger;
				triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
				triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;
		
				upperRiver.AddLink(link);
				lowerRiver.AddLink(link);

				lowerRiver.AddLink(triggerLink);
				trigger.AddLink(triggerLink);

				upperRiver.Prepare();
				lowerRiver.Prepare();
				trigger.Prepare();

				double firstTriggerGetValuesTime = lowerRiver.TimeHorizon.Start.ModifiedJulianDay;
				TimeStamp[] triggerTimes = new TimeStamp[2];
				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 3);
				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 4.3);

				trigger.Run(triggerTimes);

				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(315.0/32.0,x1);

				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
				Assert.AreEqual(315.0/32.0,x2);

				upperRiver.Finish();
				lowerRiver.Finish();

				upperRiver.Dispose();
				lowerRiver.Dispose();

			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void RestoreState()
		{
			//  This test is based on GetValues2C
			try
			{
				ILinkableComponent timeSeries = new TimeSeriesComponent();
				ILinkableComponent upperRiver = new RiverModelLC();
				ILinkableComponent lowerRiver = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger     = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();

				timeSeries.Initialize(new Argument[0]);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] upperRiverArguments = new Argument[2];
				upperRiverArguments[0] = new Argument("ModelID","upperRiverModel",true,"argument");
				upperRiverArguments[1] = new Argument("TimeStepLength","21600",true,"xx");
				upperRiver.Initialize(upperRiverArguments);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] lowerRiverArguments = new Argument[2];
				lowerRiverArguments[0] = new Argument("ModelID","lowerRiverModel",true,"argument");
				lowerRiverArguments[1] = new Argument("TimeStepLength","86400",true,"xx");
				lowerRiver.Initialize(lowerRiverArguments);
				trigger.Initialize(new Argument[0]);

				Assert.AreEqual("upperRiverModel",upperRiver.ModelID);
				Assert.AreEqual("lowerRiverModel",lowerRiver.ModelID);

				Link timeSeriesToUpperRiverLink = new Link();
				timeSeriesToUpperRiverLink.ID = "timeSeriesToUpperRiverLink";
				timeSeriesToUpperRiverLink.SourceComponent  = timeSeries;
				timeSeriesToUpperRiverLink.SourceElementSet = timeSeries.GetOutputExchangeItem(0).ElementSet; //last branch in the river
				timeSeriesToUpperRiverLink.SourceQuantity   = timeSeries.GetOutputExchangeItem(0).Quantity;
				timeSeriesToUpperRiverLink.TargetComponent  = upperRiver;
				timeSeriesToUpperRiverLink.TargetElementSet = upperRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				timeSeriesToUpperRiverLink.TargetQuantity   = upperRiver.GetInputExchangeItem(0).Quantity;
				
				Link link = new Link();
				link.ID = "RiverToRiverLink";
				link.SourceComponent  = upperRiver;
				link.SourceElementSet = upperRiver.GetOutputExchangeItem(2).ElementSet; //last branch in the river
				link.SourceQuantity   = upperRiver.GetOutputExchangeItem(2).Quantity;
				link.TargetComponent  = lowerRiver;
				link.TargetElementSet = lowerRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				link.TargetQuantity   = lowerRiver.GetInputExchangeItem(0).Quantity;

				Link triggerLink = new Link();

				triggerLink.ID				 = "TriggerLink";
				triggerLink.SourceComponent  = lowerRiver;
				triggerLink.SourceElementSet = lowerRiver.GetOutputExchangeItem(2).ElementSet;
				triggerLink.SourceQuantity   = lowerRiver.GetOutputExchangeItem(2).Quantity;
				triggerLink.TargetComponent  = trigger;
				triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
				triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;
		
				timeSeries.AddLink(timeSeriesToUpperRiverLink);
				upperRiver.AddLink(timeSeriesToUpperRiverLink);

				upperRiver.AddLink(link);
				lowerRiver.AddLink(link);

				lowerRiver.AddLink(triggerLink);
				trigger.AddLink(triggerLink);
				
				timeSeries.Prepare();
				upperRiver.Prepare();
				lowerRiver.Prepare();
				trigger.Prepare();

//				double firstTriggerGetValuesTime = lowerRiver.TimeHorizon.Start.ModifiedJulianDay;
//				TimeStamp[] triggerTimes = new TimeStamp[2];
//				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 12.5);
//				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 16.2);

				double t = lowerRiver.TimeHorizon.Start.ModifiedJulianDay;
				Assert.AreEqual(315.0/32.0 + 13.0/64.0, ((ScalarSet)lowerRiver.GetValues(new TimeStamp(t+12.5),"TriggerLink")).GetScalar(0));
				string lowerRiverStateID = ((IManageState) lowerRiver).KeepCurrentState();
				string upperRiverStateID = ((IManageState) upperRiver).KeepCurrentState();
				Assert.AreEqual(315.0/32.0 + 17.0/64.0, ((ScalarSet)lowerRiver.GetValues(new TimeStamp(t+16.2),"TriggerLink")).GetScalar(0));
				((IManageState) lowerRiver).RestoreState(lowerRiverStateID);
				((IManageState) upperRiver).RestoreState(upperRiverStateID);
				lowerRiver.GetValues(new TimeStamp(t + 14.0),"TriggerLink");
				Assert.AreEqual(315.0/32.0 + 17.0/64.0, ((ScalarSet)lowerRiver.GetValues(new TimeStamp(t+16.2),"TriggerLink")).GetScalar(0));



			

//				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
//				Assert.AreEqual(315.0/32.0 + 13.0/64.0,x1);
//
//				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
//				Assert.AreEqual(315.0/32.0 + 17.0/64.0,x2);
//
//				Assert.AreEqual(2,((RiverModelLC) upperRiver)._maxBufferSize); //Test that the buffer is cleared

				upperRiver.Finish();
				lowerRiver.Finish();

				upperRiver.Dispose();
				lowerRiver.Dispose();

			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
//		[Ignore ("This test fails when dt = 1 hour but works for dt = 0.5 day")]
		public void GetValues2C()
		{
			// This test is a variation of GetValues 2B. What makes this test different is that the the two
			// connected river models are not using the same timesteps.
			// This test will test:
			// - is the buffer working correcly with respect to interpolations and buffering
			// - is the buffer working correctly with respect to clearing the buffer.
			
			try
			{
				ILinkableComponent timeSeries = new TimeSeriesComponent();
				ILinkableComponent upperRiver = new RiverModelLC();
				ILinkableComponent lowerRiver = new RiverModelLC();
				HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger trigger     = new HydroNumerics.OpenMI.Sdk.Wrapper.UnitTest.Trigger();

				timeSeries.Initialize(new Argument[0]);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] upperRiverArguments = new Argument[2];
				upperRiverArguments[0] = new Argument("ModelID","upperRiverModel",true,"argument");
				upperRiverArguments[1] = new Argument("TimeStepLength","21600",true,"A time step length of 1 day");
				upperRiver.Initialize(upperRiverArguments);

				// The ModelID is passes in ordet to make it easier to debug, otherwise you cannot se the difference between the two istances of RiverModelLC
				Argument[] lowerRiverArguments = new Argument[2];
				lowerRiverArguments[0] = new Argument("ModelID","lowerRiverModel",true,"argument");
				lowerRiverArguments[1] = new Argument("TimeStepLength","86400",true,"xx");
				lowerRiver.Initialize(lowerRiverArguments);
				trigger.Initialize(new Argument[0]);

				Assert.AreEqual("upperRiverModel",upperRiver.ModelID);
				Assert.AreEqual("lowerRiverModel",lowerRiver.ModelID);

				Link timeSeriesToUpperRiverLink = new Link();
				timeSeriesToUpperRiverLink.ID = "timeSeriesToUpperRiverLink";
				timeSeriesToUpperRiverLink.SourceComponent  = timeSeries;
				timeSeriesToUpperRiverLink.SourceElementSet = timeSeries.GetOutputExchangeItem(0).ElementSet; //last branch in the river
				timeSeriesToUpperRiverLink.SourceQuantity   = timeSeries.GetOutputExchangeItem(0).Quantity;
				timeSeriesToUpperRiverLink.TargetComponent  = upperRiver;
				timeSeriesToUpperRiverLink.TargetElementSet = upperRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				timeSeriesToUpperRiverLink.TargetQuantity   = upperRiver.GetInputExchangeItem(0).Quantity;
				
				Link link = new Link();
				link.ID = "RiverToRiverLink";
				link.SourceComponent  = upperRiver;
				link.SourceElementSet = upperRiver.GetOutputExchangeItem(2).ElementSet; //last branch in the river
				link.SourceQuantity   = upperRiver.GetOutputExchangeItem(2).Quantity;
				link.TargetComponent  = lowerRiver;
				link.TargetElementSet = lowerRiver.GetInputExchangeItem(0).ElementSet;  //first node in the river
				link.TargetQuantity   = lowerRiver.GetInputExchangeItem(0).Quantity;

				Link triggerLink = new Link();

				triggerLink.ID				 = "TriggerLink";
				triggerLink.SourceComponent  = lowerRiver;
				triggerLink.SourceElementSet = lowerRiver.GetOutputExchangeItem(2).ElementSet;
				triggerLink.SourceQuantity   = lowerRiver.GetOutputExchangeItem(2).Quantity;
				triggerLink.TargetComponent  = trigger;
				triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;
				triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;
		
				timeSeries.AddLink(timeSeriesToUpperRiverLink);
				upperRiver.AddLink(timeSeriesToUpperRiverLink);

				upperRiver.AddLink(link);
				lowerRiver.AddLink(link);

				lowerRiver.AddLink(triggerLink);
				trigger.AddLink(triggerLink);
				
				timeSeries.Prepare();
				upperRiver.Prepare();
				lowerRiver.Prepare();
				trigger.Prepare();

				double firstTriggerGetValuesTime = lowerRiver.TimeHorizon.Start.ModifiedJulianDay;
				TimeStamp[] triggerTimes = new TimeStamp[2];
				triggerTimes[0] = new TimeStamp(firstTriggerGetValuesTime + 12.5);
				triggerTimes[1] = new TimeStamp(firstTriggerGetValuesTime + 16.2);

				trigger.Run(triggerTimes);

				double x1 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(0)).GetScalar(0);
				Assert.AreEqual(315.0/32.0 + 13.0/64.0,x1);

				double x2 = ((IScalarSet)trigger.ResultsBuffer.GetValuesAt(1)).GetScalar(0);
				Assert.AreEqual(315.0/32.0 + 17.0/64.0,x2);

				Assert.AreEqual(10,((RiverModelLC) upperRiver)._maxBufferSize); //Test that the buffer is cleared

				upperRiver.Finish();
				lowerRiver.Finish();

				upperRiver.Dispose();
				lowerRiver.Dispose();

			}
			catch (System.Exception e)
			{
				ExceptionHandler.WriteException(e);
				throw (e);
			}
		}
		public void ClearState()
		{
			RiverModelLC riverModelLC = new RiverModelLC();
			Trigger trigger = new Trigger();

			riverModelLC.Initialize(new Argument[0]);

			Link triggerLink = new Link();
			triggerLink.ID = "TargetToTriggerLink";
			triggerLink.SourceComponent  = riverModelLC;
			triggerLink.SourceElementSet = riverModelLC.GetOutputExchangeItem(0).ElementSet; //last branch in the river
			triggerLink.SourceQuantity   = riverModelLC.GetOutputExchangeItem(0).Quantity;
			triggerLink.TargetComponent  = trigger;
			triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;  
			triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;

			riverModelLC.AddLink(triggerLink);
			riverModelLC.Prepare();
			string stateID = riverModelLC.KeepCurrentState();
			Assert.AreEqual("state:1",stateID);
			Assert.AreEqual(1,riverModelLC._riverModelEngine._states.Count);
			riverModelLC.ClearState("state:1");
			Assert.AreEqual(0,riverModelLC._riverModelEngine._states.Count);
		}
		public void XEvent()
		{
			// Event Test
			// Testing : 1) That all events are actually thrown during calculations
			
			TestEngineLC  sourceModel = new TestEngineLC();
			TestEngineLC  targetModel = new TestEngineLC();
			Trigger trigger           = new Trigger();

			sourceModel.Initialize(new Argument[0]);
			targetModel.Initialize(new Argument[0]);
			trigger.Initialize(new Argument[0]);

			Link link = new Link();
			link.ID = "SourceToTargetLink";
			link.SourceComponent  = sourceModel;
			link.SourceElementSet = sourceModel.GetOutputExchangeItem(0).ElementSet; //last branch in the river
			link.SourceQuantity   = sourceModel.GetOutputExchangeItem(0).Quantity;
			link.TargetComponent  = targetModel;
			link.TargetElementSet = targetModel.GetInputExchangeItem(0).ElementSet;  //first node in the river
			link.TargetQuantity   = targetModel.GetInputExchangeItem(0).Quantity;

			Link triggerLink = new Link();
			triggerLink.ID = "TargetToTriggerLink";
			triggerLink.SourceComponent  = targetModel;
			triggerLink.SourceElementSet = targetModel.GetOutputExchangeItem(0).ElementSet; //last branch in the river
			triggerLink.SourceQuantity   = targetModel.GetOutputExchangeItem(0).Quantity;
			triggerLink.TargetComponent  = trigger;
			triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;  
			triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;

			sourceModel.AddLink(link);
			targetModel.AddLink(link);

			targetModel.AddLink(triggerLink);
			trigger.AddLink(triggerLink);

			EventListener eventListener = new EventListener();
			eventListener._isSilent = true;

			for (int i = 0; i < eventListener.GetAcceptedEventTypeCount(); i++)
			{
				for (int n = 0; n < sourceModel.GetPublishedEventTypeCount(); n++)
				{
					if (eventListener.GetAcceptedEventType(i) == sourceModel.GetPublishedEventType(n))
					{
						sourceModel.Subscribe(eventListener, eventListener.GetAcceptedEventType(i));
					}
				}

				for (int n = 0; n < targetModel.GetPublishedEventTypeCount(); n++)
				{
					if (eventListener.GetAcceptedEventType(i) == targetModel.GetPublishedEventType(n))
					{
						targetModel.Subscribe(eventListener, eventListener.GetAcceptedEventType(i));
					}
				}
			}

			sourceModel.Prepare();
			targetModel.Prepare();
			trigger.Prepare();

			trigger.Run(new TimeStamp(sourceModel.TimeHorizon.Start.ModifiedJulianDay + 10));

			Assert.AreEqual(true , eventListener._dataChanged);   
			Assert.AreEqual(false, eventListener._globalProgress);
//			Assert.AreEqual(true , eventListener._informative);   //TODO This test was out commented, because it fails, further investigation needed
			Assert.AreEqual(false, eventListener._other);
			Assert.AreEqual(true, eventListener._sourceAfterGetValuesCall);
			Assert.AreEqual(true, eventListener._sourceBeforeGetValuesReturn);
			Assert.AreEqual(true, eventListener._targetAfterGetValuesReturn);
			Assert.AreEqual(true, eventListener._targetBeforeGetValuesCall);
			Assert.AreEqual(false, eventListener._timeStepProgres);
			Assert.AreEqual(false, eventListener._valueOutOfRange);
			Assert.AreEqual(false, eventListener._warning);
		}
		public void XUnitConvertion()
		{
			// Unit conversion. Converting Fahrenheit to Celcius
			
			double x;
			double y;
			
			TestEngineLC  sourceModel = new TestEngineLC();
			TestEngineLC  targetModel = new TestEngineLC();

			sourceModel.Initialize(new Argument[0]);
			targetModel.Initialize(new Argument[0]);

			Link link = new Link();
			link.ID = "SourcToTargetLink";
			link.SourceComponent  = sourceModel;
			link.SourceElementSet = sourceModel.GetOutputExchangeItem(0).ElementSet; //last branch in the river
			link.SourceQuantity   = new Quantity(new Unit("Deg. Fahrenheit",5.0/9.0, 273.16 - 32.0 * (5.0/9.0) ,"Fahrenheit"),"temperature","Temperature",global::OpenMI.Standard.ValueType.Scalar,new Dimension());
			link.TargetComponent  = targetModel;
			link.TargetElementSet = targetModel.GetInputExchangeItem(0).ElementSet;  //first node in the river
			link.TargetQuantity   = new Quantity(new Unit("Deg. Celcius",1.0, 273.16,"Celcius"),"temperature","Temperature",global::OpenMI.Standard.ValueType.Scalar,new Dimension());

			sourceModel.AddLink(link);
			targetModel.AddLink(link);

			sourceModel.Prepare();
			targetModel.Prepare();

			for (int i = 0; i < ((ScalarSet)sourceModel.GetValues(new TimeStamp(sourceModel.TimeHorizon.Start.ModifiedJulianDay + 10),"SourcToTargetLink")).Count; i++)
			{
				x = ((ScalarSet)sourceModel.GetValues(new TimeStamp(sourceModel.TimeHorizon.Start.ModifiedJulianDay + 10),"SourcToTargetLink")).GetScalar(i);
				y = (100.0 - 32.0) * (5.0/9.0); // = 37.7778  (100 deg. F = 37.7778 deg.C)
				Assert.AreEqual(y,x,0.0000000001);  //internal value is 80 deg Fahrenheit
			}
		}
        public void LinkedToTestComponent()
        {
            CreateHydroNetInputfile();

            HydroNumerics.OpenMI.Sdk.Backbone.OmiFileParser omiFileParser = new HydroNumerics.OpenMI.Sdk.Backbone.OmiFileParser();
            omiFileParser.ReadOmiFile(filename + ".omi");

            IArgument[] arguments = omiFileParser.GetArgumentsAsIArgumentArray();

            // Create the HydroNet linkableComponent
            LinkableComponent hydroNetLC = new LinkableComponent();

            hydroNetLC.Initialize(arguments);
            Assert.AreEqual("Lake model", hydroNetLC.ModelID);

            // Create the TestLinkableComponent
            TestLinkableComponent testLC = new TestLinkableComponent();

            testLC.Initialize(new HydroNumerics.OpenMI.Sdk.Backbone.Argument[0] {
            });

            // Link (hydroNet to TestLC) (leakage --> infiltration)
            IOutputExchangeItem leakageOutputExchangeItem = hydroNetLC.GetOutputExchangeItem(0);

            HydroNumerics.OpenMI.Sdk.Backbone.Link hydroNetLC2testLC = new HydroNumerics.OpenMI.Sdk.Backbone.Link();
            hydroNetLC2testLC.ID = "HydroNet2TestLC";
            hydroNetLC2testLC.SourceComponent  = hydroNetLC;
            hydroNetLC2testLC.TargetComponent  = testLC;
            hydroNetLC2testLC.SourceElementSet = hydroNetLC.GetOutputExchangeItem(0).ElementSet;
            hydroNetLC2testLC.SourceQuantity   = hydroNetLC.GetOutputExchangeItem(0).Quantity;
            Assert.AreEqual("Leakage", hydroNetLC2testLC.SourceQuantity.ID);
            hydroNetLC2testLC.TargetElementSet = testLC.GetOutputExchangeItem(0).ElementSet;
            hydroNetLC2testLC.TargetQuantity   = testLC.GetInputExchangeItem(0).Quantity;
            hydroNetLC2testLC.AddDataOperation(hydroNetLC.GetOutputExchangeItem(0).GetDataOperation(3));

            // Link (TestLC to hydroNet) (groundwaterhead --> groundwaterhead)
            HydroNumerics.OpenMI.Sdk.Backbone.Link testLC2HydroNetLC = new HydroNumerics.OpenMI.Sdk.Backbone.Link();
            testLC2HydroNetLC.ID = "testLC2HydroNetLc";
            testLC2HydroNetLC.SourceComponent  = testLC;
            testLC2HydroNetLC.TargetComponent  = hydroNetLC;
            testLC2HydroNetLC.SourceQuantity   = testLC.GetOutputExchangeItem(0).Quantity;
            testLC2HydroNetLC.SourceElementSet = testLC.GetOutputExchangeItem(0).ElementSet;
            testLC2HydroNetLC.TargetQuantity   = hydroNetLC.GetInputExchangeItem(0).Quantity;
            Assert.AreEqual("Head", testLC2HydroNetLC.TargetQuantity.ID); //check to see if this is the right quantity
            testLC2HydroNetLC.TargetElementSet = hydroNetLC.GetInputExchangeItem(0).ElementSet;
            testLC2HydroNetLC.AddDataOperation(testLC.GetOutputExchangeItem(0).GetDataOperation(3));
            testLC.AddLink(testLC2HydroNetLC);
            hydroNetLC.AddLink(testLC2HydroNetLC);

            hydroNetLC.AddLink(hydroNetLC2testLC);
            testLC.AddLink(hydroNetLC2testLC);

            // triggerlink
            HydroNumerics.OpenMI.Sdk.DevelopmentSupport.Trigger trigger = new HydroNumerics.OpenMI.Sdk.DevelopmentSupport.Trigger();
            trigger.Initialize(new HydroNumerics.OpenMI.Sdk.Backbone.Argument[0] {
            });
            HydroNumerics.OpenMI.Sdk.Backbone.Link triggerLink = new HydroNumerics.OpenMI.Sdk.Backbone.Link();
            triggerLink.ID = "TriggerLink";
            triggerLink.SourceComponent  = testLC;
            triggerLink.TargetComponent  = trigger;
            triggerLink.SourceQuantity   = testLC.GetOutputExchangeItem(0).Quantity;
            triggerLink.SourceElementSet = testLC.GetOutputExchangeItem(0).ElementSet;
            triggerLink.TargetQuantity   = trigger.GetInputExchangeItem(0).Quantity;
            triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;

            testLC.AddLink(triggerLink);
            trigger.AddLink(triggerLink);

            // prepare
            trigger.Prepare();
            hydroNetLC.Prepare();
            testLC.Prepare();

            ScalarSet scalarSet = (ScalarSet)hydroNetLC.GetValues(new TimeStamp(new DateTime(2001, 6, 1)), hydroNetLC2testLC.ID);
            double    expected  = -0.0000065836086956521805 * 2.0;

            Assert.AreEqual(0, scalarSet.data[0], 0.000000000001);
            Assert.AreEqual(0, scalarSet.data[1], 0.000000000001);
            Assert.AreEqual(expected, scalarSet.data[2], 0.000000000001);
            Assert.AreEqual(0, scalarSet.data[3], 0.000000000001);

            // Run
            //trigger.Run(testLC.TimeHorizon.End);

            //TimestampSeries infiltTSS = ((TimestampSeries) testLC.TestEngine.Infiltrations.Items[0]);


            trigger.Finish();
            hydroNetLC.Finish();
            testLC.Finish();

            trigger.Dispose();
            hydroNetLC.Dispose();
            testLC.Dispose();
        }
		public void RemoveLink()
		{
			TestEngineLC  sourceModel = new TestEngineLC();
			TestEngineLC  targetModel = new TestEngineLC();

			sourceModel.Initialize(new Argument[0]);
			targetModel.Initialize(new Argument[0]);
	
			Link link = new Link();
			link.ID = "SourceToTargetLink";
			link.SourceComponent  = sourceModel;
			link.SourceElementSet = sourceModel.GetOutputExchangeItem(0).ElementSet; //last branch in the river
			link.SourceQuantity   = sourceModel.GetOutputExchangeItem(0).Quantity;
			link.TargetComponent  = targetModel;
			link.TargetElementSet = targetModel.GetInputExchangeItem(0).ElementSet;  //first node in the river
			link.TargetQuantity   = targetModel.GetInputExchangeItem(0).Quantity;

			Assert.AreEqual(0,sourceModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,sourceModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,targetModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,targetModel.SmartOutputLinks.Count);
			
			sourceModel.AddLink(link);
			targetModel.AddLink(link);

			Assert.AreEqual(1,sourceModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,sourceModel.SmartInputLinks.Count);
			Assert.AreEqual(0,targetModel.SmartOutputLinks.Count);
			Assert.AreEqual(1,targetModel.SmartInputLinks.Count);

			sourceModel.RemoveLink(link.ID);
			targetModel.RemoveLink(link.ID);

			Assert.AreEqual(0,sourceModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,sourceModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,targetModel.SmartOutputLinks.Count);
			Assert.AreEqual(0,targetModel.SmartOutputLinks.Count);
		
		}
		private void buttonApply_Click(object sender, System.EventArgs e)
		{
			// get checked items
			IQuantity providerQuantity, acceptorQuantity;
			IElementSet providerElementSet, acceptorElementSet;
			IDataOperation[] providerDataOperations, acceptorDataOperations;

			providerExchangeItemSelector.GetCheckedExchangeItem( out providerQuantity, out providerElementSet, out providerDataOperations );
			acceptorExchangeItemSelector.GetCheckedExchangeItem( out acceptorQuantity, out acceptorElementSet, out acceptorDataOperations );

			// check wheather all needed informations are avaliable
			if( providerElementSet==null )
			{
				MessageBox.Show( "No Output Exchange Item selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
				return;
			}
			if( acceptorElementSet==null )
			{
				MessageBox.Show( "No Input Exchange Item selected.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
				return;
			}
			if( _uilink.AcceptingModel.ModelID == CompositionManager.TriggerModelID
				&& _uilink.Links.Count>=1
				&& listLinks.SelectedIndex==0 )
			{
				MessageBox.Show( "Trigger can have only one link.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
				return;
			}

			if( !CheckIfDataOperationsAreValid() )
			{
				switch( MessageBox.Show("Selected combination of DataOperations is invalid. Adding such link to LinkableComponents may\nway to unexpected result, maybe whole application will crash. If you are sure what you do,\nclick 'Yes', but in this case it's STRONGLY recommended to save your project before you proceed.\n\nDo you really want to continue ?", "WARNING", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) )
				{
					case DialogResult.Yes:
						break;
					default:
						return;
				}
			}

			Debug.Assert( providerQuantity!=null && acceptorQuantity!=null );
			Debug.Assert( listLinks.SelectedIndex >= 0 );

			int linkID;

			// TODO: shouldn't be this functionallity in UIConnection class ???
			//       - only problem with unique linkID

			if( listLinks.SelectedIndex==0 )
			{
				// Creating new link, so create new ID for it
				linkID = ++_startingLinkID; 
			}
			else
			{
				// Modifying existing link, use its previous ID
				string oldLinkID = ((ILink)_uilink.Links[listLinks.SelectedIndex-1]).ID ;
				linkID = int.Parse( oldLinkID );

				// Remove this link from both LinkableComponents
				_uilink.AcceptingModel.LinkableComponent.RemoveLink( oldLinkID ); 
				_uilink.ProvidingModel.LinkableComponent.RemoveLink( oldLinkID );
			}

			// Create a new link even if modifing existing one.
			// That's because if some DataOperations were not selected,
			// we wouldn't be able to remove them from the link
			Link link = new Link(
				_uilink.ProvidingModel.LinkableComponent,
				providerElementSet,
				providerQuantity,
				_uilink.AcceptingModel.LinkableComponent,
				acceptorElementSet,
				acceptorQuantity,
				linkID.ToString() );

			// add DataOperations
			foreach( IDataOperation dataOperation in providerDataOperations )
			{
				// set all changed writeable Arguments to dataOperation from property box 
				if( _propertyManagerCache.Contains(dataOperation) )
					for( int i=0; i<dataOperation.ArgumentCount; i++ )
					{
						IArgument argument = dataOperation.GetArgument(i);

						if( !argument.ReadOnly )
						{
							string newValue = ((HydroNumerics.OpenMI.Gui.Controls.PropertyManager)_propertyManagerCache[dataOperation]).GetProperty( argument.Key );
							if( argument.Value != newValue )
								argument.Value = newValue;
						}
					}				

				link.AddDataOperation( dataOperation );
			}
		
			// add/set new link to list
			if( listLinks.SelectedIndex==0 )
				_uilink.Links.Add(link);
			else
				_uilink.Links[ listLinks.SelectedIndex-1 ] = link;

			// ...and add new link to both LinkableComponents
			_uilink.ProvidingModel.LinkableComponent.AddLink( link );
			_uilink.AcceptingModel.LinkableComponent.AddLink( link );
			
			UpdateListLinks();
			UpdateViewElementSetButton();
		
			_shouldBeSaved = true;
		}
        public void LinkedToTestComponent()
        {

            CreateHydroNetInputfile();

            HydroNumerics.OpenMI.Sdk.Backbone.OmiFileParser omiFileParser = new HydroNumerics.OpenMI.Sdk.Backbone.OmiFileParser();
            omiFileParser.ReadOmiFile(filename + ".omi");

            IArgument[] arguments = omiFileParser.GetArgumentsAsIArgumentArray();

            // Create the HydroNet linkableComponent
            LinkableComponent hydroNetLC = new LinkableComponent();
            hydroNetLC.Initialize(arguments);
            Assert.AreEqual("Lake model", hydroNetLC.ModelID);

            // Create the TestLinkableComponent
            TestLinkableComponent testLC = new TestLinkableComponent();
            testLC.Initialize(new HydroNumerics.OpenMI.Sdk.Backbone.Argument[0] { });

            // Link (hydroNet to TestLC) (leakage --> infiltration)
            IOutputExchangeItem leakageOutputExchangeItem = hydroNetLC.GetOutputExchangeItem(0);
            HydroNumerics.OpenMI.Sdk.Backbone.Link hydroNetLC2testLC = new HydroNumerics.OpenMI.Sdk.Backbone.Link();
            hydroNetLC2testLC.ID = "HydroNet2TestLC";
            hydroNetLC2testLC.SourceComponent = hydroNetLC;
            hydroNetLC2testLC.TargetComponent = testLC;
            hydroNetLC2testLC.SourceElementSet = hydroNetLC.GetOutputExchangeItem(0).ElementSet;
            hydroNetLC2testLC.SourceQuantity = hydroNetLC.GetOutputExchangeItem(0).Quantity;
            Assert.AreEqual("Leakage", hydroNetLC2testLC.SourceQuantity.ID);
            hydroNetLC2testLC.TargetElementSet = testLC.GetOutputExchangeItem(0).ElementSet;
            hydroNetLC2testLC.TargetQuantity = testLC.GetInputExchangeItem(0).Quantity;
            hydroNetLC2testLC.AddDataOperation(hydroNetLC.GetOutputExchangeItem(0).GetDataOperation(3));

            // Link (TestLC to hydroNet) (groundwaterhead --> groundwaterhead)
            HydroNumerics.OpenMI.Sdk.Backbone.Link testLC2HydroNetLC = new HydroNumerics.OpenMI.Sdk.Backbone.Link();
            testLC2HydroNetLC.ID = "testLC2HydroNetLc";
            testLC2HydroNetLC.SourceComponent = testLC;
            testLC2HydroNetLC.TargetComponent = hydroNetLC;
            testLC2HydroNetLC.SourceQuantity = testLC.GetOutputExchangeItem(0).Quantity;
            testLC2HydroNetLC.SourceElementSet = testLC.GetOutputExchangeItem(0).ElementSet;
            testLC2HydroNetLC.TargetQuantity = hydroNetLC.GetInputExchangeItem(0).Quantity;
            Assert.AreEqual("Head", testLC2HydroNetLC.TargetQuantity.ID); //check to see if this is the right quantity
            testLC2HydroNetLC.TargetElementSet = hydroNetLC.GetInputExchangeItem(0).ElementSet;
            testLC2HydroNetLC.AddDataOperation(testLC.GetOutputExchangeItem(0).GetDataOperation(3));
            testLC.AddLink(testLC2HydroNetLC);
            hydroNetLC.AddLink(testLC2HydroNetLC);

            hydroNetLC.AddLink(hydroNetLC2testLC);
            testLC.AddLink(hydroNetLC2testLC);

            // triggerlink
            HydroNumerics.OpenMI.Sdk.DevelopmentSupport.Trigger trigger = new HydroNumerics.OpenMI.Sdk.DevelopmentSupport.Trigger();
            trigger.Initialize(new HydroNumerics.OpenMI.Sdk.Backbone.Argument[0] { });
            HydroNumerics.OpenMI.Sdk.Backbone.Link triggerLink = new HydroNumerics.OpenMI.Sdk.Backbone.Link();
            triggerLink.ID = "TriggerLink";
            triggerLink.SourceComponent = testLC;
            triggerLink.TargetComponent = trigger;
            triggerLink.SourceQuantity = testLC.GetOutputExchangeItem(0).Quantity;
            triggerLink.SourceElementSet = testLC.GetOutputExchangeItem(0).ElementSet;
            triggerLink.TargetQuantity = trigger.GetInputExchangeItem(0).Quantity;
            triggerLink.TargetElementSet = trigger.GetInputExchangeItem(0).ElementSet;

            testLC.AddLink(triggerLink);
            trigger.AddLink(triggerLink);

            // prepare
            trigger.Prepare();
            hydroNetLC.Prepare();
            testLC.Prepare();

            ScalarSet scalarSet =  (ScalarSet) hydroNetLC.GetValues(new TimeStamp(new DateTime(2001, 6, 1)), hydroNetLC2testLC.ID);
            double expected = -0.0000065836086956521805 * 2.0;
            Assert.AreEqual(0, scalarSet.data[0], 0.000000000001);
            Assert.AreEqual(0, scalarSet.data[1], 0.000000000001);
            Assert.AreEqual(expected, scalarSet.data[2], 0.000000000001);
            Assert.AreEqual(0, scalarSet.data[3], 0.000000000001);

            // Run
            //trigger.Run(testLC.TimeHorizon.End);

            //TimestampSeries infiltTSS = ((TimestampSeries) testLC.TestEngine.Infiltrations.Items[0]);

           
            trigger.Finish();
            hydroNetLC.Finish();
            testLC.Finish();

            trigger.Dispose();
            hydroNetLC.Dispose();
            testLC.Dispose();
        }