/// <summary>
        ///
        /// </summary>
        /// <param name="userUID"></param>
        /// <param name="newgenUID"></param>
        /// <param name="prevgenUID"></param>
        /// <returns></returns>
        public virtual bool MatchConstructs(string userUID, string newgenUID, string prevgenUID)
        {
            if (string.IsNullOrEmpty(userUID) && string.IsNullOrEmpty(newgenUID) && string.IsNullOrEmpty(prevgenUID))
            {
                throw new ArgumentException("Cannot match 3 null objects!");
            }


            // Get Base Constructs. Make sure we can find the ones we are given.
            IBaseConstruct userBC    = GetBaseConstructfromUID(userUID, UserCodeRoot);
            IBaseConstruct newgenBC  = GetBaseConstructfromUID(newgenUID, NewGenCodeRoot);
            IBaseConstruct prevgenBC = GetBaseConstructfromUID(prevgenUID, PrevGenCodeRoot);

            if (userBC == null && newgenBC == null && prevgenBC == null)
            {
                throw new ArgumentException("Could not find any of the elements specified");
            }

            CodeRootMapNode parent = GetExactNode(userBC ?? newgenBC ?? prevgenBC).ParentNode;

            if ((newgenBC != null && parent != GetExactNode(newgenBC).ParentNode) ||
                (prevgenBC != null && parent != GetExactNode(prevgenBC).ParentNode))
            {
                throw new ArgumentException("The 3 nodes specified do not belong to the same parent and thus cannot be matched.");
            }

            MatchConstructs(parent, userBC, newgenBC, prevgenBC);

            return(true);
        }
        public CodeRootMapNode(CodeRootMap parentTree, CodeRootMapNode parentNode)
        {
            parentCRMTree = parentTree;
            parentCRMNode = parentNode;
            parentCRMNode.children.Add(this);

            parentCRMTree.AddNode(this);
        }
        /// <summary>
        /// Matches the 3 given nodes for diff and merge purposes. Does not modify the CodeRoots, just rewires the
        /// CodeRootMap. Only works if the base constructs being matched have the same parent. They may have the same
        /// parent if their parent has been matched with somthing else.
        /// </summary>
        /// <param name="parentNode">The parent CodeRootMapNode of the 3 base constructs. If the BCs were functions, this would
        /// be the CodeRootMapNode that holds their parent class.</param>
        /// <param name="userObj">The user object to map.</param>
        /// <param name="newGenObj">The template object to map.</param>
        /// <param name="prevGenObj">The prevgen object to map.</param>
        public void MatchConstructs(CodeRootMapNode parentNode, IBaseConstruct userObj, IBaseConstruct newGenObj, IBaseConstruct prevGenObj)
        {
            if (userObj != null)
            {
                CodeRootMapNode childNode = parentNode.GetChildNode(userObj);
                if (childNode == null)
                {
                    throw new Exception("UserObject not part of this tree");
                }
                childNode.RemoveBaseConstruct(userObj, false);
            }
            if (newGenObj != null)
            {
                CodeRootMapNode childNode = parentNode.GetChildNode(newGenObj);
                if (childNode == null)
                {
                    throw new Exception("NewGen not part of this tree");
                }
                childNode.RemoveBaseConstruct(newGenObj, false);
            }
            if (prevGenObj != null)
            {
                CodeRootMapNode childNode = parentNode.GetChildNode(prevGenObj);
                if (childNode == null)
                {
                    throw new Exception("PrevGen not part of this tree");
                }
                childNode.RemoveBaseConstruct(prevGenObj, false);
            }

            CleanUpTree();

            CodeRootMapNode newNode = new CodeRootMapNode(parentNode.ParentTree, parentNode);

            newNode.IsCustomMatch = true;
            if (userObj != null)
            {
                newNode.AddBaseConstruct(userObj, Version.User);
            }
            if (newGenObj != null)
            {
                newNode.AddBaseConstruct(newGenObj, Version.NewGen);
            }
            if (prevGenObj != null)
            {
                newNode.AddBaseConstruct(prevGenObj, Version.PrevGen);
            }
        }
        /// <summary>
        /// Adds the Base Construct to this node, and processes its children to add them too.
        /// </summary>
        /// <param name="bc"></param>
        /// <param name="t"></param>
        public CodeRootMapNode AddBaseConstructAsNewChild(IBaseConstruct bc, Version t)
        {
            if (bc == null)
            {
                return(null);
            }
            CodeRootMapNode node = new CodeRootMapNode(ParentTree, this);

            node.SetBaseConstruct(bc, t);

            foreach (IBaseConstruct child in bc.WalkChildren())
            {
                node.AddBaseConstructAsNewChild(child, t);
            }

            return(node);
        }
        internal void RemoveChildFromTree(CodeRootMapNode node)
        {
            allNodes.Remove(node);

            List <CodeRootMapNode> nodesToRemove = new List <CodeRootMapNode>();

            foreach (CodeRootMapNode child in node.ChildNodes)
            {
                nodesToRemove.Add(child);
            }

            node.ParentNode.RemoveChild(node);
            foreach (CodeRootMapNode nodeToRemove in nodesToRemove)
            {
                RemoveChildFromTree(nodeToRemove);
            }
        }
        /// <summary>
        /// Gets a list of nodes that have custom matches. It is guaranteed
        /// that any custom matched child nodes will come after their ancestors,
        /// if any of their ancestors are custom matched.
        /// </summary>
        /// <returns></returns>
        public IList <CodeRootMapNode> GetCustomMatchedNodes()
        {
            List <CodeRootMapNode>  nodes         = new List <CodeRootMapNode>();
            Queue <CodeRootMapNode> nodesToSearch = new Queue <CodeRootMapNode>(ChildNodes);

            // Do a breadth first search of all of the nodes in the tree.
            while (nodesToSearch.Count > 0)
            {
                CodeRootMapNode node = nodesToSearch.Dequeue();

                if (node.IsCustomMatch)
                {
                    nodes.Add(node);
                }

                foreach (CodeRootMapNode child in node.ChildNodes)
                {
                    nodesToSearch.Enqueue(child);
                }
            }
            return(nodes);
        }
 internal void RemoveChild(CodeRootMapNode node)
 {
     children.Remove(node);
     node.ParentNode = null;
 }
 /// <summary>
 /// Override this in the Tree class to provide a method of adding nodes to a collection of all nodes.
 /// </summary>
 /// <param name="node">The node to add.</param>
 /// <exception cref="InvalidOperationException">Thrown if the base version of this method is called. It must be overridden.</exception>
 protected virtual void AddNode(CodeRootMapNode node)
 {
     throw new InvalidOperationException("Cannot call this on a node, must be called on the root Tree.");
 }
 /// <summary>
 /// Adds node to a collection of all nodes.
 /// </summary>
 /// <param name="node">The node to add.</param>
 protected override void AddNode(CodeRootMapNode node)
 {
     allNodes.Add(node);
 }