Browses areas and sources in the AE server.
Inheritance: ComObject
        /// <summary>
        /// Initializes the next stage of browsing.
        /// </summary>
        private void NextStage()
        {
            ComHdaClientManager system = (ComHdaClientManager)this.SystemContext.SystemHandle;
            ComHdaClient client = (ComHdaClient)system.SelectClient((ServerSystemContext)SystemContext, false);

            // determine which stage is next based on the reference types requested.
            for (Stage next = m_stage+1; next <= Stage.Done; next++)
            {
                if (next == Stage.Browse)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Children)
                {
                    if (IsRequired(ReferenceTypeIds.HasProperty, false) || IsRequired(ReferenceTypeIds.HasHistoricalConfiguration, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Parents)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, true) || IsRequired(ReferenceTypeIds.HasHistoricalConfiguration, true))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Done)
                {
                    m_stage = next;
                    break;
                }
            }

            // start enumerating areas.
            if (m_stage == Stage.Browse)
            {
                m_browser = null;

                if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.FolderType)
                {
                    m_browser = new ComHdaBrowserClient(client, m_itemId);
                }

                return;
            }

            // start enumerating attributes.
            if (m_stage == Stage.Children)
            {
                m_position = 0;
                m_children = null;

                if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.FolderType)
                {
                    return;
                }

                List<BaseInstanceState> children = new List<BaseInstanceState>();

                // check if browsing aggregate functions.
                if (m_sourceBrowseName == Opc.Ua.BrowseNames.AggregateFunctions)
                {
                    if (IsRequired(ReferenceTypeIds.HasComponent, false))
                    {
                        BaseObjectState[] aggregates = client.GetSupportedAggregates(m_namespaceIndex);

                        if (aggregates != null)
                        {
                            children.AddRange(aggregates);
                        }

                        m_children = children.ToArray();
                    }

                    return;
                }
                
                // must be browsing children of an item.
                HdaItem[] items = client.GetItems(m_itemId);
                
                if (items[0].Error < 0)
                {
                    return;
                }
                    
                try
                {
                    HdaAttributeValue[] attributes = client.ReadAvailableAttributes(items[0]);

                    if (m_sourceTypeDefinitionId == Opc.Ua.VariableTypeIds.DataItemType)
                    {
                        FindChildrenForHdaItem(client, children, attributes);
                    }

                    if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.HistoricalDataConfigurationType)
                    {
                        FindChildrenForHdaItemConfiguration(client, children, attributes);
                    }
                }
                finally
                {
                    client.ReleaseItemHandles(items);
                }

                m_children = children.ToArray();
                return;
            }

            // start enumerating parents.
            if (m_stage == Stage.Parents)
            {
                return;
            }

            // all done.
        }
        /// <summary>
        /// Verifies that the specified node exists.
        /// </summary>
        protected override NodeState ValidateNode(
            ServerSystemContext context,
            NodeHandle handle,
            IDictionary<NodeId, NodeState> cache)
        {
            // not valid if no root.
            if (handle == null)
            {
                return null;
            }

            // check if previously validated.
            if (handle.Validated)
            {
                return handle.Node;
            }

            NodeState target = null;

            // check if already in the cache.
            if (cache != null)
            {
                if (cache.TryGetValue(handle.NodeId, out target))
                {
                    // nulls mean a NodeId which was previously found to be invalid has been referenced again.
                    if (target == null)
                    {
                        return null;
                    }

                    handle.Node = target;
                    handle.Validated = true;
                    return handle.Node;
                }

                target = null;
            }

            try
            {
                // check if the node id has been parsed.
                HdaParsedNodeId parsedNodeId = handle.ParsedNodeId as HdaParsedNodeId;

                if (parsedNodeId == null)
                {
                    return null;
                }

                ComHdaClient client = (ComHdaClient)m_system.SelectClient(context, false);

                switch (parsedNodeId.RootType)
                {
                    case HdaModelUtils.HdaBranch:
                    {
                        ComHdaBrowserClient browser = new ComHdaBrowserClient(client, null);
                        target = browser.FindBranch(context, parsedNodeId.RootId, NamespaceIndex);
                        browser.Dispose();
                        break;
                    }

                    case HdaModelUtils.HdaItem:
                    {
                        HdaItem[] items = client.GetItems(parsedNodeId.RootId);

                        if (items[0].Error < 0)
                        {
                            return null;
                        }

                        try
                        {
                            string browseName = null;

                            if (!m_configuration.ItemIdParser.Parse(client, m_configuration, parsedNodeId.RootId, out browseName))
                            {
                                HdaAttributeValue[] attributes = client.ReadAttributeValues(items[0].ServerHandle, OpcRcw.Hda.Constants.OPCHDA_ITEMID);
                                browseName = attributes[0].Value as string;
                            }

                            target = new HdaItemState(items[0].ItemId, browseName, NamespaceIndex);
                        }
                        finally
                        {
                            client.ReleaseItemHandles(items);
                        }

                        break;
                    }

                    case HdaModelUtils.HdaItemAttribute:
                    {
                        bool[] results = client.ValidateItemIds(parsedNodeId.RootId);

                        if (!results[0])
                        {
                            return null;
                        }

                        target = client.FindItemAttribute(parsedNodeId.RootId, parsedNodeId.AttributeId, NamespaceIndex);
                        break;
                    }

                    case HdaModelUtils.HdaItemAnnotations:
                    {
                        bool[] results = client.ValidateItemIds(parsedNodeId.RootId);

                        if (!results[0])
                        {
                            return null;
                        }

                        target = client.FindItemAnnotations(parsedNodeId.RootId, NamespaceIndex);
                        break;
                    }

                    case HdaModelUtils.HdaItemConfiguration:
                    {
                        bool[] results = client.ValidateItemIds(parsedNodeId.RootId);

                        if (results == null || !results[0])
                        {
                            return null;
                        }

                        target = HdaModelUtils.GetItemConfigurationNode(parsedNodeId.RootId, NamespaceIndex);
                        target.OnCreateBrowser = OnCreateItemConfigurationBrowser;
                        break;
                    }

                    case HdaModelUtils.HdaAggregate:
                    {
                        target = client.FindAggregate(parsedNodeId.AggregateId, NamespaceIndex);
                        break;
                    }
                }

                // check if found.
                if (target == null)
                {
                    return null;
                }

                // found a valid component.
                handle.Validated = true;
                handle.Node = target;

                return handle.Node;
            }
            finally
            {
                // store the node in the cache to optimize subsequent lookups.
                if (cache != null)
                {
                    cache.Add(handle.NodeId, target);
                }
            }
        }
        /// <summary>
        /// Initializes the next stage of browsing.
        /// </summary>
        private void NextStage()
        {
            ComHdaClientManager system = (ComHdaClientManager)this.SystemContext.SystemHandle;
            ComHdaClient        client = (ComHdaClient)system.SelectClient((ServerSystemContext)SystemContext, false);

            // determine which stage is next based on the reference types requested.
            for (Stage next = m_stage + 1; next <= Stage.Done; next++)
            {
                if (next == Stage.Browse)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Children)
                {
                    if (IsRequired(ReferenceTypeIds.HasProperty, false) || IsRequired(ReferenceTypeIds.HasHistoricalConfiguration, false))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Parents)
                {
                    if (IsRequired(ReferenceTypeIds.Organizes, true) || IsRequired(ReferenceTypeIds.HasHistoricalConfiguration, true))
                    {
                        m_stage = next;
                        break;
                    }
                }

                else if (next == Stage.Done)
                {
                    m_stage = next;
                    break;
                }
            }

            // start enumerating areas.
            if (m_stage == Stage.Browse)
            {
                m_browser = null;

                if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.FolderType)
                {
                    m_browser = new ComHdaBrowserClient(client, m_itemId);
                }

                return;
            }

            // start enumerating attributes.
            if (m_stage == Stage.Children)
            {
                m_position = 0;
                m_children = null;

                if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.FolderType)
                {
                    return;
                }

                List <BaseInstanceState> children = new List <BaseInstanceState>();

                // check if browsing aggregate functions.
                if (m_sourceBrowseName == Opc.Ua.BrowseNames.AggregateFunctions)
                {
                    if (IsRequired(ReferenceTypeIds.HasComponent, false))
                    {
                        BaseObjectState[] aggregates = client.GetSupportedAggregates(m_namespaceIndex);

                        if (aggregates != null)
                        {
                            children.AddRange(aggregates);
                        }

                        m_children = children.ToArray();
                    }

                    return;
                }

                // must be browsing children of an item.
                HdaItem[] items = client.GetItems(m_itemId);

                if (items[0].Error < 0)
                {
                    return;
                }

                try
                {
                    HdaAttributeValue[] attributes = client.ReadAvailableAttributes(items[0]);

                    if (m_sourceTypeDefinitionId == Opc.Ua.VariableTypeIds.DataItemType)
                    {
                        FindChildrenForHdaItem(client, children, attributes);
                    }

                    if (m_sourceTypeDefinitionId == Opc.Ua.ObjectTypeIds.HistoricalDataConfigurationType)
                    {
                        FindChildrenForHdaItemConfiguration(client, children, attributes);
                    }
                }
                finally
                {
                    client.ReleaseItemHandles(items);
                }

                m_children = children.ToArray();
                return;
            }

            // start enumerating parents.
            if (m_stage == Stage.Parents)
            {
                return;
            }

            // all done.
        }