public void ConvertBytesToItemStatus(byte[] theBuffer, out ItemStatus[] theStatuses)
        {
            theStatuses = null;

            if (theBuffer != null)
            {
                //try
                //{ 
                MemoryStream ms = new MemoryStream(theBuffer);
                BinaryReader br = new BinaryReader(ms);
                // count of MIVs.
                //  [unsigned int number_of_elements ]
                uint statusCnt = br.ReadUInt32();
                theStatuses = new ItemStatus[statusCnt];

                for (uint currStatus = 0;
                    currStatus < statusCnt;
                    currStatus++)
                {
                    //  <<ItemIdentity>>
                    ConvertBytesToItemIdentity(ref (theStatuses[currStatus].itemField), br);
                    //      [ushort errorCodeField]
                    theStatuses[currStatus].errorCodeField = br.ReadUInt16();
                    //      [bool errorCodeFieldSpecified]
                    theStatuses[currStatus].errorCodeFieldSpecified = br.ReadBoolean();

                }
                //}
                //catch (Exception e)
                //{
                //    // TODO RJK use real logging here..
                //    Console.WriteLine("{0}", e.StackTrace);
                //}
            }
        }
        public void NullArrayTest()
        {
            int countToTest = 2;
            MonitoredItemValue[] mivs = new MonitoredItemValue[countToTest];
            ItemStatus[] statuses = new ItemStatus[countToTest];
            for (uint currOfst = 0;
                    currOfst < countToTest;
                    currOfst++)
            {
                mivs[currOfst].itemField.Type = (ushort)(currOfst + 1);
                mivs[currOfst].itemField.ReferenceType = (ushort)(currOfst + 2);
                //mivs[currOfst].itemField.Name = String.Format("testing name string #{0}", currOfst + 3);
                mivs[currOfst].itemField.Name = null;
                mivs[currOfst].itemField.ContextName = null;
                mivs[currOfst].itemField.Id = (ulong)(currOfst + 5);
                mivs[currOfst].itemField.IdSpecified = false;

                mivs[currOfst].valueField.timestampField = DateTime.Now;
                mivs[currOfst].valueField.timestampFieldSpecified = true;
                mivs[currOfst].valueField.valueField.typeField = (ushort)(currOfst + 6);
                mivs[currOfst].valueField.valueField.lengthField = (int)(currOfst + 7);
                mivs[currOfst].valueField.valueField.payloadField = null;
                mivs[currOfst].valueField.statusField.countField = (sbyte)(currOfst + 8);
                mivs[currOfst].valueField.statusField.payloadField = null;
                mivs[currOfst].userDataField.typeField = (ushort)(currOfst + 9);
                mivs[currOfst].userDataField.lengthField = (int)(currOfst + 10);
                mivs[currOfst].userDataField.payloadField = null;

                statuses[currOfst].itemField.Type = (ushort)(currOfst + 11);
                statuses[currOfst].itemField.ReferenceType = (ushort)(currOfst + 12);
                statuses[currOfst].itemField.Name = null;
                statuses[currOfst].itemField.ContextName = null;
                statuses[currOfst].itemField.Id = (ulong)(currOfst + 13);
                statuses[currOfst].itemField.IdSpecified = false;
                statuses[currOfst].errorCodeField = (ushort)(currOfst + 14);
                statuses[currOfst].errorCodeFieldSpecified = true;

            }
            MonitoredItemConverter cnvrtr = new MonitoredItemConverter();

            byte[] buf = cnvrtr.ConvertMIVToBytes(mivs);
            byte[] statusesBuf = cnvrtr.ConvertItemStatusToBytes(statuses);

            MonitoredItemValue[] mivs2;
            ItemStatus[] statuses2;

            // this makes a copy.. which is probably ok given what we are doing..
            // GetBuffer is more efficient here.. but returns more than what we 
            // need to transfer (its highly likely to have unused slop-over bytes at the 
            // end of the buffer), which is highly wasteful of network resources, which
            // is the efficiency we are tracking here..
            Console.WriteLine("MIV buf dump:");
            DumpString(buf);
            Console.WriteLine("ItemStatus buf dump:");
            DumpString(statusesBuf);

            cnvrtr.ConvertBytesToMIV(buf, out mivs2);
            cnvrtr.ConvertBytesToItemStatus(statusesBuf, out statuses2);

            Assert.AreEqual(mivs.Length, mivs2.Length);
            Assert.AreEqual(statuses.Length, statuses2.Length);
            Assert.AreEqual(mivs2.Length,statuses2.Length);

            int len = mivs.Length;
            for (int currmiv = 0;
                currmiv < len;
                currmiv++)
            {
                //mivs[currOfst].itemField.Type = (ushort)(currOfst + 1);
                Assert.AreEqual(mivs[currmiv].itemField.Type, mivs2[currmiv].itemField.Type);
                //mivs[currOfst].itemField.ReferenceType = (ushort)(currOfst + 2);
                Assert.AreEqual(mivs[currmiv].itemField.ReferenceType, mivs2[currmiv].itemField.ReferenceType);
                //mivs[currOfst].itemField.Name = String.Format("testing name string #{0}", currOfst + 3);
                Assert.AreEqual(mivs[currmiv].itemField.Name, null);
                Assert.AreEqual(mivs2[currmiv].itemField.Name,"");
                //mivs[currOfst].itemField.ContextName = String.Format("testing contextname string #{0}", currOfst + 4);
                Assert.AreEqual(mivs[currmiv].itemField.ContextName, null);
                Assert.AreEqual(mivs2[currmiv].itemField.ContextName, "" );
                //mivs[currOfst].itemField.Id = (ulong)(currOfst + 5);
                Assert.AreEqual(mivs[currmiv].itemField.Id, mivs2[currmiv].itemField.Id);
                //mivs[currOfst].itemField.IdSpecified = false;
                Assert.AreEqual(mivs[currmiv].itemField.IdSpecified, mivs2[currmiv].itemField.IdSpecified);

                //mivs[currOfst].valueField.timestampField = DateTime.Now;
                Assert.AreEqual(mivs[currmiv].valueField.timestampField, mivs2[currmiv].valueField.timestampField);
                //mivs[currOfst].valueField.timestampFieldSpecified = true;
                Assert.AreEqual(mivs[currmiv].valueField.timestampFieldSpecified, mivs2[currmiv].valueField.timestampFieldSpecified);
                //mivs[currOfst].valueField.valueField.typeField = (ushort)(currOfst + 6);
                Assert.AreEqual(mivs[currmiv].valueField.valueField.typeField, mivs2[currmiv].valueField.valueField.typeField);
                //mivs[currOfst].valueField.valueField.lengthField = (int)(currOfst + 7);
                Assert.AreEqual(mivs[currmiv].valueField.valueField.lengthField, mivs2[currmiv].valueField.valueField.lengthField);
                //byte[] tmpBytes = new byte[currOfst + 2];
                //for (int aryOfst = 0; aryOfst < tmpBytes.Length; aryOfst++)
                //{
                //    tmpBytes[aryOfst] = (byte)(aryOfst + currOfst);
                //}
                //mivs[currOfst].valueField.valueField.payloadField = tmpBytes;
                Assert.AreEqual(mivs[currmiv].valueField.valueField.payloadField, null);
                Assert.AreEqual(mivs2[currmiv].valueField.valueField.payloadField, null);

                //mivs[currOfst].valueField.statusField.countField = (sbyte)(currOfst + 8);
                Assert.AreEqual(mivs[currmiv].valueField.statusField.countField, mivs2[currmiv].valueField.statusField.countField);
                //mivs[currOfst].valueField.statusField.payloadField = tmpBytes;
                Assert.AreEqual(mivs[currmiv].valueField.statusField.payloadField,null);
                Assert.AreEqual(mivs2[currmiv].valueField.statusField.payloadField,null);


                //mivs[currOfst].userDataField.typeField = (ushort)(currOfst + 9);
                Assert.AreEqual(mivs[currmiv].userDataField.typeField, mivs2[currmiv].userDataField.typeField);
                //mivs[currOfst].userDataField.lengthField = (int)(currOfst + 10);
                Assert.AreEqual(mivs[currmiv].userDataField.lengthField, mivs2[currmiv].userDataField.lengthField);
                //mivs[currOfst].userDataField.payloadField = tmpBytes;
                Assert.AreEqual(mivs[currmiv].userDataField.payloadField,null);
                Assert.AreEqual(mivs2[currmiv].userDataField.payloadField,null);

                Assert.AreEqual(statuses[currmiv].itemField.Type,           statuses2[currmiv].itemField.Type);
                Assert.AreEqual(statuses[currmiv].itemField.ReferenceType,  statuses2[currmiv].itemField.ReferenceType);
                Assert.AreEqual(statuses[currmiv].itemField.Name, null);
                Assert.AreEqual(statuses2[currmiv].itemField.Name, "");
                Assert.AreEqual(statuses[currmiv].itemField.ContextName, null);
                Assert.AreEqual(statuses2[currmiv].itemField.ContextName, "");
                Assert.AreEqual(statuses[currmiv].itemField.Id,             statuses2[currmiv].itemField.Id);
                Assert.AreEqual(statuses[currmiv].itemField.IdSpecified,    statuses2[currmiv].itemField.IdSpecified);
                Assert.AreEqual(statuses[currmiv].errorCodeField,           statuses2[currmiv].errorCodeField);
                Assert.AreEqual(statuses[currmiv].errorCodeFieldSpecified,  statuses2[currmiv].errorCodeFieldSpecified);
            }
        }
        // legend:
        //  [something physical to be stored in buffer]  (something to be translated to/from the byte array)
        //  <<description of item>> (no physical storaged.. just to make reading the structure easier!)
        // 
        // overall layout of byte buffer:
        //
        //  [unsigned int number_of_elements ]
        //  [element]
        //  [element]
        //  ...
        //
        // element = 
        //  <<ItemIdentity>>
        //      [ushort typeField]
        //      [ushort referenceTypeField]
        //      <<embedded ary>>
        //          [unsigned int namefield_length]
        //          [bytes nameField_strdata 0..n]
        //      <<embedded ary>>
        //          [unsigned int contextNameField_length]
        //          [bytes contextNameField_strdata 0..n]
        //      [ulong idField]
        //      [bool idFieldSpecified]
        // 
        //  <<simple variables>>
        //  
        //      [ushort errorCodeField]
        //      [bool errorCodeFieldSpecified]

        public byte[] ConvertItemStatusToBytes(ItemStatus[] theStatuses)
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            System.IO.BinaryWriter bw = new System.IO.BinaryWriter(ms);
            byte[] retval = null;

            if (theStatuses != null)
            {
                if (theStatuses.Length > 0)
                {
                    //try
                    //{ 

                    //  [unsigned int number_of_elements ]
                    bw.Write((uint)theStatuses.Length);
                    uint statusesLen = (uint)theStatuses.Length;

                    for (uint currOfst = 0;
                         currOfst < statusesLen;
                         currOfst++)
                    {
                        //  <<ItemIdentity>>
                        ConvertItemIdentityToBytes(ref theStatuses[currOfst].itemField, bw);

                        //      [ushort errorCodeField]
                        bw.Write(theStatuses[currOfst].errorCodeField);
                        //      [bool errorCodeFieldSpecified]
                        bw.Write(theStatuses[currOfst].errorCodeFieldSpecified);
                    }
                    retval = ms.ToArray();

                    //}
                    //catch (Exception e)
                    //{
                    //    // TODO RJK use real logging here..
                    //    Console.WriteLine("{0}", e.StackTrace);
                    //}
                }
            }
            return retval;

        }