void LoadDataSourceAccessRules(ISystemContext context, ToolState tool, DsatsDemo.DataSource.DeclarationType declaration)
        {
            if (declaration == null || declaration.AccessRules == null)
            {
                return;
            }

            BaseInstanceState folder = tool.FindChildBySymbolicName(context, DsatsDemo.BrowseNames.AccessRules);

            if (folder == null)
            {
                return;
            }

            foreach (DsatsDemo.DataSource.AccessRuleType rule in declaration.AccessRules)
            {
                NodeId phaseId = new NodeId("Phases/" + rule.Phase, NamespaceIndex);
                NodeId lockId  = new NodeId("Locks/" + rule.Lock, NamespaceIndex);

                AccessRuleState node = new AccessRuleState(null);
                node.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasComponent;

                node.Create(
                    context,
                    new NodeId(declaration.Path + "/" + declaration.BrowseName + "/AccessRules/" + rule.Phase, NamespaceIndex),
                    new QualifiedName(rule.Phase, NamespaceIndex),
                    null,
                    true);

                node.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, true, folder.NodeId);
                folder.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, false, node.NodeId);

                AddPredefinedNode(context, node);

                NodeState target = FindPredefinedNode(phaseId, typeof(NodeState));

                if (target != null)
                {
                    NodeId referenceTypeId = new NodeId(DsatsDemo.ReferenceTypes.HasPhase, NamespaceIndex);
                    node.AddReference(referenceTypeId, false, target.NodeId);
                    target.AddReference(referenceTypeId, true, node.NodeId);
                }

                target = (DsatsDemo.LockConditionState)FindPredefinedNode(lockId, typeof(DsatsDemo.LockConditionState));

                if (target != null)
                {
                    NodeId referenceTypeId = new NodeId(DsatsDemo.ReferenceTypes.HasLock, NamespaceIndex);
                    node.AddReference(referenceTypeId, false, target.NodeId);
                    target.AddReference(referenceTypeId, true, node.NodeId);
                }

                tool.SetPhaseLock(phaseId, lockId);
            }
        }
        void LoadDataSourceDeclarations(ISystemContext context, DsatsDemo.DataSource.DataSource datasource)
        {
            if (datasource == null || datasource.Declaration == null)
            {
                return;
            }

            m_tools = new List <ToolState>();

            foreach (DsatsDemo.DataSource.DeclarationType declaration in datasource.Declaration)
            {
                BaseInstanceState parent = m_rig;

                if (!String.IsNullOrEmpty(declaration.Path))
                {
                    parent = m_rig.FindChildBySymbolicName(context, declaration.Path);
                }

                if (parent == null)
                {
                    Utils.Trace("Skipping declaration with unknown parent. {0}", declaration.Path);
                    continue;
                }

                NodeId            typeDefinitionId = datasource.ReadNodeId(context, declaration.TypeDefinitionId);
                BaseInstanceState child            = parent.FindChildBySymbolicName(context, declaration.BrowseName);

                if (child == null)
                {
                    uint?id = typeDefinitionId.Identifier as uint?;

                    if (id != null)
                    {
                        switch (id.Value)
                        {
                        case DsatsDemo.ObjectTypes.MudPumpType:
                        {
                            child = new MudPumpState(null);
                            break;
                        }
                        }

                        child.Create(
                            context,
                            new NodeId(declaration.Path + "/" + declaration.BrowseName, NamespaceIndex),
                            new QualifiedName(declaration.BrowseName, NamespaceIndex),
                            null,
                            true);

                        child.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, true, parent.NodeId);
                        parent.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, false, child.NodeId);

                        AddPredefinedNode(context, child);
                    }
                }

                ToolState tool = child as ToolState;

                if (tool != null)
                {
                    LoadDataSourceAccessRules(context, tool, declaration);
                    LoadDataSourceSources(context, tool, datasource, declaration);
                }

                m_tools.Add(tool);
            }
        }