/// <summary>
        /// Adds an item to the list view.
        /// </summary>
        private void AddValue(object subscriptionHandle, TsCDaItemValueResult item, ref ListViewItem replaceableItem)
        {
            string quality = "";

            // format quality.
            if (item.QualitySpecified)
            {
                quality += item.Quality.QualityBits.ToString();

                if (item.Quality.LimitBits != TsDaLimitBits.None)
                {
                    quality += ", ";
                    quality += item.Quality.LimitBits.ToString();
                }

                if (item.Quality.VendorBits != 0)
                {
                    quality += String.Format(", {0:X}", item.Quality.VendorBits);
                }
            }

            // format columns.
            string[] columns = new string[]
            {
                item.ItemName,
                item.ItemPath,
                OpcClientSdk.OpcConvert.ToString(item.Value),
                (item.Value != null)?OpcClientSdk.OpcConvert.ToString(item.Value.GetType()):"",
                quality,
                (item.TimestampSpecified)?OpcClientSdk.OpcConvert.ToString(item.Timestamp):"",
                GetErrorText(subscriptionHandle, item.Result)
            };

            // update an existing item.
            if (replaceableItem != null)
            {
                for (int ii = 0; ii < replaceableItem.SubItems.Count; ii++)
                {
                    replaceableItem.SubItems[ii].Text = columns[ii];
                }

                replaceableItem.Tag       = item;
                replaceableItem.ForeColor = Color.Empty;

                // update detail view dialog.
                EditComplexValueDlg dialog = (EditComplexValueDlg)m_viewers[replaceableItem];

                if (dialog != null)
                {
                    dialog.UpdateValue(item.Value);
                }

                return;
            }

            // create a new list view item.
            replaceableItem     = new ListViewItem(columns, Resources.IMAGE_YELLOW_SCROLL);
            replaceableItem.Tag = item;

            // insert after any existing item value with the same client handle.
            for (int ii = ItemListLV.Items.Count - 1; ii >= 0; ii--)
            {
                TsCDaItemValueResult previous = (TsCDaItemValueResult)ItemListLV.Items[ii].Tag;

                if (previous.ClientHandle != null && previous.ClientHandle.Equals(item.ClientHandle))
                {
                    ItemListLV.Items.Insert(ii + 1, replaceableItem);
                    return;
                }
            }

            ItemListLV.Items.Add(replaceableItem);
        }