public void MyTestInitialize()
        {
            filename = "HydroNumerics.Time.OpenMI.UnitTest.LinkableTimeSeriesGroupTest.xts";
            outputFilename = "HydroNumerics.Time.OpenMI.UnitTest.LinkableTimeSeriesGroupTest.out.xts";
            
            TimespanSeries timespanSeries = new TimespanSeries("Flow", new System.DateTime(2010, 1, 1), 10, 2, TimestepUnit.Days, 4.3);
            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, 6.3);
            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 = "MyTsGroup";
            tsg.Items.Add(timespanSeries);
            tsg.Items.Add(timestampSeries);
            tsg.Save(filename);

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

        }
		public void ReadOnly()
		{
			Argument param = new Argument();
			param.ReadOnly = true;
			Assert.AreEqual(true,param.ReadOnly);
			param.ReadOnly = false;
			Assert.AreEqual(false,param.ReadOnly);
		}
		public void Constructor()
		{
			Argument param = new Argument("key","value",true,"argument1");
			Assert.AreEqual("key",param.Key);
			Assert.AreEqual("value",param.Value);

			Argument param2 = new Argument(param);
			Assert.AreEqual(param,param2);
		}
 public IArgument[] GetArgumentsAsIArgumentArray()
 {
     IArgument[] args = new Argument[arguments.Count];
     int i = 0;
     foreach (KeyValuePair<string, string> keyValuePair in arguments)
     {
         args[i] = new Argument(keyValuePair.Key, keyValuePair.Value, true, "No description");
         i++;
     }
     
     return args;
 }
		public void Arguments()
		{
			Argument param1 = new Argument("key1","value1",true,"argument1");
			Argument param2 = new Argument("key2","value2",true,"argument2");
			Argument param3 = new Argument("key3","value3",true,"argument3");

			DataOperation operation = new DataOperation();
			operation.AddArgument(param1);
			operation.AddArgument(param2);
			operation.AddArgument(param3);

			Assert.AreEqual(3,operation.ArgumentCount);
			Assert.AreEqual(param1,operation.GetArgument(0));
			Assert.AreEqual(param2,operation.GetArgument(1));
			Assert.AreEqual(param3,operation.GetArgument(2));
		}
		public void Constructor() 
		{
			DataOperation operation = new DataOperation("DataOperationID");
			Argument param1 = new Argument("key1","value1",true,"argument1");
			Argument param2 = new Argument("key2","value2",true,"argument2");
			Argument param3 = new Argument("key3","value3",true,"argument3");
			operation.AddArgument(param1);
			operation.AddArgument(param2);
			operation.AddArgument(param3);
			Assert.AreEqual("DataOperationID",operation.ID);
			
			DataOperation operation2 = new DataOperation(operation);

			Assert.AreEqual(operation,operation2);

		}
Exemple #7
0
        /// <summary>
        /// Constructor
        /// </summary>
        public SmartBufferDataOperation()
        {
            _arguments = new HydroNumerics.OpenMI.Sdk.Backbone.Argument[3];

            _arguments[0]             = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
            _arguments[0].Description = "Arguments associated the buffering and extrapolation";
            _arguments[0].Key         = "Type";
            _arguments[0].Value       = "SmartBuffer Arguments";
            _arguments[0].ReadOnly    = true;

            _arguments[1]             = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
            _arguments[1].Description = "Relaxation factor used for temporal extrapolation must be in the interval [0.0,1.0]";
            _arguments[1].Key         = "Relaxation Factor";
            _arguments[1].Value       = "0.0";
            _arguments[1].ReadOnly    = false;

            _arguments[2]             = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
            _arguments[2].Description = "Do extended validation. Must be \"true\" or \"false\"";
            _arguments[2].Key         = "Do Extended Data Validation";
            _arguments[2].Value       = "true";
            _arguments[2].ReadOnly    = false;

            _isActivated = false;
        }
		/// <summary>
		/// Constructor
		/// </summary>
        public SmartBufferDataOperation()
		{
			_arguments = new HydroNumerics.OpenMI.Sdk.Backbone.Argument[3];

			_arguments[0] = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
			_arguments[0].Description = "Arguments associated the buffering and extrapolation";
			_arguments[0].Key = "Type";
			_arguments[0].Value = "SmartBuffer Arguments";
			_arguments[0].ReadOnly = true;

			_arguments[1] = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
			_arguments[1].Description = "Relaxation factor used for temporal extrapolation must be in the interval [0.0,1.0]";
			_arguments[1].Key = "Relaxation Factor";
			_arguments[1].Value = "0.0";
			_arguments[1].ReadOnly = false;

			_arguments[2] = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
			_arguments[2].Description = "Do extended validation. Must be \"true\" or \"false\"";
			_arguments[2].Key = "Do Extended Data Validation";
			_arguments[2].Value = "true";
			_arguments[2].ReadOnly = false;

			_isActivated = false;
		}
		/// <summary>
		/// Constructor
		/// </summary>
        public LinearConversionDataOperation()
		{
			_arguments = new HydroNumerics.OpenMI.Sdk.Backbone.Argument[3];

			_arguments[0] = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
			_arguments[0].Description = "Parameter A. Used in conversion: A*x + B";
			_arguments[0].Key = "Type";
			_arguments[0].Value = "Linear Conversion";
			_arguments[0].ReadOnly = true;

			_arguments[1] = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
			_arguments[1].Description = "Parameter A. Used in conversion: A*x + B";
			_arguments[1].Key = "A";
			_arguments[1].Value = "1.0";
			_arguments[1].ReadOnly = false;

			_arguments[2] = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
			_arguments[2].Description = "Parameter B. Used in conversion: A*x + B";
			_arguments[2].Key = "B";
			_arguments[2].Value = "0.0";
			_arguments[2].ReadOnly = false;

			_isActivated = false;
		}
Exemple #10
0
        /// <summary>
        /// Constructor
        /// </summary>
        public LinearConversionDataOperation()
        {
            _arguments = new HydroNumerics.OpenMI.Sdk.Backbone.Argument[3];

            _arguments[0]             = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
            _arguments[0].Description = "Parameter A. Used in conversion: A*x + B";
            _arguments[0].Key         = "Type";
            _arguments[0].Value       = "Linear Conversion";
            _arguments[0].ReadOnly    = true;

            _arguments[1]             = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
            _arguments[1].Description = "Parameter A. Used in conversion: A*x + B";
            _arguments[1].Key         = "A";
            _arguments[1].Value       = "1.0";
            _arguments[1].ReadOnly    = false;

            _arguments[2]             = new HydroNumerics.OpenMI.Sdk.Backbone.Argument();
            _arguments[2].Description = "Parameter B. Used in conversion: A*x + B";
            _arguments[2].Key         = "B";
            _arguments[2].Value       = "0.0";
            _arguments[2].ReadOnly    = false;

            _isActivated = false;
        }
		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 Equals()
		{
			Argument param1 = new Argument("key","value",true,"argument1");
			Argument param2 = new Argument("key","value",true,"argument2");

			Assert.IsTrue(param1.Equals(param2));
			param1.Key = "key1";
			Assert.IsFalse(param1.Equals(param2));
			param1.Key = "key";
			param1.Value ="value1";
			Assert.IsFalse(param1.Equals(param2));

			Assert.IsFalse(param1.Equals(null));
			Assert.IsFalse(param1.Equals("string"));
		}
		public void Description()
		{
			Argument param = new Argument();
			param.Description = "Description";
			Assert.AreEqual("Description",param.Description);
		}
        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 Value()
		{
			Argument param = new Argument();
			param.Value = "OperationValue";
			Assert.AreEqual("OperationValue",param.Value);
		}
		public void Key()
		{
			Argument param = new Argument();
			param.Key = "OperationKey";
			Assert.AreEqual("OperationKey",param.Key);
		}
		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 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);
			}
		}
//		[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 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);
			}
		}
		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 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 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 Initialize()
		{
			//----- Testing -----------------------------------------------------------
			// 1: That the Initialize method is called on the engine
			// 2: That the initializeMethodWasInvoked flas is altered from false to true
			// 3: That the Argument are correctly changed to a Hashtable
			// -------------------------------------------------------------------------

			ILinkableComponent riverModelLC = new RiverModelLC();
			Argument[] arguments = new Argument[1];
			arguments[0] = new Argument("ModelID","TestRiverModelID",true,"ID for the model");
			Assert.AreEqual(false,((RiverModelLC)riverModelLC)._riverModelEngine._initializeMethodWasInvoked);
			riverModelLC.Initialize(arguments);
			Assert.AreEqual(true,((RiverModelLC)riverModelLC)._riverModelEngine._initializeMethodWasInvoked);
			Assert.AreEqual("TestRiverModelID",riverModelLC.ModelID);
			riverModelLC.Prepare();
			riverModelLC.Finish();
			riverModelLC.Dispose();
		}
		public void Equals()
		{
			Argument param1 = new Argument("key1","value1",true,"argument1");
			Argument param2 = new Argument("key2","value2",true,"argument2");
			Argument param3 = new Argument("key3","value3",true,"argument3");

			DataOperation operation1 = new DataOperation("ID");

			operation1.AddArgument(param1);
			operation1.AddArgument(param2);
			operation1.AddArgument(param3);

			param1 = new Argument("key1","value1",true,"argument1");
			param2 = new Argument("key2","value2",true,"argument2");
			param3 = new Argument("key3","value3",true,"argument3");

			DataOperation operation2 = new DataOperation("ID");
			operation2.AddArgument(param1);
			operation2.AddArgument(param2);

			Assert.IsFalse(operation1.Equals(operation2));

			operation2.AddArgument(param3);

			Assert.IsTrue(operation1.Equals(operation2));

			param1.Key="key";

			Assert.IsFalse(operation1.Equals(operation2));

			param1.Key="key1";

			operation1.ID = "ID1";

			Assert.IsFalse(operation1.Equals(operation2));

			operation1.ID = "ID";

			Assert.IsFalse(operation1.Equals(null));
			Assert.IsFalse(operation1.Equals("string"));
		}
		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);
			}
		}