/// <summary>
        /// Edits items in the specified subscription.
        /// </summary>
        private void EditItem(TreeNode node, TsCDaSubscription subscription, TsCDaItem item)
        {
            try
            {
                // save existing item id.
                OpcItem itemId = new OpcItem(item);

                TsCDaItem[] items = new ItemListEditDlg().ShowDialog(new TsCDaItem[] { item }, false, false);

                if (items == null)
                {
                    return;
                }

                // modify an existing item.
                if (itemId.Key == items[0].Key)
                {
                    subscription.ModifyItems((int)TsCDaStateMask.All, items);
                }

                // add/remove item because the item id changed.
                else
                {
                    items = subscription.AddItems(items);
                    subscription.RemoveItems(new OpcItem[] { itemId });
                }

                node.Text = items[0].ItemName;
                node.Tag  = items[0];
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        /// <summary>
        /// Toggles the active state of a subscription.
        /// </summary>
        private void SetActive(TreeNode node, TsCDaSubscription subscription, TsCDaItem item, bool active)
        {
            try
            {
                item.Active          = active;
                item.ActiveSpecified = true;

                TsCDaItem[] items = subscription.ModifyItems((int)TsCDaStateMask.Active, new TsCDaItem[] { item });

                if (items != null)
                {
                    node.Tag = items[0];
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        /// <summary>
        /// Edits items in the specified subscription.
        /// </summary>
        private void EditItems(TreeNode node, TsCDaSubscription subscription)
        {
            try
            {
                // save item ids to detect item id changes.
                OpcItem[] itemIDs = new OpcItem[subscription.Items.Length];

                for (int ii = 0; ii < itemIDs.Length; ii++)
                {
                    itemIDs[ii] = new OpcItem(subscription.Items[ii]);
                }

                // edit the items.
                TsCDaItem[] items = new ItemListEditDlg().ShowDialog(subscription.Items, false, false);

                if (items == null)
                {
                    return;
                }

                // separate the items in lists depending on whether item id changed.
                ArrayList insertItems = new ArrayList();
                ArrayList updateItems = new ArrayList();
                ArrayList deleteItems = new ArrayList();

                for (int ii = 0; ii < itemIDs.Length; ii++)
                {
                    if (items[ii].Key != itemIDs[ii].Key)
                    {
                        insertItems.Add(items[ii]);
                        deleteItems.Add(itemIDs[ii]);
                    }
                    else
                    {
                        updateItems.Add(items[ii]);
                    }
                }

                // update existing items.
                if (updateItems.Count > 0)
                {
                    subscription.ModifyItems((int)TsCDaStateMask.All, (TsCDaItem[])updateItems.ToArray(typeof(TsCDaItem)));
                }

                // insert new items.
                if (insertItems.Count > 0)
                {
                    subscription.AddItems((TsCDaItem[])insertItems.ToArray(typeof(TsCDaItem)));
                }

                // delete old items.
                if (deleteItems.Count > 0)
                {
                    subscription.RemoveItems((OpcItem[])deleteItems.ToArray(typeof(OpcItem)));
                }

                // update tree.
                node.Nodes.Clear();

                foreach (TsCDaItem item in subscription.Items)
                {
                    AddItem(node, item);
                }

                node.Expand();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }