private void GetDAItemIDsMI_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (typeof(Condition).IsInstanceOfType(BrowseTV.SelectedNode.Tag))
                {
                    OpcClientSdk.Ae.TsCAeBrowseElement source = (OpcClientSdk.Ae.TsCAeBrowseElement)BrowseTV.SelectedNode.Parent.Tag;
                    Condition condition = (Condition)BrowseTV.SelectedNode.Tag;

                    new ItemIDsViewDlg().ShowDialog(m_server, source.QualifiedName, condition.Name, null);
                }

                if (typeof(string).IsInstanceOfType(BrowseTV.SelectedNode.Tag))
                {
                    OpcClientSdk.Ae.TsCAeBrowseElement source = (OpcClientSdk.Ae.TsCAeBrowseElement)BrowseTV.SelectedNode.Parent.Parent.Tag;
                    Condition condition    = (Condition)BrowseTV.SelectedNode.Parent.Tag;
                    string    subcondition = (string)BrowseTV.SelectedNode.Tag;

                    new ItemIDsViewDlg().ShowDialog(m_server, source.QualifiedName, condition.Name, subcondition);
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
        /// <summary>
        /// Gets the current state for the selected condition.
        /// </summary>
        private void GetConditionStateMI_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (typeof(Condition).IsInstanceOfType(BrowseTV.SelectedNode.Tag))
                {
                    Condition condition = (Condition)BrowseTV.SelectedNode.Tag;
                    OpcClientSdk.Ae.TsCAeBrowseElement source = (OpcClientSdk.Ae.TsCAeBrowseElement)BrowseTV.SelectedNode.Parent.Tag;

                    new ConditionStateDlg().ShowDialog(m_server, source.QualifiedName, condition.Name);
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
        /// <summary>
        /// Populates the tree with the conditions for the source.
        /// </summary>
        private void BrowseSource(TreeNodeCollection nodes, OpcClientSdk.Ae.TsCAeBrowseElement source)
        {
            // fetch conditions.
            string[] conditions = m_server.QueryConditionNames(source.QualifiedName);

            // add conditions to tree.
            for (int ii = 0; ii < conditions.Length; ii++)
            {
                // create node.
                TreeNode node = new TreeNode(conditions[ii]);

                node.ImageIndex         = Resources.IMAGE_EXPLODING_BOX;
                node.SelectedImageIndex = Resources.IMAGE_EXPLODING_BOX;
                node.Tag = new Condition(conditions[ii]);

                // add dummy child to ensure '+' sign is visible.
                node.Nodes.Add(new TreeNode());

                // add to tree.
                nodes.Add(node);
            }
        }
        /// <summary>
        /// Fetches the children for the specified node.
        /// </summary>
        private void FetchChildren(TreeNode node)
        {
            // check for element.
            if (typeof(OpcClientSdk.Ae.TsCAeBrowseElement).IsInstanceOfType(node.Tag))
            {
                // get the element.
                OpcClientSdk.Ae.TsCAeBrowseElement element = (OpcClientSdk.Ae.TsCAeBrowseElement)node.Tag;

                node.Nodes.Clear();

                // browse area.
                if (element.NodeType == OpcClientSdk.Ae.TsCAeBrowseType.Area)
                {
                    BrowseArea(node.Nodes, OpcClientSdk.Ae.TsCAeBrowseType.Area, element);
                    BrowseArea(node.Nodes, OpcClientSdk.Ae.TsCAeBrowseType.Source, element);
                }

                // browse source
                else
                {
                    BrowseSource(node.Nodes, element);
                }
            }

            // check for category.
            else if (typeof(OpcClientSdk.Ae.TsCAeCategory).IsInstanceOfType(node.Tag))
            {
                node.Nodes.Clear();
                BrowseCategory(node.Nodes, (OpcClientSdk.Ae.TsCAeCategory)node.Tag);
            }

            // check for conditions.
            else if (typeof(Condition).IsInstanceOfType(node.Tag))
            {
                node.Nodes.Clear();
                BrowseCondition(node.Nodes, (Condition)node.Tag);
            }
        }
        /// <summary>
        /// Enables condition based notifications for the area or source.
        /// </summary>
        private void SetEnabledStateMI_Click(object sender, System.EventArgs e)
        {
            try
            {
                // find current selection.
                OpcClientSdk.Ae.TsCAeBrowseElement selection = null;

                if (typeof(OpcClientSdk.Ae.TsCAeBrowseElement).IsInstanceOfType(BrowseTV.SelectedNode.Tag))
                {
                    selection = (OpcClientSdk.Ae.TsCAeBrowseElement)BrowseTV.SelectedNode.Tag;
                }
                else if (!typeof(TsCAeServer).IsInstanceOfType(BrowseTV.SelectedNode.Tag))
                {
                    return;
                }

                // prompt user.
                bool enabled = false;

                bool result = new SetEnabledStateDlg().ShowDialog(
                    m_server,
                    selection,
                    out enabled,
                    ref m_recursive);

                if (!result)
                {
                    return;
                }

                // apply changes.
                ArrayList elements = new ArrayList();

                if (m_recursive)
                {
                    FindBrowseElements(BrowseTV.SelectedNode, elements);
                }
                else
                {
                    elements.Add(selection);
                }

                // seperate into areas and sources.
                ArrayList areas   = new ArrayList();
                ArrayList sources = new ArrayList();

                foreach (OpcClientSdk.Ae.TsCAeBrowseElement element in elements)
                {
                    if (element.NodeType == OpcClientSdk.Ae.TsCAeBrowseType.Area)
                    {
                        areas.Add(element.QualifiedName);
                    }
                    else
                    {
                        sources.Add(element.QualifiedName);
                    }
                }

                // call server.
                if (enabled)
                {
                    m_server.EnableConditionByArea((string[])areas.ToArray(typeof(string)));
                    m_server.EnableConditionBySource((string[])sources.ToArray(typeof(string)));
                }
                else
                {
                    m_server.DisableConditionByArea((string[])areas.ToArray(typeof(string)));
                    m_server.DisableConditionBySource((string[])sources.ToArray(typeof(string)));
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
        /// <summary>
        /// Populates the tree with the elements within the specified area.
        /// </summary>
        private void BrowseArea(TreeNodeCollection nodes, OpcClientSdk.Ae.TsCAeBrowseType browseType, OpcClientSdk.Ae.TsCAeBrowseElement area)
        {
            IOpcBrowsePosition position = null;

            try
            {
                // fetch first batch of elements.
                OpcClientSdk.Ae.TsCAeBrowseElement[] elements = m_server.Browse(
                    (area != null) ? area.QualifiedName : null,
                    browseType,
                    m_browseFilter,
                    m_maxElements,
                    out position);


                do
                {
                    // add elements to tree.
                    for (int ii = 0; ii < elements.Length; ii++)
                    {
                        // create node.
                        TreeNode node = new TreeNode(elements[ii].Name);

                        node.ImageIndex         = (browseType == OpcClientSdk.Ae.TsCAeBrowseType.Area)?Resources.IMAGE_CLOSED_BLUE_FOLDER:Resources.IMAGE_GREEN_SCROLL;
                        node.SelectedImageIndex = (browseType == OpcClientSdk.Ae.TsCAeBrowseType.Area)?Resources.IMAGE_OPEN_BLUE_FOLDER:Resources.IMAGE_GREEN_SCROLL;
                        node.Tag = elements[ii];

                        // add dummy child to ensure '+' sign is visible.
                        node.Nodes.Add(new TreeNode());

                        // add to tree.
                        nodes.Add(node);
                    }

                    // check if browse is complete.
                    if (position == null)
                    {
                        break;
                    }

                    // prompt to continue browse.
                    DialogResult result = MessageBox.Show(
                        "More elements meeting search criteria exist. Continue browse?",
                        "Browse " + browseType + "s",
                        MessageBoxButtons.YesNo);

                    if (result == DialogResult.No)
                    {
                        break;
                    }

                    // continue browse.
                    elements = m_server.BrowseNext(m_maxElements, ref position);
                }while (true);
            }
            finally
            {
                // dipose position object on exit.
                if (position != null)
                {
                    position.Dispose();
                    position = null;
                }
            }
        }