private static void RemoveGlobalContentTreeNodesIfNecessary(TreeNode treeNode)
        {
            if (treeNode.IsDirectoryNode())
            {
                string directory = treeNode.GetRelativePath();

                directory = ProjectManager.MakeAbsolute(directory, true);


                if (!Directory.Exists(directory))
                {
                    // The directory isn't here anymore, so kill it!
                    treeNode.Parent.Nodes.Remove(treeNode);

                }
                else
                {
                    // The directory is valid, but let's check subdirectories
                    for (int i = treeNode.Nodes.Count - 1; i > -1; i--)
                    {
                        RemoveGlobalContentTreeNodesIfNecessary(treeNode.Nodes[i]);
                    }
                }
            }
            else // assume content for now
            {

                ReferencedFileSave referencedFileSave = treeNode.Tag as ReferencedFileSave;

                if (!ProjectManager.GlueProjectSave.GlobalFiles.Contains(referencedFileSave))
                {
                    treeNode.Parent.Nodes.Remove(treeNode);
                }
                else
                {
                    // The RFS may be contained, but see if the file names match
                    string rfsName = FileManager.Standardize(referencedFileSave.Name, null, false).ToLower();
                    string treeNodeFile = FileManager.Standardize(treeNode.GetRelativePath(), null, false).ToLower();

                    // We first need to make sure that the file is part of GlobalContentFiles.
                    // If it is, then we may have tree node in the wrong folder, so let's get rid
                    // of it.  If it doesn't start with globalcontent/ then we shouldn't remove it here.
                    if (rfsName.StartsWith("globalcontent/") &&  rfsName != treeNodeFile)
                    {
                        treeNode.Parent.Nodes.Remove(treeNode);
                    }
                }
            }
        }
        public void AddDirectory(string folderName, TreeNode treeNodeToAddTo)
        {

            if (treeNodeToAddTo.IsGlobalContentContainerNode())
            {
                string rootDirectory = FileManager.RelativeDirectory;
                if (ProjectManager.ContentProject != null)
                {
                    rootDirectory = ProjectManager.ContentProject.Directory;
                }

                string directory = rootDirectory + "GlobalContent/" + folderName;

                Directory.CreateDirectory(directory);
            }
            else if (treeNodeToAddTo.IsRootEntityNode())
            {
                string directory = FileManager.RelativeDirectory + "Entities/" +
                    folderName;

                Directory.CreateDirectory(directory);
            }
            else if (treeNodeToAddTo.IsDirectoryNode())
            {
                // This used to use RelativeDirectory, but
                // I think we want this to be content, so not
                // sure why it uses RelativeDirectory...
                //string directory = FileManager.RelativeDirectory +
                //    currentTreeNode.GetRelativePath() +
                //    tiw.Result;
                // Update October 16, 2011
                // An Enity has both folders
                // in the code folder (represented
                // by RelativeDirectory) as well as
                // in the Content project.  An Entity
                // may not have files in the Content folder,
                // but it must have code files.  Therefore, we
                // create folders in the code directory tree and
                // we worry about content when NamedObjectSaves are
                // added to a given Entity later.
                //string directory = currentTreeNode.GetRelativePath() +
                //    tiw.Result;
                // Update February 17, 2012
                // But...when we add a new folder
                // to an Entity, we want that folder
                // to show up in the tree view in Glue.
                // Glue only scans the content folder, so
                // we want to make sure this folder exists
                // so it shows up okay.

                string directory = FileManager.RelativeDirectory +
                        treeNodeToAddTo.GetRelativePath() +
                        folderName;
                directory = ProjectManager.MakeAbsolute(directory, true);

                Directory.CreateDirectory(directory);

                directory = ProjectManager.ContentDirectory +
                        treeNodeToAddTo.GetRelativePath() +
                        folderName;
                directory = ProjectManager.MakeAbsolute(directory, true);

                Directory.CreateDirectory(directory);

            }
            else if (treeNodeToAddTo.IsFilesContainerNode() || treeNodeToAddTo.IsFolderInFilesContainerNode())
            {
                string directory =
                    treeNodeToAddTo.GetRelativePath() + folderName;

                Directory.CreateDirectory(ProjectManager.MakeAbsolute(directory, true));

                if (EditorLogic.CurrentEntityTreeNode != null)
                {
                    EditorLogic.CurrentEntityTreeNode.UpdateReferencedTreeNodes();
                }
                else if (EditorLogic.CurrentScreenTreeNode != null)
                {
                    EditorLogic.CurrentScreenTreeNode.UpdateReferencedTreeNodes();
                }
            }
            else if (treeNodeToAddTo.IsFolderInFilesContainerNode())
            {

                throw new NotImplementedException();
            }

            var containingElementNode = treeNodeToAddTo.GetContainingElementTreeNode();

            IElement element = null;
            if (containingElementNode != null)
            {
                element = containingElementNode.Tag as IElement;
            }

            if (containingElementNode == null)
            {
                GlueCommands.Self.RefreshCommands.RefreshGlobalContent();
            }
            else
            {
                GlueCommands.Self.RefreshCommands.RefreshUi(element);
            }

            GlueCommands.Self.RefreshCommands.RefreshDirectoryTreeNodes();
        }
        private static void MoveReferencedFile(TreeNode treeNodeMoving, TreeNode targetNode)
        {
            while (targetNode != null && targetNode.IsReferencedFile
                ())
            {
                targetNode = targetNode.Parent;
            }
            // If the user drops a file on a Screen or Entity, let's allow them to
            // complete the operation on the Files node
            if (targetNode is BaseElementTreeNode)
            {
                targetNode = ((BaseElementTreeNode)targetNode).FilesTreeNode;
            }

            ReferencedFileSave referencedFileSave = treeNodeMoving.Tag as ReferencedFileSave;

            if (targetNode.IsGlobalContentContainerNode())
            {
                if (targetNode.GetContainingElementTreeNode() == null)
                {
                    string targetDirectory = ProjectManager.MakeAbsolute(targetNode.GetRelativePath(), true);
                    MoveReferencedFileToDirectory(referencedFileSave, targetDirectory);
                }
                else
                {
                    DragAddFileToGlobalContent(treeNodeMoving, referencedFileSave);
                    // This means the user wants to add the file
                    // to global content.
                }
            }
            else if (targetNode.IsFolderForGlobalContentFiles())
            {
                string targetDirectory = ProjectManager.MakeAbsolute(targetNode.GetRelativePath(), true);
                MoveReferencedFileToDirectory(referencedFileSave, targetDirectory);
            }
            else if (!targetNode.IsFilesContainerNode() &&
                !targetNode.IsFolderInFilesContainerNode() &&
                !targetNode.IsFolderForGlobalContentFiles())
            {
                MessageBox.Show(@"Can't drop this file here");
                return;
            }
            else if (!string.IsNullOrEmpty(referencedFileSave.SourceFile) ||
                referencedFileSave.SourceFileCache.Count != 0)
            {
                MessageBox.Show("Can't move the file\n\n" + referencedFileSave.Name + "\n\nbecause it has source-referencing files.  These sources will be broken " +
                    "if the file is moved.  You will need to manually move the file, modify the source references, remove this file, then add the newly-created file.");
                return;
            }
            //if (targetNode.IsFolderInFilesContainerNode() || targetNode.IsFilesContainerNode())
            else
            {
                // See if we're moving the RFS from one Element to another
                IElement container = ObjectFinder.Self.GetElementContaining(referencedFileSave);
                TreeNode elementTreeNodeDroppingIn = targetNode.GetContainingElementTreeNode();
                IElement elementDroppingIn = null;
                if (elementTreeNodeDroppingIn != null)
                {
                    // User didn't drop on an entity, but instead on a node within the entity.
                    // Let's check if it's a subfolder. If so, we need to tell the user that we
                    // can't add the file in a subfolder.

                    if (targetNode.IsFolderInFilesContainerNode())
                    {
                        MessageBox.Show("Shared files cannot be added to subfolders, so it will be added directly to \"Files\"");
                    }

                    elementDroppingIn = elementTreeNodeDroppingIn.Tag as IElement;
                }

                if (container != elementDroppingIn)
                {
                    ElementViewWindow.SelectedNode = targetNode;

                    string absoluteFileName = ProjectManager.MakeAbsolute(referencedFileSave.Name, true);
                    string creationReport;
                    string errorMessage;

                    var newlyCreatedFile = ElementCommands.Self.CreateReferencedFileSaveForExistingFile(elementDroppingIn, null, absoluteFileName,
                                                                    PromptHandleEnum.Prompt, 
                                                                    referencedFileSave.GetAssetTypeInfo(),
                                                                    out creationReport,
                                                                    out errorMessage);

                    ElementViewWindow.UpdateChangedElements();

                    
                    

                    if (!String.IsNullOrEmpty(errorMessage))
                    {
                        MessageBox.Show(errorMessage);
                    }
                    else if(newlyCreatedFile != null)
                    {
                        GlueCommands.Self.TreeNodeCommands.SelectTreeNode(newlyCreatedFile);

                    }
                }
                else
                {
                    // Not moving into or out of an element
                    string targetDirectory = ProjectManager.MakeAbsolute(targetNode.GetRelativePath(), true);
                    MoveReferencedFileToDirectory(referencedFileSave, targetDirectory);
                }
            }
        }
        static void MoveEntityToDirectory(EntityTreeNode treeNodeMoving, TreeNode targetNode)
        {
            bool succeeded = true;

            // Things to do:
            // 1 Move the TreeNode from one parent TreeNode to another
            // 2 Move the .cs and .generated.cs file from one folder to another
            // 3 Remove the BuildItems from the project and add them back in in the VisualStudio project
            // 4 Change the EntitySave's name
            // 5 Change namespaces
            // 6 Find all NamedObjectSaves that are use this Entity and re-generate the Elements, and also see if anything uses it as a base
            // 7 Save everything!

            EntitySave entitySave = treeNodeMoving.EntitySave;
            string targetDirectory = FileManager.RelativeDirectory + targetNode.GetRelativePath();
            string oldName = entitySave.Name;
            string newName = targetNode.GetRelativePath().Replace("/", "\\") + entitySave.ClassName;


            succeeded = MoveEntityCodeFilesToDirectory(entitySave, targetDirectory);



            if (succeeded)
            {


                // 1: Move it from one node to another
                treeNodeMoving.Parent.Nodes.Remove(treeNodeMoving);
                targetNode.Nodes.Add(treeNodeMoving);


                // 2: Move the .cs files
                // Also handled above.
                treeNodeMoving.GeneratedCodeFile = newName + ".Generated.cs";
                treeNodeMoving.CodeFile = newName + ".cs";
            }

            if(succeeded)
            {
                // 4: Change the Entity's name

                entitySave.Name = newName;
                treeNodeMoving.Text = FileManager.RemovePath(newName);
            }

            if (succeeded)
            {
                // Do this after changing the name of the Entity so
                // namespaces come over properly
                succeeded = UpdateNamespaceOnCodeFiles(entitySave);
            }
            if(succeeded)
            {
                // 5: Change namespaces
                string newNamespace = ProjectManager.ProjectNamespace + "." + FileManager.MakeRelative(targetDirectory).Replace("/", ".");
                newNamespace = newNamespace.Substring(0, newNamespace.Length - 1);
                string customFileContents = FileManager.FromFileText(FileManager.RelativeDirectory + newName + ".cs");
                customFileContents = CodeWriter.ReplaceNamespace(customFileContents, newNamespace);
                FileManager.SaveText(customFileContents, FileManager.RelativeDirectory + newName + ".cs");

                // Generated will automatically have its namespace changed when it is re-generated

                // 6:  Find all objects referending this NamedObjectSave and re-generate the code

                if (entitySave.CreatedByOtherEntities)
                {
                    // Vic says: I'm tired.  For now just ignore the directory.  Fix this when it becomes a problem.
                    FactoryCodeGenerator.UpdateFactoryClass(entitySave);
                }

                List<NamedObjectSave> namedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(oldName);


                // Let's get all the TreeNodes to regenerate.
                // We want to store them in a list so we only generate
                // each tree node once.
                List<BaseElementTreeNode> treeNodesForElementsToRegenerate = new List<BaseElementTreeNode>();

                foreach (NamedObjectSave nos in namedObjects)
                {
                    if (nos.SourceClassGenericType == oldName)
                    {
                        nos.SourceClassGenericType = newName;
                    }

                    if (nos.SourceClassType == oldName)
                    {
                        nos.SourceClassType = newName;
                    }

                    IElement element = nos.GetContainer();

                    BaseElementTreeNode treeNode = GlueState.Self.Find.ElementTreeNode(element);
                    if (!treeNodesForElementsToRegenerate.Contains(treeNode))
                    {
                        treeNodesForElementsToRegenerate.Add(treeNode);
                    }
                }


                foreach (EntitySave esToTestForInheritance in ProjectManager.GlueProjectSave.Entities)
                {
                    if (esToTestForInheritance.BaseEntity == oldName)
                    {
                        esToTestForInheritance.BaseEntity = newName;

                        BaseElementTreeNode treeNode = GlueState.Self.Find.EntityTreeNode(esToTestForInheritance);
                        if (!treeNodesForElementsToRegenerate.Contains(treeNode))
                        {
                            treeNodesForElementsToRegenerate.Add(treeNode);
                        }
                    }
                }

                foreach (BaseElementTreeNode treeNode in treeNodesForElementsToRegenerate)
                {
                    CodeWriter.GenerateCode(treeNode.SaveObjectAsElement);
                }


                // 7: Save it!
                ProjectLoader.Self.MakeGeneratedItemsNested();
                CodeWriter.GenerateCode(treeNodeMoving.SaveObjectAsElement);

                GluxCommands.Self.SaveGlux();
                ProjectManager.SaveProjects();
            }
        }
        static void MoveEntityToDirectory(EntityTreeNode treeNodeMoving, TreeNode targetNode)
        {
            bool succeeded = true;

            EntitySave entitySave = treeNodeMoving.EntitySave;

            string newRelativeDirectory = targetNode.GetRelativePath();

            string newName = newRelativeDirectory.Replace("/", "\\") + entitySave.ClassName;

            // modify data and files
            succeeded = GlueCommands.Self.GluxCommands.MoveEntityToDirectory(entitySave, newRelativeDirectory);

            // adjust the UI
            if (succeeded)
            {
                treeNodeMoving.Parent.Nodes.Remove(treeNodeMoving);
                targetNode.Nodes.Add(treeNodeMoving);


                treeNodeMoving.GeneratedCodeFile = newName + ".Generated.cs";
                treeNodeMoving.CodeFile = newName + ".cs";
                treeNodeMoving.Text = FileManager.RemovePath(newName);

            }

            // Generate and save
            if (succeeded)
            {
                // 7: Save it!
                ProjectLoader.Self.MakeGeneratedItemsNested();
                CodeWriter.GenerateCode(entitySave);

                GluxCommands.Self.SaveGlux();
                ProjectManager.SaveProjects();

                GlueState.Self.CurrentElement = entitySave;
            }
        }
        private void AddDirectoryNodesRecursively(string currentDirectory, TreeNode treeNode)
        {
            if (System.IO.Directory.Exists(currentDirectory))
            {
                string[] directories = System.IO.Directory.GetDirectories(currentDirectory);

                #region Add new nodes

                foreach (string directory in directories)
                {

                    if (!ElementViewWindow.DirectoriesToIgnore.Contains(FileManager.RemovePath(directory)))
                    {
                        bool alreadyHasNode = false;

                        // See if there is already a tree node with this name
                        string directoryRelativeToThisTreeNode = FileManager.MakeRelative(
                            directory, ProjectManager.MakeAbsolute(treeNode.GetRelativePath(), true)) + "/";

                        TreeNode existingTreeNode = GetNodeForDirectory(directoryRelativeToThisTreeNode, treeNode);

                        if (existingTreeNode == null)
                        {
                            TreeNode newNode = new TreeNode(FileManager.RemovePath(directory));

                            newNode.ForeColor = ElementViewWindow.FolderColor;

                            if (BaseElementTreeNode.UseIcons)
                            {
                                newNode.ImageKey = "folder.png";
                                newNode.SelectedImageKey = "folder.png";
                            }

                            treeNode.Nodes.Add(newNode);
                        }
                    }
                }

                #endregion


                foreach (TreeNode subNode in treeNode.Nodes)
                {
                    if (subNode.IsFolderInFilesContainerNode())
                    {
                        string subDirectory = subNode.GetRelativePath();

                        subDirectory = ProjectManager.MakeAbsolute(subDirectory, true);

                        AddDirectoryNodesRecursively(subDirectory, subNode);

                    }

                }
            }

        }
        private TreeNode GetNodeForDirectory(string directory, TreeNode currentNode)
        {
            if (string.IsNullOrEmpty(directory))
            {
                return currentNode;
            }

            if (currentNode.IsFilesContainerNode())
            {
                string currentNodeDirectory = FileManager.Standardize(currentNode.GetRelativePath(), null, false);

                directory = FileManager.Standardize(directory, null, false);

                if (directory.StartsWith(currentNodeDirectory))
                {
                    directory = directory.Substring(currentNodeDirectory.Length);
                }
                
            }

            int indexOfSlash = directory.IndexOf("/");

            if (string.IsNullOrEmpty(directory))
            {
                return this;
            }
            else
            {
                string nameToSearchFor = directory.Substring(0, indexOfSlash);

                for (int i = 0; i < currentNode.Nodes.Count; i++)
                {
                    TreeNode subNode = currentNode.Nodes[i];

                    if (subNode.Text == nameToSearchFor && subNode.IsFolderInFilesContainerNode())
                    {
                        return GetNodeForDirectory(directory.Substring(indexOfSlash + 1), subNode);
                    }
                }

                return null;
            }
        }