/// <summary>
 /// Creates a new browser object with a set of filters.
 /// </summary>
 /// <param name="context">The system context to use.</param>
 /// <param name="view">The view which may restrict the set of references/nodes found.</param>
 /// <param name="referenceType">The type of references being followed.</param>
 /// <param name="includeSubtypes">Whether subtypes of the reference type are followed.</param>
 /// <param name="browseDirection">Which way the references are being followed.</param>
 /// <param name="browseName">The browse name of a specific target (used when translating browse paths).</param>
 /// <param name="additionalReferences">Any additional references that should be included.</param>
 /// <param name="internalOnly">If true the browser should not making blocking calls to external systems.</param>
 /// <param name="source">The segment being accessed.</param>
 public ArchiveFolderBrowser(
     ISystemContext context,
     ViewDescription view,
     NodeId referenceType,
     bool includeSubtypes,
     BrowseDirection browseDirection,
     QualifiedName browseName,
     IEnumerable <IReference> additionalReferences,
     bool internalOnly,
     ArchiveFolderState source)
     :
     base(
         context,
         view,
         referenceType,
         includeSubtypes,
         browseDirection,
         browseName,
         additionalReferences,
         internalOnly)
 {
     _source = source;
     _stage  = Stage.Begin;
 }
        /// <summary>
        /// Returns the next child.
        /// </summary>
        private IReference NextChild()
        {
            var system = (UnderlyingSystem)SystemContext.SystemHandle;

            NodeId targetId = null;

            // check if a specific browse name is requested.
            if (!QualifiedName.IsNull(BrowseName))
            {
                // check if match found previously.
                if (_position == int.MaxValue)
                {
                    return(null);
                }

                // browse name must be qualified by the correct namespace.
                if (_source.BrowseName.NamespaceIndex != BrowseName.NamespaceIndex)
                {
                    return(null);
                }

                // look for matching folder.
                if (_stage == Stage.Folders && _folders != null)
                {
                    for (var ii = 0; ii < _folders.Length; ii++)
                    {
                        if (BrowseName.Name == _folders[ii].Name)
                        {
                            targetId = ArchiveFolderState.ConstructId(_folders[ii].UniquePath, _source.NodeId.NamespaceIndex);
                            break;
                        }
                    }
                }

                // look for matching item.
                else if (_stage == Stage.Items && _items != null)
                {
                    for (var ii = 0; ii < _items.Length; ii++)
                    {
                        if (BrowseName.Name == _items[ii].Name)
                        {
                            targetId = ArchiveItemState.ConstructId(_items[ii].UniquePath, _source.NodeId.NamespaceIndex);
                            break;
                        }
                    }
                }

                // look for matching parent.
                else if (_stage == Stage.Parents)
                {
                    var parent = _source.ArchiveFolder.GetParentFolder();

                    if (BrowseName.Name == parent.Name)
                    {
                        targetId = ArchiveFolderState.ConstructId(parent.UniquePath, _source.NodeId.NamespaceIndex);
                    }
                }

                _position = int.MaxValue;
            }

            // return the child at the next position.
            else
            {
                // look for next folder.
                if (_stage == Stage.Folders && _folders != null)
                {
                    if (_position >= _folders.Length)
                    {
                        return(null);
                    }

                    targetId = ArchiveFolderState.ConstructId(_folders[_position++].UniquePath, _source.NodeId.NamespaceIndex);
                }

                // look for next item.
                else if (_stage == Stage.Items && _items != null)
                {
                    if (_position >= _items.Length)
                    {
                        return(null);
                    }

                    targetId = ArchiveItemState.ConstructId(_items[_position++].UniquePath, _source.NodeId.NamespaceIndex);
                }

                // look for matching parent.
                else if (_stage == Stage.Parents)
                {
                    var parent = _source.ArchiveFolder.GetParentFolder();

                    if (parent != null)
                    {
                        targetId = ArchiveFolderState.ConstructId(parent.UniquePath, _source.NodeId.NamespaceIndex);
                    }
                }
            }

            // create reference.
            if (targetId != null)
            {
                return(new NodeStateReference(ReferenceTypeIds.Organizes, false, targetId));
            }

            return(null);
        }