/// <summary>
        /// Process a new node.
        /// </summary>
        /// <param name="nodeElement">The node element.</param>
        /// <param name="opcParentItem">The opc parent item.</param>
        /// <returns>
        /// The <see cref="OpcItem"/>.
        /// </returns>
        private static OpcItem ProcessNode(DANodeElement nodeElement, OpcItem opcParentItem)
        {
            var opcItem = new OpcItem(true)
            {
                Name = nodeElement.Name
            };

            // We mark with a valid ItemId only the items that can be read, written or subscribed.
            if (!string.IsNullOrEmpty(nodeElement.ItemId) && nodeElement.IsItem)
            {
                opcItem.ItemId = nodeElement.ItemId;
            }

            opcParentItem.Children.Add(opcItem);
            return(opcItem);
        }
            public static void DataTypes()
            {
                var easyDAClient = new EasyDAClient();

                // Define the list of data types we will be checking for.
                // Change as needed for your application.
                // This technique is only usable if there is a known list of
                // data types you are interested in. If you are interested in
                // all leaves, even those that are of data types not explicitly
                // listed, always include VarTypes.Empty as the first data type.
                // The leaves of "unlisted" data types will have VarTypes.Empty
                // associated with them.
                var dataTypes = new VarType[] { VarTypes.Empty, VarTypes.I2, VarTypes.R4 };

                // For each leaf found, this dictionary wil hold its associated data type.
                var dataTypeDictionary = new Dictionary <DANodeElement, VarType>();

                // For each data type, browse for leaves of this data type.
                foreach (VarType dataType in dataTypes)
                {
                    var browseParameters = new DABrowseParameters(DABrowseFilter.Leaves, "", "", dataType);
                    DANodeElementCollection nodeElements =
                        easyDAClient.BrowseNodes("", "AutoJet.ACPFileServerDA.1", "Cttmt2008", browseParameters);

                    // Store the leaf information into the dictionary, and
                    // associate the current data type with it.
                    foreach (var nodeElement in nodeElements)
                    {
                        dataTypeDictionary[nodeElement] = dataType;
                    }
                }

                // Display each leaf found, and its associated data type.
                foreach (KeyValuePair <DANodeElement, VarType> pair in dataTypeDictionary)
                {
                    DANodeElement nodeElement = pair.Key;
                    VarType       dataType    = pair.Value;
                    Console.WriteLine("{0}: {1}", nodeElement, dataType);
                }
            }
        /// <summary>
        /// Browse recursively the address space of an OPC server.
        /// </summary>
        /// <param name="opc">The opc client.</param>
        /// <param name="serverDescriptor">The server descriptor.</param>
        /// <param name="nodeElement">The node element.</param>
        /// <param name="opcParentItem">The opc parent item.</param>
        private void BrowseRecursive(EasyDAClient opc, ServerDescriptor serverDescriptor, DANodeElement nodeElement, OpcItem opcParentItem)
        {
            if (nodeElement == null)
            {
                var branches = opc.BrowseBranches(serverDescriptor);
                var leaves   = opc.BrowseLeaves(serverDescriptor);

                foreach (var branch in branches)
                {
                    this.BrowseRecursive(opc, serverDescriptor, branch, opcParentItem);
                }

                foreach (var leaf in leaves)
                {
                    this.BrowseRecursive(opc, serverDescriptor, leaf, opcParentItem);
                }
            }
            else
            {
                // A node element is processed only here.
                var newOpcItem = ProcessNode(nodeElement, opcParentItem);

                // Go on recursively if the node element has children.
                if (nodeElement.HasChildren)
                {
                    var nodeDescriptor = new DANodeDescriptor(nodeElement);
                    var branches       = opc.BrowseBranches(serverDescriptor, nodeDescriptor);
                    var leaves         = opc.BrowseLeaves(serverDescriptor, nodeDescriptor);

                    foreach (var branch in branches)
                    {
                        this.BrowseRecursive(opc, serverDescriptor, branch, newOpcItem);
                    }

                    foreach (var leaf in leaves)
                    {
                        this.BrowseRecursive(opc, serverDescriptor, leaf, newOpcItem);
                    }
                }
            }
        }