/// <summary>
        /// ANalize the Master Detail controller and creates the suitable nodes
        /// </summary>
        /// <param name="masterDetailController"></param>
        /// <param name="showDetailsGroupingNode"></param>
        private void InitializeMasterDetailNode(IUMasterDetailController masterDetailController, bool showDetailsGroupingNode)
        {
            // Keep the Master information.
            QueryContext = masterDetailController.Master.Context;
            // Initialize the DisplaySet information.
            mDisplaySetInfo = new DisplaySetInformation(masterDetailController.Master.DisplaySet.DisplaySetList[0].Name);
            // It has to be considered only the items that the agent is able to access.
            mDisplaySetInfo.DisplaySetItems   = masterDetailController.Master.DisplaySet.DisplaySetList[0].GetVisibleDisplaySetItems(Logic.Agent.ClassName);
            QueryContext.DisplaySetAttributes = mDisplaySetInfo.GetDisplaySetItemsAsString();
            Alias      = CultureManager.TranslateString(masterDetailController.IdXMLDetailAlias, masterDetailController.DetailAlias);
            Action     = masterDetailController.Master.Action;
            Navigation = masterDetailController.Master.Navigation;
            masterDetailController.Master.Action     = null;
            masterDetailController.Master.Navigation = null;
            IUPopulationController lPopController = masterDetailController.Master as IUPopulationController;

            if (lPopController != null)
            {
                foreach (IUFilterController lFilter in lPopController.Filters)
                {
                    Filters.Add(lFilter);
                }
                lPopController.Filters.Clear();
            }

            // Analize every detail properties
            #region Details sub-nodes creation
            int nodeCounter             = 0;
            TreeNodeController lSubNode = null;

            // Process all the Master-Detail details, in order to create the suitable sub-nodes.
            foreach (IDetailController lDetail in masterDetailController.Details)
            {
                bool lShowInTree = CalculateShowInTree(lDetail);
                lSubNode = new TreeNodeController(NodeId, NodeId + "_" + nodeCounter.ToString(), lDetail, null, false, showDetailsGroupingNode, lShowInTree);
                mSubNodes.Add(lSubNode);
                // Suscribe subnode events
                lSubNode.RefreshRequired += new EventHandler <RefreshNodeRequiredEventArgs>(HandleSubNodeRefreshRequired);
                lSubNode.ContextRequired += new EventHandler <ContextRequiredEventArgs>(HandleSubNodeContextRequired);
                nodeCounter++;

                // Special situation. If this Detail won't be shown in the Tree
                //  assign the FinalNodeController. Only for the first one
                if (!lSubNode.ShowInTree && FinalNodeQueryController == null)
                {
                    FinalNodeID = lSubNode.NodeId;
                    FinalNodeQueryController  = lDetail;
                    lSubNode.ShowGroupingNode = false;
                }
            }
            #endregion Details sub-nodes creation

            // Empty the detail list
            masterDetailController.Details.Clear();
        }
 /// <summary>
 /// Initializes a new Tree node controller
 /// </summary>
 /// <param name="parentNodeId">Parent node identifier</param>
 /// <param name="id">Id</param>
 /// <param name="queryController">Detail Interface</param>
 /// <param name="instanceMasterController">Main Master Instance IU</param>
 /// <param name="isMainMaster">True if it is the Main Master</param>
 /// <param name="showGroupingNode">True if Grouping nodes must be shown</param>
 public TreeNodeController(string parentNodeId, string id, IDetailController queryController, IUInstanceController instanceMasterController, bool isMainMaster, bool showGroupingNode)
 {
     mRecursiveNodes  = new List <TreeNodeController>();
     Filters          = new FilterControllerList();
     mOriginalNode    = null;
     ParentNodeId     = parentNodeId;
     NodeId           = id;
     mIsMainMaster    = isMainMaster;
     ShowGroupingNode = showGroupingNode;
     ShowInTree       = CalculateShowInTree(queryController);
     FinalNodeID      = NodeId;
     InitializeNode(queryController);
 }
        /// <summary>
        /// Gets the tree node from a node identifier
        /// </summary>
        /// <param name="nodeId">Node identifier</param>
        /// <returns>A Tree node</returns>
        public TreeNodeController GetNodeById(string nodeId)
        {
            if (NodeId.Equals(nodeId))
            {
                return(this);
            }

            foreach (TreeNodeController node in SubNodes)
            {
                TreeNodeController lNode = node.GetNodeById(nodeId);
                if (lNode != null)
                {
                    return(lNode);
                }
            }

            return(null);
        }
        /// <summary>
        /// Copy constructor
        /// </summary>
        /// <param name="nodeToBeCopied"></param>
        /// <param name="newExchangeInfo"></param>
        public TreeNodeController(TreeNodeController nodeToBeCopied, ExchangeInfoNavigation newExchangeInfo)
        {
            mRecursiveNodes   = new List <TreeNodeController>();
            mParentNodeId     = nodeToBeCopied.ParentNodeId;
            mNodeId           = nodeToBeCopied.NodeId;
            mIsMainMaster     = false;
            mShowGroupingNode = nodeToBeCopied.ShowGroupingNode;
            Filters           = new FilterControllerList();
            mQueryContext     = new IUPopulationContext(newExchangeInfo, nodeToBeCopied.QueryContext.ClassName, "");
            mQueryContext.DisplaySetAttributes = nodeToBeCopied.QueryContext.DisplaySetAttributes;
            mOriginalNode = nodeToBeCopied;
            IUPopulationContext lPopContext = nodeToBeCopied.QueryContext as IUPopulationContext;

            if (lPopContext != null)
            {
                ((IUPopulationContext)QueryContext).BlockSize = lPopContext.BlockSize;
            }
            mShowInTree  = nodeToBeCopied.ShowInTree;
            mFinalNodeID = nodeToBeCopied.FinalNodeID;
        }
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="nodeToBeCopied"></param>
 /// <param name="newExchangeInfo"></param>
 public TreeNodeController(TreeNodeController nodeToBeCopied, ExchangeInfoNavigation newExchangeInfo)
 {
     mRecursiveNodes = new List<TreeNodeController>();
     mParentNodeId = nodeToBeCopied.ParentNodeId;
     mNodeId = nodeToBeCopied.NodeId;
     mIsMainMaster = false;
     mShowGroupingNode = nodeToBeCopied.ShowGroupingNode;
     Filters = new FilterControllerList();
     mQueryContext = new IUPopulationContext(newExchangeInfo, nodeToBeCopied.QueryContext.ClassName, "");
     mQueryContext.DisplaySetAttributes = nodeToBeCopied.QueryContext.DisplaySetAttributes;
     mOriginalNode = nodeToBeCopied;
     IUPopulationContext lPopContext = nodeToBeCopied.QueryContext as IUPopulationContext;
     if (lPopContext != null)
     {
         ((IUPopulationContext)QueryContext).BlockSize = lPopContext.BlockSize;
     }
     mShowInTree = nodeToBeCopied.ShowInTree;
     mFinalNodeID = nodeToBeCopied.FinalNodeID;
 }
        /// <summary>
        /// ANalize the Master Detail controller and creates the suitable nodes
        /// </summary>
        /// <param name="masterDetailController"></param>
        /// <param name="showDetailsGroupingNode"></param>
        private void InitializeMasterDetailNode(IUMasterDetailController masterDetailController, bool showDetailsGroupingNode)
        {
            // Keep the Master information.
            QueryContext = masterDetailController.Master.Context;
            // Initialize the DisplaySet information.
            mDisplaySetInfo = new DisplaySetInformation(masterDetailController.Master.DisplaySet.DisplaySetList[0].Name);
            // It has to be considered only the items that the agent is able to access.
            mDisplaySetInfo.DisplaySetItems = masterDetailController.Master.DisplaySet.DisplaySetList[0].GetVisibleDisplaySetItems(Logic.Agent.ClassName);
            QueryContext.DisplaySetAttributes = mDisplaySetInfo.GetDisplaySetItemsAsString();
            Alias = CultureManager.TranslateString(masterDetailController.IdXMLDetailAlias, masterDetailController.DetailAlias);
            Action = masterDetailController.Master.Action;
            Navigation = masterDetailController.Master.Navigation;
            masterDetailController.Master.Action = null;
            masterDetailController.Master.Navigation = null;
            IUPopulationController lPopController = masterDetailController.Master as IUPopulationController;
            if (lPopController != null)
            {
                foreach (IUFilterController lFilter in lPopController.Filters)
                {
                    Filters.Add(lFilter);
                }
                lPopController.Filters.Clear();
            }

            // Analize every detail properties
            #region Details sub-nodes creation
            int nodeCounter = 0;
            TreeNodeController lSubNode = null;

            // Process all the Master-Detail details, in order to create the suitable sub-nodes.
            foreach (IDetailController lDetail in masterDetailController.Details)
            {

                bool lShowInTree = CalculateShowInTree(lDetail);
                lSubNode = new TreeNodeController(NodeId, NodeId + "_" + nodeCounter.ToString(), lDetail, null, false, showDetailsGroupingNode, lShowInTree);
                mSubNodes.Add(lSubNode);
                // Suscribe subnode events
                lSubNode.RefreshRequired += new EventHandler<RefreshNodeRequiredEventArgs>(HandleSubNodeRefreshRequired);
                lSubNode.ContextRequired += new EventHandler<ContextRequiredEventArgs>(HandleSubNodeContextRequired);
                nodeCounter++;

                // Special situation. If this Detail won't be shown in the Tree
                //  assign the FinalNodeController. Only for the first one
                if (!lSubNode.ShowInTree && FinalNodeQueryController == null)
                {
                    FinalNodeID = lSubNode.NodeId;
                    FinalNodeQueryController = lDetail;
                    lSubNode.ShowGroupingNode = false;
                }
            }
            #endregion Details sub-nodes creation

            // Empty the detail list
            masterDetailController.Details.Clear();
        }
 /// <summary>
 /// Initializes a new Tree node controller
 /// </summary>
 /// <param name="parentNodeId">Parent node identifier</param>
 /// <param name="id">Id</param>
 /// <param name="queryController">Detail Interface</param>
 /// <param name="instanceMasterController">Main Master Instance IU</param>
 /// <param name="isMainMaster">True if it is the Main Master</param>
 /// <param name="showGroupingNode">True if Grouping nodes must be shown</param>
 public TreeNodeController(string parentNodeId, string id, IDetailController queryController, IUInstanceController instanceMasterController, bool isMainMaster, bool showGroupingNode)
 {
     mRecursiveNodes = new List<TreeNodeController>();
     Filters = new FilterControllerList();
     mOriginalNode = null;
     ParentNodeId = parentNodeId;
     NodeId = id;
     mIsMainMaster = isMainMaster;
     ShowGroupingNode = showGroupingNode;
     ShowInTree = CalculateShowInTree(queryController);
     FinalNodeID = NodeId;
     InitializeNode(queryController);
 }
        /// <summary>
        /// Converts the Master-Detail structure to Tree-Node structure
        /// </summary>
        /// <param name="masterDetailController"></param>
        private void ConvertMasterDetailInfo(IUMasterDetailController masterDetailController)
        {
            // Assign the Alias and the IdXML properties from the IUMasterDetailController controller.
            this.Alias = masterDetailController.Alias;
            this.IdXML = masterDetailController.IdXML;

            // Main Master controller
            TreeNodeController lRootNode = null;
            // If the Main Master is a Instance
            if (masterDetailController.Master.GetType().Name.Equals("IUInstanceController"))
            {
                int nodeCounter = 0;
                // If there is more than one detail, show the grouping node
                bool showGroupingNode = masterDetailController.Details.Count > 1;
                foreach (IDetailController detail in masterDetailController.Details)
                {
                    lRootNode = new TreeNodeController("", nodeCounter.ToString(), detail, (masterDetailController.Master as IUInstanceController), false, showGroupingNode);
                    RootNodes.Add(lRootNode);
                    lRootNode.RefreshRequired += new EventHandler<RefreshNodeRequiredEventArgs>(HandleRootNodeRefreshRequired);
                    lRootNode.ContextRequired += new EventHandler<ContextRequiredEventArgs>(HandleRootNodeContextRequired);
                    lRootNode.ExecuteFilter += new EventHandler<ExecuteFilterEventArgs>(HandleRootNodeExecuteFilter);
                    nodeCounter++;
                }

                // Assign the Instance Main Master
                InstanceMasterController = masterDetailController.Master as IUInstanceController;
            }
            else
            {
                // Main master is a population
                lRootNode = new TreeNodeController("", "0", masterDetailController, null, true, false,true);
                RootNodes.Add(lRootNode);
                masterDetailController.Details.Clear();
                lRootNode.RefreshRequired += new EventHandler<RefreshNodeRequiredEventArgs>(HandleRootNodeRefreshRequired);
                lRootNode.ContextRequired += new EventHandler<ContextRequiredEventArgs>(HandleRootNodeContextRequired);
                lRootNode.ExecuteFilter += new EventHandler<ExecuteFilterEventArgs>(HandleRootNodeExecuteFilter);
            }
            // Remove the existing details
            masterDetailController.Details.Clear();
        }
        /// <summary>
        /// Returns the context corresponding with the received path, staring in the received Node Controller
        /// </summary>
        /// <param name="completeOidPathList"></param>
        /// <returns></returns>
        private IUQueryContext GetQueryContextFromPath(TreeNodeController treeNodeController, List<KeyValuePair<string, Oid>> oidPathList)
        {
            // The first element in the list must correspond with the NodeId of one subnode or recursive node
            KeyValuePair<string, Oid> lPair = oidPathList[0];

            // Recursive node
            foreach (TreeNodeController lTreeNodeController in treeNodeController.RecursiveNodes)
            {
                if (lTreeNodeController.NodeId.Equals(lPair.Key))
                {
                    if (oidPathList.Count > 1)
                    {
                        oidPathList.RemoveAt(0);
                        return GetQueryContextFromPath(lTreeNodeController.OriginalNode, oidPathList);
                    }
                    else
                    {
                        return lTreeNodeController.QueryContext;
                    }
                }
            }

            // Standard node
            foreach (TreeNodeController lTreeNodeController in treeNodeController.SubNodes)
            {
                if (lTreeNodeController.NodeId.Equals(lPair.Key))
                {
                    if (oidPathList.Count > 1)
                    {
                        oidPathList.RemoveAt(0);
                        return GetQueryContextFromPath(lTreeNodeController, oidPathList);
                    }
                    else
                    {
                        return lTreeNodeController.QueryContext;
                    }
                }
            }
            // Return null if has not been returned any value
            return null;
        }
        /// <summary>
        /// Retruns true if the node is a sub node at any level
        /// </summary>
        /// <param name="node">Node</param>
        /// <param name="nodeToBeFound">Sub node</param>
        /// <returns></returns>
        private bool ContainsNodeController(TreeNodeController node, TreeNodeController nodeToBeFound)
        {
            if (node == nodeToBeFound)
                return true;

            foreach (TreeNodeController lNodeController in node.SubNodes)
            {
                if (ContainsNodeController(lNodeController, nodeToBeFound))
                {
                    return true;
                }
            }

            return false;
        }
 /// <summary>
 /// Configures the Tree presentation for the received node and its subnodes
 /// </summary>
 private void ConfigureTreeForNode(string parentNodeId, TreeNodeController treeNode)
 {
     // Configures the Tree using the received Node and locating the TreeNodes contained in it
     mTree.AddIntermediaNode(parentNodeId, treeNode.NodeId, treeNode.Alias, treeNode.Menu, treeNode.SubNodes.Count == 0, treeNode.ImageKey, treeNode.GroupImageKey, treeNode.ShowGroupingNode);
     foreach (TreeNodeController subNode in treeNode.SubNodes)
     {
         if (subNode.ShowInTree || subNode.ShowGroupingNode)
             ConfigureTreeForNode(treeNode.NodeId, subNode);
     }
 }
        /// <summary>
        /// This method allows the creation of recursive relations in the Tree
        /// Adds a new child node to an existing one that must be one of the parent nodes at any level
        /// The new child node will show related instances using the role path 
        /// </summary>
        /// <param name="parentNode">Parent node</param>
        /// <param name="newChildNode">New child node</param>
        /// <param name="rolePath">Role path</param>
        /// <param name="navigationalFilterId">Navigational filter id</param>
        /// <param name="alias">Alias to be shown in the grouping node</param>
        public void AddRecursiveNode(TreeNodeController parentNode, TreeNodeController newChildNode, string rolePath, string navigationalFilterId, string alias)
        {
            // Check if the new child node contains the parent node or it is the same
            // If not, it is not a recursive node
            bool lFound = parentNode == newChildNode;
            if (!lFound)
            {
                foreach (TreeNodeController lNodeController in newChildNode.SubNodes)
                {
                    lFound = ContainsNodeController(lNodeController, parentNode);
                    if (lFound)
                    {
                        break;
                    }
                }
            }

            if (!lFound)
            {
                return;
            }

            // Parent node has a new subnode. All existing subnodes requires a grouping intermedia node
            foreach (TreeNodeController lSubNode in parentNode.SubNodes)
            {
                lSubNode.ShowGroupingNode = true;
            }

            // Add to the list
            ExchangeInfoNavigation lNavInfo = new ExchangeInfoNavigation(newChildNode.QueryContext.ClassName, "", rolePath, navigationalFilterId, null, null, "");
            TreeNodeController lNewNode = new TreeNodeController(newChildNode, lNavInfo);
            parentNode.RecursiveNodes.Add(lNewNode);

            // Notify to the Tree the new recursive node
            Tree.AddRecursiveNode(parentNode.NodeId, newChildNode.NodeId, alias);
        }
        /// <summary>
        /// Updates a complete existing branch in the tree
        /// </summary>
        /// <param name="originalOidPath"></param>
        /// <param name="nodeController"></param>
        private void UpdateBranch(List<KeyValuePair<string, Oid>> originalOidPath, TreeNodeController nodeController)
        {
            // Check if the branch still exists in the Tree
            if (!Tree.ExistCompleteOidPath(originalOidPath))
            {
                return;
            }

            // If there is only one element in the list, it is a root node
            if (originalOidPath.Count == 1)
            {
                // The root node it is an instance, refresh it
                if (originalOidPath[0].Value != null)
                {
                    RefreshInstance(nodeController.NodeId, originalOidPath[0].Value as Oid);
                    return;
                }
                else
                {
                    // The root node it is a grouping node, refresh all the branch
                }
            }

            // Keep the original list
            List<KeyValuePair<string, Oid>> oidPathList = new List<KeyValuePair<string, Oid>>(originalOidPath);

            Oid lParentOid = null;
            lParentOid = GetLastOidInPath(oidPathList);

            // Find the corresponfing ExchangeInfo with the Complete Oid Path
            // Add the last NodeId to the list
            IUQueryContext queryContext = GetQueryContextFromPath(oidPathList);

            // Get the relaed data
            DataTable lData = null;
            if (lParentOid == null)
            {
                // If parent oid is null, use the last selected instance in the context
                if (queryContext.ExchangeInformation.SelectedOids != null &&
                    queryContext.ExchangeInformation.SelectedOids.Count > 0)
                {
                    lData = GetPopulationRelatedWith(queryContext.ExchangeInformation.SelectedOids[0], queryContext);
                }
            }
            else
            {
                lData = GetPopulationRelatedWith(lParentOid, queryContext);
            }

            // Replace the existing data in the Tree
            HideAllGroups();
            Tree.RefreshBranch(originalOidPath, lData, nodeController.DisplaySetInfo, IsLastBlock(queryContext));
        }
 /// <summary>
 /// Initializes the Group Container for the received node and its subnodes
 /// </summary>
 private void InitializeGroupContainer(TreeNodeController node, ref int nodeCounter)
 {
     foreach (TreeNodeController subNode in node.SubNodes)
     {
         if (subNode.IsFinalNode())
         {
             GroupContainer.AssignGroupId(nodeCounter, subNode.NodeId);
             nodeCounter++;
         }
         else
         {
             InitializeGroupContainer(subNode, ref nodeCounter);
         }
     }
 }