private void CreateEntityTreeNodes()
        {
            //ProjectManager.GlueProjectSave.Entities[78].NamedObjects[9].UpdateCustomProperties();


            // Let's make this faster.
            //foreach (EntitySave entity in ProjectManager.GlueProjectSave.Entities)
            // Actually, the contained functions may show popups, and if 2 simultaneous popups
            // are shown, one can cancel the other out and this can cause Glue to freeze. This means
            // we can't parallel foreah it
            //Parallel.ForEach(ProjectManager.GlueProjectSave.Entities, (entity) =>
            foreach (EntitySave entity in ProjectManager.GlueProjectSave.Entities)
                {
                    entity.UpdateCustomProperties();
                    entity.UpdateFromBaseType();
                }

            for (int i = 0; i < ProjectManager.GlueProjectSave.Entities.Count; i++)
            {
                EntitySave entitySave = ProjectManager.GlueProjectSave.Entities[i];
                // This is so fast that we no longer need to show the
                // user details - and not doing it will make things even faster
                //SetInitWindowText("Creating Entity: " + entitySave.Name);

                EntityTreeNode entityTreeNode = GlueState.Self.Find.EntityTreeNode(entitySave.Name);

                #region If there is no EntityTreeNode

                if (entityTreeNode == null)
                {
                    // See if the file exists
                    string fileToSearchFor = FileManager.RelativeDirectory + entitySave.Name + ".cs";

                    if (System.IO.File.Exists(fileToSearchFor))
                    {
                        // If we got here that means there's probably not a build item for this file
                        MessageBox.Show("The Glue project has the following Entity:\n" + entitySave.Name + "\n" +
                            "but this file is not part of Visual Studio.  This file may have been removed manually or " +
                            "there may have been some saving error.  You should close Glue, manually add this and the Generated file " +
                            "to Visual Studio, then restart Glue.");
                        MainGlueWindow.Self.HasErrorOccurred = true;
                    }
                    else
                    {
                        MultiButtonMessageBox mbmb = new MultiButtonMessageBox();

                        mbmb.MessageText = "Could not find the file name\n\n" + fileToSearchFor + "\n\nwhich is used by the entity\n\n" + entitySave.Name + "\n\n" +
                            "What would you like to do?";


                        mbmb.AddButton("Create a new custom code file", DialogResult.Yes);
                        mbmb.AddButton("Delete this Entity", DialogResult.No);
                        mbmb.AddButton("Do nothing.  The Entity will not show up in Glue until this problem is fixed.", DialogResult.Cancel);

                        DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                        switch (result)
                        {
                            case DialogResult.Yes:
                                if (entityTreeNode == null)
                                {
                                    entityTreeNode = ElementViewWindow.AddEntity(entitySave);
                                }

                                CodeWriter.GenerateAndAddElementCustomCode(entitySave);

                                //entityTreeNode.GenerateCode(ProjectManager.EntityTemplateCode);

                                break;
                            case DialogResult.No:
                                ProjectManager.GlueProjectSave.Entities.RemoveAt(i);
                                i--;
                                continue;

                            //break;
                            case DialogResult.Cancel:
                                // do nothing
                                continue;

                            //break;
                        }

                        System.Windows.Forms.MessageBox.Show("Could not create the EntitySave for " + entitySave.Name +
                            " because the following file doesn't exist\n\n" + fileToSearchFor);
                    }
                    //mGlueProjectSave.Entities.RemoveAt(i);
                    //i--;
                }

                #endregion


                entityTreeNode.EntitySave = entitySave;

                CheckForMissingCustomFile(entityTreeNode);


                entityTreeNode.UpdateReferencedTreeNodes(performSave: false);

                // moved above
                //entityTreeNode.EntitySave.UpdateCustomProperties();
                //entityTreeNode.EntitySave.UpdateFromBaseType();
            }
        }
        private bool DeserializeGluxXmlInternal(string projectFileName, string glueProjectFile)
        {
            bool succeeded = true;
            try
            {
                ProjectManager.GlueProjectSave = GlueProjectSaveExtensions.Load(glueProjectFile);

                string errors;
                ProjectManager.GlueProjectSave.PostLoadInitialize(out errors);

                if (errors != null)
                {
                    GlueGui.ShowMessageBox(errors);
                }
            }
            catch (Exception e)
            {
                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                mbmb.MessageText = "There was an error loading the .glux file.  What would you like to do?";

                mbmb.AddButton("Nothing - Glue will abort loading the project.", DialogResult.None);
                mbmb.AddButton("See the Exception", DialogResult.OK);
                mbmb.AddButton("Try loading again", DialogResult.Retry);
                mbmb.AddButton("Test for conflicts", DialogResult.Yes);

                DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);
                mCurrentInitWindow.Close();

                switch (result)
                {
                    case DialogResult.None:
                        // Do nothing;

                        break;
                    case DialogResult.OK:
                        MessageBox.Show(e.ToString());
                        break;
                    case DialogResult.Retry:
                        LoadProject(projectFileName);
                        break;
                    case DialogResult.Yes:
                        string text = FileManager.FromFileText(glueProjectFile);

                        if (text.Contains("<<<"))
                        {
                            MessageBox.Show("There are conflicts in your GLUX file.  You will need to use a merging " +
                                "tool or text editor to resolve these conflicts.");
                        }
                        else
                        {
                            MessageBox.Show("No Subversion conflicts found in your GLUX.");
                        }
                        break;
                }
                succeeded = false;
            }
            return succeeded;
        }
        private static void CheckForExistingFileOfSameName(string oldName, ReferencedFileSave fileSave, string newFileNameAbsolute, ref bool shouldMove, ref bool shouldContinue)
        {
            if (FileManager.FileExists(newFileNameAbsolute))
            {
                string message = "The new file name already exists.  What would you like to do?";

                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();

                mbmb.MessageText = message;

                mbmb.AddButton("Use existing file", DialogResult.Yes);
                mbmb.AddButton("Cancel the rename", DialogResult.Cancel);

                DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                if (result == DialogResult.Cancel)
                {
                    fileSave.SetNameNoCall(oldName);
                    shouldContinue = false;
                }
                else if (result == DialogResult.Yes)
                {
                    shouldMove = false;
                }
            }
        }
        void ContentPipelineChange(bool useContentPipeline, CurrentElementOrAll currentOrAll)
        {
            TextureProcessorOutputFormat? textureFormat = null;

            if (useContentPipeline)
            {
                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                mbmb.MessageText = "How should the texture formats be set?";
                mbmb.AddButton("Set to DXT Compression", DialogResult.Yes);
                mbmb.AddButton("Set to Color", DialogResult.OK);
                mbmb.AddButton("Do nothing", DialogResult.No);

                DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                switch (result)
                {
                    case DialogResult.Yes:
                        textureFormat = TextureProcessorOutputFormat.DxtCompressed;
                        break;
                    case DialogResult.OK:
                        textureFormat = TextureProcessorOutputFormat.Color;
                        break;
                    case DialogResult.No:
                        // do nothing, leave it to null
                        break;


                }
            }

            InitializationWindow initWindow = new InitializationWindow();
            initWindow.Show(MainGlueWindow.Self);
            initWindow.Message = "Performing Operation...";


            List<ReferencedFileSave> allRfses = new List<ReferencedFileSave>();

            if (currentOrAll == CurrentElementOrAll.CurrentElement)
            {
                IElement element = EditorLogic.CurrentElement;
                allRfses.AddRange(element.ReferencedFiles);
            }
            else
            {
                allRfses.AddRange(ObjectFinder.Self.GetAllReferencedFiles());
            }

            int totalRfs = allRfses.Count;
            //int count = 0;

            initWindow.SubMessage = "Removing/adding files as appropriate";
            Application.DoEvents();

            foreach (ReferencedFileSave rfs in allRfses)
            {
                if (rfs.GetAssetTypeInfo() != null && rfs.GetAssetTypeInfo().MustBeAddedToContentPipeline)
                {
                    rfs.UseContentPipeline = true;
                }
                else
                {
                    rfs.UseContentPipeline = useContentPipeline;
                }
            }

            ContentPipelineHelper.ReactToUseContentPipelineChange(allRfses);

            if (useContentPipeline)
            {

                initWindow.SubMessage = "Updating texture formats";
                Application.DoEvents();
                
                foreach (ReferencedFileSave rfs in allRfses)
                {
                    if (textureFormat.HasValue)
                    {
                        rfs.TextureFormat = textureFormat.Value;
                    }

                    ContentPipelineHelper.UpdateTextureFormatFor(rfs);
                }
            }

            initWindow.SubMessage = "Refreshing UI";
            Application.DoEvents();
            if (EditorLogic.CurrentElement != null)
            {
                GlueCommands.RefreshCommands.RefreshUiForSelectedElement();
            }

            initWindow.SubMessage = "Generating Code";
            Application.DoEvents();

            if (currentOrAll == CurrentElementOrAll.CurrentElement)
            {
                GlueCommands.GenerateCodeCommands.GenerateCurrentElementCode();
            }
            else
            {
                GlueCommands.GenerateCodeCommands.GenerateAllCode();
            }

            GlueCommands.GluxCommands.SaveGlux();

            GlueCommands.ProjectCommands.SaveProjects();


            initWindow.Close();


        }
        private void ReactToTextureAddressMode(NamedObjectSave namedObjectSave, object oldValue)
        {
            bool isSprite = namedObjectSave.SourceType == SourceType.FlatRedBallType && namedObjectSave.SourceClassType == "Sprite";
            if(isSprite)
            {
                var addressModeVariable = namedObjectSave.GetCustomVariable("TextureAddressMode");

                if (addressModeVariable != null && addressModeVariable.Value != null && 
                    ((TextureAddressMode)(addressModeVariable.Value) == TextureAddressMode.Wrap || (TextureAddressMode)(addressModeVariable.Value) == TextureAddressMode.Mirror))
                {
                    // How big is the texture?
                    var textureVariable = namedObjectSave.GetCustomVariable("Texture");

                    if (textureVariable != null && textureVariable.Value != null)
                    {
                        string value = textureVariable.Value as string;

                        var rfs = namedObjectSave.GetContainer().GetReferencedFileSaveByInstanceName(value);

                        if (rfs != null)
                        {

                            var width = ImageHeader.GetDimensions(
                                    ProjectManager.MakeAbsolute(rfs.Name)).Width;
                            var height = ImageHeader.GetDimensions(
                                    ProjectManager.MakeAbsolute(rfs.Name)).Height;

                            string whatIsWrong = null;

                            if (FlatRedBall.Math.MathFunctions.IsPowerOfTwo(width) == false)
                            {
                                whatIsWrong = "This Sprite's texture (" + textureVariable.Value + ") has a width of " + 
                                    width + " but it should be a power of two to use " + addressModeVariable.Value + " TextureAddressMode";
                            }


                            if (FlatRedBall.Math.MathFunctions.IsPowerOfTwo(height) == false)
                            {
                                whatIsWrong = "This Sprite's texture (" + textureVariable.Value + ") has a height of " +
                                    height + " but it should be a power of two to use " + addressModeVariable.Value + " TextureAddressMode";
                            }

                            if(!string.IsNullOrEmpty(whatIsWrong))
                            {
                                whatIsWrong += "\nWhat would you like to do?";

                                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                                mbmb.MessageText = whatIsWrong;
                                mbmb.AddButton("Undo the change", DialogResult.Cancel);
                                mbmb.AddButton("Keep the change (May cause runtime crashes)", DialogResult.Yes);

                                var result = mbmb.ShowDialog();

                                if(result == DialogResult.Cancel)
                                {
                                    addressModeVariable.Value = oldValue;
                                }

                            }
                        }
                    }
                }
            }
        }
        public static bool UpdateNamedObjectsFromBaseType(INamedObjectContainer namedObjectContainer)
        {
            bool haveChangesOccurred = false;

            List<NamedObjectSave> referencedObjectsBeforeUpdate = new List<NamedObjectSave>();

            for (int i = 0; i < namedObjectContainer.NamedObjects.Count; i++)
            {
                if (namedObjectContainer.NamedObjects[i].DefinedByBase)
                {
                    referencedObjectsBeforeUpdate.Add(namedObjectContainer.NamedObjects[i]);
                }
            }

            List<NamedObjectSave> namedObjectsSetByDerived = new List<NamedObjectSave>();
            List<NamedObjectSave> namedObjectsExposedInDerived = new List<NamedObjectSave>();

            List<INamedObjectContainer> baseElements = new List<INamedObjectContainer>();

            // June 1, 2011:
            // The following code
            // was using AddRange instead
            // of manually looping, but this
            // is only possible in .NET 4.0, and
            // GlueView still uses 3.1.  
            // July 24, 2011
            // Before today, this
            // code would loop through
            // all base Entities and search
            // for SetByDerived properties in
            // any NamedObjectSave. This caused
            // bugs.  Basically if you had 3 Elements
            // in an inheritance chain and the one at the
            // very base defined a NOS to be SetByDerived, then
            // anything that inherited directly from the base should
            // be forced to define it.  If it does, then the 3rd Element
            // in the inheritance chain shouldn't have to define it, but before
            // to day it did.  This caused a lot of problems including generated
            // code creating the element twice.
            if (namedObjectContainer is EntitySave)
            {
                if (!string.IsNullOrEmpty(namedObjectContainer.BaseObject))
                {
                    baseElements.Add(ObjectFinder.Self.GetIElement(namedObjectContainer.BaseObject));
                }
                //List<EntitySave> allBase = ((EntitySave)namedObjectContainer).GetAllBaseEntities();
                //foreach (EntitySave baseEntitySave in allBase)
                //{
                //    baseElements.Add(baseEntitySave);
                //}
            }
            else
            {
                if (!string.IsNullOrEmpty(namedObjectContainer.BaseObject))
                {
                    baseElements.Add(ObjectFinder.Self.GetIElement(namedObjectContainer.BaseObject));
                }
                //List<ScreenSave> allBase = ((ScreenSave)namedObjectContainer).GetAllBaseScreens();
                //foreach (ScreenSave baseScreenSave in allBase)
                //{
                //    baseElements.Add(baseScreenSave);
                //}
            }


            foreach (INamedObjectContainer baseNamedObjectContainer in baseElements)
            {

                if (baseNamedObjectContainer != null)
                {
                    namedObjectsSetByDerived.AddRange(baseNamedObjectContainer.GetNamedObjectsToBeSetByDerived());
                    namedObjectsExposedInDerived.AddRange(baseNamedObjectContainer.GetNamedObjectsToBeExposedInDerived());
                }
            }

            #region See if there are any objects to be removed from the derived.
            for (int i = referencedObjectsBeforeUpdate.Count - 1; i > -1; i--)
            {
                bool contains = false;

                for (int j = 0; j < namedObjectsSetByDerived.Count; j++)
                {
                    if (referencedObjectsBeforeUpdate[i].InstanceName == namedObjectsSetByDerived[j].InstanceName &&
                        referencedObjectsBeforeUpdate[i].DefinedByBase)
                    {
                        contains = true;
                        break;
                    }
                }

                for (int j = 0; j < namedObjectsExposedInDerived.Count; j++)
                {
                    if (referencedObjectsBeforeUpdate[i].InstanceName == namedObjectsExposedInDerived[j].InstanceName &&
                        referencedObjectsBeforeUpdate[i].DefinedByBase)
                    {
                        contains = true;
                        break;
                    }
                }

                if (!contains)
                {

                    NamedObjectSave nos = referencedObjectsBeforeUpdate[i];

                    string message = "The following object is marked as \"defined by base\" but it is not contained in " +
                        "any base elements\n\n" + nos.ToString() + "\n\nWhat would you like to do?";

                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();

                    mbmb.MessageText = message;

                    mbmb.AddButton("Remove " + nos.ToString(), DialogResult.Yes);
                    mbmb.AddButton("Keep it, make it not \"defined by base\"", DialogResult.No);

                    DialogResult result = mbmb.ShowDialog();

                    if (result == DialogResult.Yes)
                    {
                        // We got a NamedObject we should remove
                        namedObjectContainer.NamedObjects.Remove(nos);
                        referencedObjectsBeforeUpdate.RemoveAt(i);
                    }
                    else
                    {
                        nos.DefinedByBase = false;
                        nos.InstantiatedByBase = false;
                    }
                    haveChangesOccurred = true;
                }
            }
            #endregion

            #region Next, see if there are any objects to be added
            for (int i = 0; i < namedObjectsSetByDerived.Count; i++)
            {
                NamedObjectSave namedObjectSetByDerived = namedObjectsSetByDerived[i];

                NamedObjectSave matchingDefinedByBase = null;// contains = false;
                for (int j = 0; j < referencedObjectsBeforeUpdate.Count; j++)
                {
                    if (referencedObjectsBeforeUpdate[j].InstanceName == namedObjectSetByDerived.InstanceName &&
                        referencedObjectsBeforeUpdate[j].DefinedByBase)
                    {
                        matchingDefinedByBase = referencedObjectsBeforeUpdate[j];
                        break;
                    }
                }

                if (matchingDefinedByBase == null)
                {
                    AddSetByDerivedNos(namedObjectContainer, namedObjectSetByDerived, false);
                }
                else
                {
                    MatchDerivedToBase(namedObjectSetByDerived, matchingDefinedByBase);
                }
            }

            for (int i = 0; i < namedObjectsExposedInDerived.Count; i++)
            {
                NamedObjectSave namedObjectSetByDerived = namedObjectsExposedInDerived[i];

                NamedObjectSave matchingDefinedByBase = null;// contains = false;
                for (int j = 0; j < referencedObjectsBeforeUpdate.Count; j++)
                {
                    if (referencedObjectsBeforeUpdate[j].InstanceName == namedObjectSetByDerived.InstanceName &&
                        referencedObjectsBeforeUpdate[j].DefinedByBase)
                    {
                        matchingDefinedByBase = referencedObjectsBeforeUpdate[j];
                        break;
                    }
                }

                if (matchingDefinedByBase == null)
                {
                    AddSetByDerivedNos(namedObjectContainer, namedObjectSetByDerived, true);
                }
                else
                {
                    MatchDerivedToBase(namedObjectSetByDerived, matchingDefinedByBase);
                }
            }

            #endregion

            return haveChangesOccurred;
        }
        private static void RemoveEntity(EntitySave entityToRemove, List<string> filesThatCouldBeRemoved)
        {


            List<NamedObjectSave> namedObjectsToRemove = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(entityToRemove.Name);



            DialogResult result = DialogResult.Yes;

            string message = null;

            if (namedObjectsToRemove.Count != 0)
            {
                message = "The Entity " + entityToRemove.ToString() + " is referenced by the following objects:";

                for (int i = 0; i < namedObjectsToRemove.Count; i++)
                {
                    message += "\n" + namedObjectsToRemove[i].ToString();

                }


            }

            List<EntitySave> inheritingEntities = ObjectFinder.Self.GetAllEntitiesThatInheritFrom(entityToRemove);

            if (inheritingEntities.Count != 0)
            {
                message = "The Entity " + entityToRemove.ToString() + " is the base for the following Entities:";
                for (int i = 0; i < inheritingEntities.Count; i++)
                {
                    message += "\n" + inheritingEntities[i].ToString();

                }
            }

            if (message != null)
            {
                message += "\n\nDo you really want to remove this Entity?";

                result = MessageBox.Show(message, "Are you sure?", MessageBoxButtons.YesNo);
            }

            if (result == DialogResult.Yes)
            {
                for (int i = entityToRemove.NamedObjects.Count - 1; i > -1; i--)
                {
                    NamedObjectSave nos = entityToRemove.NamedObjects[i];



                    ProjectManager.RemoveNamedObject(nos, false, false, null);
                }


                if (entityToRemove.CreatedByOtherEntities == true)
                {
                    FactoryCodeGenerator.RemoveFactory(entityToRemove);
                }

                // We used to rely on RemoveUnreferencedFiles to do the removal of all RFS's 
                // However, RemoveUnreferencedFiles looks for the file's container to remove it,
                // and by this point the entityToRemove has already been removed from the project.
                // So we'll manually remove the RFS's first before removing the entire entity
                for (int i = entityToRemove.ReferencedFiles.Count - 1; i > -1; i--)
                {
                    GluxCommands.Self.RemoveReferencedFile(entityToRemove.ReferencedFiles[i], filesThatCouldBeRemoved);
                }

                    
                ProjectManager.GlueProjectSave.Entities.Remove(entityToRemove);


                RemoveUnreferencedFiles(entityToRemove, filesThatCouldBeRemoved);

                for (int i = 0; i < namedObjectsToRemove.Count; i++)
                {
                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                    NamedObjectSave nos = namedObjectsToRemove[i];
                    mbmb.MessageText = "What would you like to do with the object\n\n" + nos.ToString();

                    mbmb.AddButton("Remove this Object", DialogResult.OK);
                    mbmb.AddButton("Keep this Object (the reference will be invalid)", DialogResult.Cancel);

                    DialogResult namedObjectRemovalResult = mbmb.ShowDialog();

                    if (namedObjectRemovalResult == DialogResult.OK)
                    {

                        ProjectManager.RemoveNamedObject(nos, false, true, filesThatCouldBeRemoved);
                    }
                }
                for (int i = 0; i < inheritingEntities.Count; i++)
                {
                    EntitySave inheritingEntity = inheritingEntities[i];

                    DialogResult resetInheritance = MessageBox.Show("Reset the inheritance for " + inheritingEntity.Name + "?",
                        "Reset Inheritance?", MessageBoxButtons.YesNo);

                    if (resetInheritance == DialogResult.Yes)
                    {
                        inheritingEntity.BaseEntity = "";
                        CodeWriter.GenerateCode(inheritingEntity);
                    }
                }

                ElementViewWindow.RemoveEntity(entityToRemove);

                ProjectManager.RemoveCodeFilesForElement(filesThatCouldBeRemoved, entityToRemove);

                ProjectManager.SaveProjects();
                GluxCommands.Self.SaveGlux();
            }
        }
        private void HandleChangedIsContainer(NamedObjectSave nos, IElement element)
        {
            if (nos.IsContainer)
            {
                var existingContainer = element.AllNamedObjects.FirstOrDefault(
                    item => item.IsContainer && item != nos);

                bool succeeded = true;

                if (existingContainer != null)
                {
                    succeeded = false;

                    MessageBox.Show("The object " + existingContainer + " is already marked as IsContainer. " +
                        "Two objects in the same element cannot be marked as Iscontainer");

                }

                if (succeeded)
                {

                    bool doesBaseMatch = !string.IsNullOrEmpty(element.BaseElement) &&
                        element.BaseElement == nos.SourceClassType;

                    if (!doesBaseMatch)
                    {
                        MultiButtonMessageBox mbmb = new MultiButtonMessageBox();

                        string containerType = element.BaseElement;
                        if (string.IsNullOrEmpty(containerType))
                        {
                            containerType = "<NONE>";
                        }


                        mbmb.MessageText = "The object is of type " + nos.SourceClassType + " but the container is of type " + containerType + "\n\n" +
                            "What would you like to do?";

                        mbmb.AddButton("Set the container's type to " + nos.SourceClassType, DialogResult.Yes);
                        mbmb.AddButton("Nothing - game may not compile until this has been fixed", DialogResult.No);
                        mbmb.AddButton("Set 'IsContainer' back to false", DialogResult.Cancel);

                        var dialogResult = mbmb.ShowDialog();
                        if (dialogResult == DialogResult.Yes)
                        {
                            element.BaseObject = nos.SourceClassType;
                        }
                        else if (dialogResult == DialogResult.Cancel)
                        {
                            succeeded = false;
                        }
                    }
                }

                if(!succeeded)
                {
                    nos.IsContainer = false;
                }

            }
        }
        internal static NamedObjectSave CreateNewNamedObjectInElement(IElement elementToCreateIn, EntitySave blueprintEntity, bool createList = false)
        {
            if (elementToCreateIn is EntitySave && ((EntitySave)elementToCreateIn).ImplementsIVisible && !blueprintEntity.ImplementsIVisible)
            {
                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                mbmb.MessageText = "The Entity\n\n" + blueprintEntity + "\n\nDoes not Implement IVisible, but the Entity it is being dropped in does.  " +
                    "What would you like to do?";

                mbmb.AddButton("Make " + blueprintEntity.Name + " implement IVisible", DialogResult.OK);
                mbmb.AddButton("Nothing (your code will not compile until this problem is resolved manually)", DialogResult.Cancel);

                DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);
                if (result == DialogResult.OK)
                {
                    blueprintEntity.ImplementsIVisible = true;
                    CodeGeneratorIElement.GenerateElementDerivedAndReferenced(blueprintEntity);
                }

            }

            BaseElementTreeNode elementTreeNode = GlueState.Self.Find.ElementTreeNode(elementToCreateIn);

            //EntityTreeNode entityTreeNode =
            //    ElementViewWindow.GetEntityTreeNode(entityToCreateIn); 

            NamedObjectSave newNamedObject = new NamedObjectSave();

            // We'll add "List" or "Instance" below
            string newName = FileManager.RemovePath(blueprintEntity.Name);

            #region Set the source type properties for the new NamedObject

            if (createList)
            {
                newName += "List";
                newNamedObject.SourceType = SourceType.FlatRedBallType;
                newNamedObject.SourceClassType = "PositionedObjectList<T>";
                newNamedObject.SourceClassGenericType = blueprintEntity.Name;
                newNamedObject.UpdateCustomProperties();
            }
            else
            {
                newName += "Instance";
                newNamedObject.SourceType = SourceType.Entity;
                newNamedObject.SourceClassType = blueprintEntity.Name;
                newNamedObject.UpdateCustomProperties();
            }

            #endregion

            #region Set the name for the new NamedObject

            // get an acceptable name for the new object
            if (elementToCreateIn.GetNamedObjectRecursively(newName) != null)
            {
                newName += "2";
            }

            while (elementToCreateIn.GetNamedObjectRecursively(newName) != null)
            {
                newName = StringFunctions.IncrementNumberAtEnd(newName);
            }

            newNamedObject.InstanceName = newName;


            #endregion

            // We need to add to managers here.  Why?  Because normally when the type of a NamedObject is changed, 
            // the PropertyGrid handles setting whether it should be added or not. But in this case, we're not changing
            // the type of the new NamedObject through the PropertyGrid - instead it's being set programatically to be an
            // Entity.  So, we should add to managers programatically since the PropertyGrid won't do it for us.
            // Update December 11, 2011
            // AddToManagers defaults to
            // true on new NamedObjectSaves
            // so there's no need to explicitly
            // set it to true here.
            //newNamedObject.AddToManagers = true;


            NamedObjectSaveExtensionMethodsGlue.AddNewNamedObjectToElementTreeNode(elementTreeNode, newNamedObject, true);

            return newNamedObject;
        }
        public static bool TryAskToMoveFileRelativeToAnimationChainFile(ref string absoluteFileName, out string achxFolder)
        {
            bool shouldProceed = true;

            achxFolder = FileManager.GetDirectory(ProjectManager.Self.FileName);

            if (ShouldAskUserToCopyFile(absoluteFileName))
            {

                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                mbmb.MessageText = "The selected file:\n\n" + absoluteFileName + "\n\nis not relative to the Animation Chain file.  What would you like to do?";

                mbmb.AddButton("Copy the file to the same folder as the Animation Chain", System.Windows.Forms.DialogResult.Yes);
                mbmb.AddButton("Keep the file where it is (this may limit the portability of the Animation Chain file)", System.Windows.Forms.DialogResult.No);

                DialogResult result = mbmb.ShowDialog();

                if (result == DialogResult.Yes)
                {
                    string destination = achxFolder + FileManager.RemovePath(absoluteFileName);

                    try
                    {
                        System.IO.File.Copy(absoluteFileName, destination, true);
                        absoluteFileName = destination;
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show("Could not copy the file:\n" + e);
                    }

                }
                else if (result == DialogResult.Cancel)
                {
                    shouldProceed = false;
                }
            }

            return shouldProceed;
        }
        private static void ShowErrorMessageBox(ref bool hasUserCancelled, ref string zipToUnpack, string message)
        {
            MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
            mbmb.MessageText = message;
            mbmb.AddButton("Look for the file in the default location", DialogResult.Yes);
            mbmb.AddButton("Select a .zip file to use", DialogResult.OK);
            mbmb.AddButton("Nothing - don't create a project", DialogResult.Cancel);
            var dialogResult = mbmb.ShowDialog();

            if (dialogResult == DialogResult.Yes)
            {
                // do nothing, it'll just look in the default location....
            }
            else if (dialogResult == DialogResult.OK)
            {
                OpenFileDialog fileDialog = new OpenFileDialog();
                fileDialog.InitialDirectory = "c:\\";
                fileDialog.Filter = "Zipped FRB template (*.zip)|*.zip";
                fileDialog.RestoreDirectory = true;

                if (fileDialog.ShowDialog() == DialogResult.OK)
                {
                    zipToUnpack = fileDialog.FileName;
                }
            }
            else if (dialogResult == DialogResult.Cancel)
            {
                hasUserCancelled = true;
            }
        }
Exemple #12
0
        private static DialogResult AskToReplaceOrRename()
        {
            MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
            mbmb.AddButton("Replace original file", DialogResult.Yes);
            mbmb.AddButton("Rename and reference renamed", DialogResult.No);

            mbmb.MessageText = "What would you like to do with the resized file?";

            return mbmb.ShowDialog();
        }
Exemple #13
0
        private static DialogResult AskWhatUserWantsToDo()
        {
            MultiButtonMessageBox mbmb;

            mbmb = new MultiButtonMessageBox();
            string message = "What would you like to do?";
            mbmb.MessageText = message;
            mbmb.AddButton("Pad to power of two", System.Windows.Forms.DialogResult.OK);
            mbmb.AddButton("Cancel", System.Windows.Forms.DialogResult.Cancel);

            return mbmb.ShowDialog();
        }
Exemple #14
0
        private void CheckForMissingCustomFile(BaseElementTreeNode baseElementTreeNode)
        {
            if (baseElementTreeNode != null)
            {
                IElement element = baseElementTreeNode.SaveObjectAsElement;

                string fileToSearchFor = FileManager.RelativeDirectory + element.Name + ".cs";

                if (!System.IO.File.Exists(fileToSearchFor))
                {
                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                    mbmb.MessageText = "The following file is missing\n\n" + fileToSearchFor + "\n\nwhich is used by\n\n" + element.ToString() + "\n\nWhat would you like to do?";
                    mbmb.AddButton("Re-create an empty custom code file", DialogResult.OK);
                    mbmb.AddButton("Ignore this problem", DialogResult.Cancel);

                    DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                    switch (result)
                    {
                        case DialogResult.OK:

                            CodeWriter.GenerateAndAddElementCustomCode(element);

                            break;
                        case DialogResult.Cancel:
                            // Ignore, do nothing
                            break;

                    }
                }

            }
        }
        private static void AskToRemoveCustomVariablesWithoutState(IElement element)
        {
            for(int i = 0; i < element.CustomVariables.Count; i++)
            {
                CustomVariable variable = element.CustomVariables[i];

                if (CustomVariableHelper.IsStateMissingFor(variable, element))
                {
                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                    mbmb.MessageText = "The variable\n" + variable + "\nno longer has any states associated with it.  What would you like to do?";

                    mbmb.AddButton("Remove the variable.", DialogResult.OK);
                    mbmb.AddButton("Nothing (project may not run until this is fixed)", DialogResult.Cancel);

                    if (mbmb.ShowDialog() == DialogResult.OK)
                    {
                        element.CustomVariables.RemoveAt(i);
                        i--;
                    }
                }
            }
        }
        void HandleTextureChanged(object sender, MemberChangeArgs memberChangeArgs)
        {
            // Justin has reported a bug here.  I don't know what is going on, so I'm going to spit out the error to a message box
            try
            {
                string fullFileName = memberChangeArgs.Value as string;
                string emitterDirectory = FileManager.GetDirectory(ProjectManager.Self.FileName);

                if (FileManager.IsRelative(fullFileName))
                {
                    // This file is relative.
                    // This means that the user
                    // typed in a value rather than
                    // using the file window.  We should
                    // assume that the file is relative to
                    // the emitter.
                    fullFileName = emitterDirectory + fullFileName;
                }

                if (!FileManager.IsRelativeTo(fullFileName, emitterDirectory))
                {
                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                    mbmb.MessageText = "The selected file:\n\n" + fullFileName + "\n\nis not relative to the Emitter file.  What would you like to do?";

                    mbmb.AddButton("Copy the file to the same folder as the Emitter file", System.Windows.Forms.DialogResult.Yes);
                    mbmb.AddButton("Keep the file where it is (this may limit the portability of the Emitter file)", System.Windows.Forms.DialogResult.No);

                    DialogResult result = mbmb.ShowDialog();

                    if (result == DialogResult.Yes)
                    {
                        string destination = emitterDirectory + FileManager.RemovePath(fullFileName);

                        try
                        {
                            System.IO.File.Copy(fullFileName, destination, true);
                            fullFileName = destination;
                        }
                        catch (Exception e)
                        {
                            MessageBox.Show("Could not copy the file:\n" + e);
                        }

                    }
                }

                string relativeFileName = FileManager.MakeRelative(fullFileName, emitterDirectory);

                SettingsSaveInstance.Texture = relativeFileName;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());

            }
        }
        private static void AskToPreserveVariables(EntitySave entitySave, List<CustomVariable> variablesBefore)
        {
            foreach (CustomVariable oldVariable in variablesBefore)
            {
                if (entitySave.GetCustomVariableRecursively(oldVariable.Name) == null)
                {
                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                    string message = "The variable\n\n" + oldVariable.ToString() + "\n\nIs no longer part of the Entity.  What do you want to do?";

                    mbmb.MessageText = message;

                    mbmb.AddButton("Add a new variable with the same name and type to " + entitySave.Name, DialogResult.Yes);
                    mbmb.AddButton("Nothing - the variable will go away", DialogResult.No);

                    DialogResult result = mbmb.ShowDialog();

                    if (result == DialogResult.Yes)
                    {
                        CustomVariable newVariable = new CustomVariable();
                        newVariable.Type = oldVariable.Type;
                        newVariable.Name = oldVariable.Name;
                        newVariable.DefaultValue = oldVariable.DefaultValue;
                        newVariable.SourceObject = oldVariable.SourceObject;
                        newVariable.SourceObjectProperty = oldVariable.SourceObjectProperty;

                        newVariable.Properties = new List<PropertySave>();
                        newVariable.Properties.AddRange(oldVariable.Properties);

                        newVariable.HasAccompanyingVelocityProperty = oldVariable.HasAccompanyingVelocityProperty;
                        newVariable.CreatesEvent = oldVariable.CreatesEvent;
                        newVariable.IsShared = oldVariable.IsShared;

                        if (!string.IsNullOrEmpty(oldVariable.OverridingPropertyType))
                        {
                            newVariable.OverridingPropertyType = oldVariable.OverridingPropertyType;
                            newVariable.TypeConverter = oldVariable.TypeConverter;
                        }

                        newVariable.CreatesEvent = oldVariable.CreatesEvent;

                        entitySave.CustomVariables.Add(newVariable);

                    }

                }
            }
        }
        private void ReactToChangedNosSourceName(NamedObjectSave namedObjectSave, string oldValue)
        {
            IElement container = EditorLogic.CurrentElement;

            if (!string.IsNullOrEmpty(container.BaseElement) && !string.IsNullOrEmpty(namedObjectSave.InstanceType))
            {
                IElement baseElement = ObjectFinder.Self.GetIElement(container.BaseElement);


                NamedObjectSave namedObjectInBase = baseElement.GetNamedObjectRecursively(namedObjectSave.InstanceName);


                if (namedObjectInBase == null)
                {
                    // This is not a valid setup - what do we do here?

                }
                else
                {
                    if (namedObjectInBase.InstanceType != namedObjectSave.InstanceType)
                    {
                        if (string.IsNullOrEmpty(namedObjectInBase.InstanceType))
                        {
                            string message = "This object has type of " + namedObjectSave.InstanceType +
                                " but the base object in " + baseElement.ToString() + " is untyped.  What would you like to do?";

                            MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                            mbmb.MessageText = message;

                            mbmb.AddButton("Change " + namedObjectInBase.InstanceName + " to " +
                                namedObjectSave.InstanceType + " in " + baseElement.ToString(), DialogResult.Yes);

                            mbmb.AddButton("Do nothing (your project will likely not compile so you will need to fix this manually)", DialogResult.No);

                            DialogResult result = mbmb.ShowDialog();

                            if (result == DialogResult.Yes)
                            {
                                switch (namedObjectInBase.SourceType)
                                {
                                    case SourceType.File:
                                        // The base needs to be a FlatRedBallType
                                        namedObjectInBase.SourceType = SourceType.FlatRedBallType;
                                        namedObjectInBase.SourceClassType = namedObjectSave.InstanceType;


                                        break;
                                    case SourceType.FlatRedBallType:
                                        namedObjectInBase.SourceType = SourceType.FlatRedBallType;
                                        namedObjectInBase.SourceClassType = namedObjectSave.SourceClassType;
                                        break;
                                    case SourceType.Entity:
                                        namedObjectInBase.SourceType = SourceType.Entity;
                                        namedObjectInBase.SourceClassType = namedObjectSave.SourceClassType;
                                        break;
                                }
                                namedObjectInBase.UpdateCustomProperties();

                                CodeWriter.GenerateCode(baseElement);

                            }
                        }
                        else
                        {
                            string message = "This object is of type " + namedObjectSave.InstanceType + " but the base " +
                                "object is of type " + namedObjectInBase.InstanceType + "";

                            MessageBox.Show(message);

                            namedObjectSave.SourceName = oldValue;

                        }
                    }
                }

            }
        }
        private static void ReactToChangedImplementsIVisible(object oldValue, EntitySave entitySave)
        {
            #region If the user turned IVisible off, see if there is a "Visible" Exposed Variable
            if (((bool)oldValue) == true)
            {
                CustomVariable variableToRemove = entitySave.GetCustomVariable("Visible");
                if (variableToRemove != null)
                {
                    List<string> throwawayList = new List<string>();

                    MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                    mbmb.MessageText = "This entity has a \"Visible\" variable exposed.  This variable is no longer valid.  What would you like to do?";
                    mbmb.AddButton("Remove this variable", DialogResult.Yes);
                    mbmb.AddButton("Keep this as a non-functional Variable (it will no longer control the object's visibility)", DialogResult.No);

                    DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                    if (result == DialogResult.Yes)
                    {
                        ProjectManager.RemoveCustomVariable(variableToRemove, throwawayList);
                    }
                    else
                    {
                        // No need to do anything
                    }
                }
            }
            #endregion

            #region If the user turned IVisible on, see if there are any NamedObjectSaves that reference Elements that are not IVisible

            if (entitySave.ImplementsIVisible)
            {
                foreach (NamedObjectSave nos in entitySave.AllNamedObjects)
                {
                    if (nos.SourceType == SourceType.Entity || nos.IsList)
                    {

                        EntitySave nosEntitySave = null;

                        if (nos.SourceType == SourceType.Entity)
                        {
                            nosEntitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassType);
                        }
                        else
                        {
                            nosEntitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassGenericType);
                        }

                        if (nosEntitySave != null && nosEntitySave.ImplementsIVisible == false)
                        {
                            MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                            mbmb.MessageText = entitySave + " implements IVisible, but its object " + nos + " does not.  Would would you like to do?";

                            mbmb.AddButton("Make " + nosEntitySave + " implement IVisible", DialogResult.Yes);
                            mbmb.AddButton("Ignore " + nos + " when setting Visible on " + entitySave, DialogResult.No);
                            mbmb.AddButton("Do nothing - this will likely cause compile errors so this must be fixed manually", DialogResult.Cancel);

                            DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                            if (result == DialogResult.Yes)
                            {
                                nosEntitySave.ImplementsIVisible = true;

                                CodeGeneratorIElement.GenerateElementDerivedAndReferenced(nosEntitySave);
                            }
                            else if (result == DialogResult.No)
                            {
                                nos.IncludeInIVisible = false;
                            }
                            else if (result == DialogResult.Cancel)
                            {
                                // do nothing - the user better fix this!
                            }
                        }
                    }
                }
            }
            #endregion

            #region If it's a ScrollableEntityList, then the item it's using must also be an IVisible

            if (entitySave.ImplementsIVisible && entitySave.IsScrollableEntityList && !string.IsNullOrEmpty(entitySave.ItemType))
            {
                EntitySave itemTypeAsEntity = ObjectFinder.Self.GetEntitySave(entitySave.ItemType);

                if (itemTypeAsEntity != null && itemTypeAsEntity.ImplementsIVisible == false)
                {
                    MessageBox.Show("The item type " + itemTypeAsEntity.ToString() + " must also implement IVisible.  Glue will do this now");

                    itemTypeAsEntity.ImplementsIVisible = true;

                    // Gotta regen this thing
                    var entityForItem = ObjectFinder.Self.GetIElement(entitySave.ItemType);
                    CodeWriter.GenerateCode(entityForItem);
                }
            }

            #endregion
        }
Exemple #20
0
        public void RemoveReferencedFile(ReferencedFileSave referencedFileToRemove, List<string> additionalFilesToRemove, bool regenerateCode)
        {
            // There are some things that need to happen:
            // 1.  Remove the ReferencedFileSave from the Glue project (GLUX)
            // 2.  Remove the GUI item
            // 3.  Remove the item from the Visual Studio project.

            #region Remove the file from the current Screen or Entity if there is a current Screen or Entity

            IElement container = referencedFileToRemove.GetContainer();

            if (container != null)
            {
                // The referenced file better be a globally referenced file


                if (!container.ReferencedFiles.Contains(referencedFileToRemove))
                {
                    throw new ArgumentException();
                }
                else
                {
                    container.ReferencedFiles.Remove(referencedFileToRemove);

                }
                // Ask about any NamedObjects that reference this file.                
                for (int i = container.NamedObjects.Count - 1; i > -1; i--)
                {
                    var nos = container.NamedObjects[i];
                    if (nos.SourceType == SourceType.File && nos.SourceFile == referencedFileToRemove.Name)
                    {
                        MainGlueWindow.Self.Invoke(() =>
                            {
                                // Ask the user what to do here - remove it?  Keep it and not compile?
                                MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                                mbmb.MessageText = "The object\n" + nos.ToString() + "\nreferences the file\n" + referencedFileToRemove.Name +
                                    "\nWhat would you like to do?";
                                mbmb.AddButton("Remove this object", DialogResult.Yes);
                                mbmb.AddButton("Keep it (object will not be valid until changed)", DialogResult.No);

                                var result = mbmb.ShowDialog();

                                if (result == DialogResult.Yes)
                                {
                                    container.NamedObjects.RemoveAt(i);
                                }
                            });
                    }
                    nos.ResetVariablesReferencing(referencedFileToRemove);
                }

                MainGlueWindow.Self.Invoke(() =>
                    {
                        if (EditorLogic.CurrentScreenTreeNode != null)
                        {
                            EditorLogic.CurrentScreenTreeNode.UpdateReferencedTreeNodes();
                        }
                        else if (EditorLogic.CurrentEntityTreeNode != null)
                        {
                            EditorLogic.CurrentEntityTreeNode.UpdateReferencedTreeNodes(false);
                        }
                        if (regenerateCode)
                        {
                            ElementViewWindow.GenerateSelectedElementCode();
                        }
                    });
                
            }
            #endregion

            #region else, the file is likely part of the GlobalContentFile

            else
            {
                ProjectManager.GlueProjectSave.GlobalFiles.Remove(referencedFileToRemove);
                ProjectManager.GlueProjectSave.GlobalContentHasChanged = true;

                // Much faster to just remove the tree node.  This was done
                // to reuse code and make things reactive, but this has gotten
                // slow on bigger projects.
                //ElementViewWindow.UpdateGlobalContentTreeNodes(false); // don't save here because projects will get saved below 

                Action refreshUiAction = () =>
                {
                    TreeNode treeNode = GlueState.Self.Find.ReferencedFileSaveTreeNode(referencedFileToRemove);

                    if (treeNode.Tag != referencedFileToRemove)
                    {
                        throw new Exception("Error removing the tree node - the selected tree node doesn't reference the file being removed");
                    }

                    treeNode.Parent.Nodes.Remove(treeNode);
                };

                MainGlueWindow.Self.Invoke((MethodInvoker)delegate
                    {
                        refreshUiAction();
                    }
                    );


                ContentLoadWriter.UpdateLoadGlobalContentCode();

                List<IElement> elements = ObjectFinder.Self.GetAllElementsReferencingFile(referencedFileToRemove.Name);

                foreach (IElement element in elements)
                {
                    if (regenerateCode)
                    {
                        CodeWriter.GenerateCode(element);
                    }
                }
            }

            #endregion


            // November 10, 2015
            // I feel like this may
            // have been old code before
            // we had full dependency tracking
            // in Glue. This file should only be
            // removed from the project if nothing
            // else references it, including no entities.
            // This code does just entities/screens/global
            // content, but doesn't check the full dependency
            // tree. I think we can just remove it and depend on
            // the code below.
            // Actually, removing this seems to cause problems - files
            // that should be removed aren't. So instead we'll chnage the
            // call to use the dependency tree:
            // replace:

            List<string> referencedFiles =
                GlueCommands.Self.FileCommands.GetAllReferencedFileNames().Select(item=>item.ToLowerInvariant()).ToList();

            string absoluteToLower = GlueCommands.Self.GetAbsoluteFileName(referencedFileToRemove).ToLowerInvariant();
            string relativeToProject = FileManager.MakeRelative(absoluteToLower, GlueState.Self.ContentDirectory);

            bool isReferencedByOtherContent = referencedFiles.Contains(relativeToProject);

            if (isReferencedByOtherContent == false)
            {
                additionalFilesToRemove.Add(referencedFileToRemove.GetRelativePath());

                string itemName = referencedFileToRemove.GetRelativePath();
                string absoluteName = ProjectManager.MakeAbsolute(referencedFileToRemove.Name, true);

                // I don't know why we were removing the file from the ProjectBase - it should
                // be from the Content project
                //ProjectManager.RemoveItemFromProject(ProjectManager.ProjectBase, itemName);
                ProjectManager.RemoveItemFromProject(ProjectManager.ProjectBase.ContentProject, itemName, performSave: false);

                foreach (ProjectBase syncedProject in ProjectManager.SyncedProjects)
                {
                    ProjectManager.RemoveItemFromProject(syncedProject.ContentProject, absoluteName);
                }
            }



            if (ProjectManager.IsContent(referencedFileToRemove.GetRelativePath()))
            {

                UnreferencedFilesManager.Self.RefreshUnreferencedFiles(false);
                foreach (var file in UnreferencedFilesManager.LastAddedUnreferencedFiles)
                {
                    additionalFilesToRemove.Add(file.FilePath);
                }
            }

            ReactToRemovalIfCsv(referencedFileToRemove, additionalFilesToRemove);

            GluxCommands.Self.SaveGlux();
        }
        public static void RemoveNamedObject(NamedObjectSave namedObjectToRemove, bool performSave, bool updateUi, List<string> additionalFilesToRemove)
        {
            StringBuilder removalInformation = new StringBuilder();

            // The additionalFilesToRemove is included for consistency with other methods.  It may be used later

            // There are the following things that need to happen:
            // 1.  Remove the NamedObject from the Glue project (GLUX)
            // 2.  Remove any variables that use this NamedObject as their source
            // 3.  Remove the named object from the GUI
            // 4.  Update the variables for any NamedObjects that use this element containing this NamedObject
            // 5.  Find any Elements that contain NamedObjects that are DefinedByBase - if so, see if we should remove those or make them not DefinedByBase
            // 6.  Remove any events that tunnel into this.

            IElement element = namedObjectToRemove.GetContainer();

            if (element != null)
            {

                if (!namedObjectToRemove.RemoveSelfFromNamedObjectList(element.NamedObjects))
                {
                    throw new ArgumentException();
                }

                #region Remove all CustomVariables that reference the removed NamedObject
                for (int i = element.CustomVariables.Count - 1; i > -1; i--)
                {
                    CustomVariable variable = element.CustomVariables[i];

                    if (variable.SourceObject == namedObjectToRemove.InstanceName)
                    {
                        removalInformation.AppendLine("Removed variable " + variable.ToString());

                        element.CustomVariables.RemoveAt(i);
                    }
                }
                #endregion

                // Remove any events that use this
                for (int i = element.Events.Count - 1; i > -1; i--)
                {
                    EventResponseSave ers = element.Events[i];
                    if (ers.SourceObject == namedObjectToRemove.InstanceName)
                    {
                        removalInformation.AppendLine("Removed event " + ers.ToString());
                        element.Events.RemoveAt(i);
                    }
                }

                // Remove any objects that use this as a layer
                for (int i = 0; i < element.NamedObjects.Count; i++)
                {
                    if (element.NamedObjects[i].LayerOn == namedObjectToRemove.InstanceName)
                    {
                        removalInformation.AppendLine("Removed the following object from the deleted Layer: " + element.NamedObjects[i].ToString());
                        element.NamedObjects[i].LayerOn = null;
                    }
                }




                element.RefreshStatesToCustomVariables();

                #region Ask the user what to do with all NamedObjects that are DefinedByBase

                List<IElement> derivedElements = new List<IElement>();
                if (element is EntitySave)
                {
                    derivedElements.AddRange(ObjectFinder.Self.GetAllEntitiesThatInheritFrom(element as EntitySave));
                }
                else
                {
                    derivedElements.AddRange(ObjectFinder.Self.GetAllScreensThatInheritFrom(element as ScreenSave));
                }

                foreach (IElement derivedElement in derivedElements)
                {
                    // At this point, namedObjectToRemove is already removed from the current Element, so this will only
                    // return NamedObjects that exist in the derived.
                    NamedObjectSave derivedNamedObject = derivedElement.GetNamedObjectRecursively(namedObjectToRemove.InstanceName);

                    if (derivedNamedObject != null && derivedNamedObject != namedObjectToRemove && derivedNamedObject.DefinedByBase)
                    {
                        MultiButtonMessageBox mbmb = new MultiButtonMessageBox();
                        mbmb.MessageText = "What would you like to do with the object " + derivedNamedObject.ToString();
                        mbmb.AddButton("Keep it", DialogResult.OK);
                        mbmb.AddButton("Delete it", DialogResult.Cancel);

                        DialogResult result = mbmb.ShowDialog(MainGlueWindow.Self);

                        if (result == DialogResult.OK)
                        {
                            // Keep it
                            derivedNamedObject.DefinedByBase = false;
                            BaseElementTreeNode treeNode = GlueState.Self.Find.ElementTreeNode(derivedElement);

                            if (updateUi)
                            {
                                treeNode.UpdateReferencedTreeNodes();
                            }
                            CodeWriter.GenerateCode(derivedElement);
                        }
                        else
                        {
                            // Delete it
                            RemoveNamedObject(derivedNamedObject, performSave, updateUi, additionalFilesToRemove);
                        }


                    }

                }
                #endregion


                if (element is ScreenSave)
                {
                    ScreenTreeNode stn = GlueState.Self.Find.ScreenTreeNode(element as ScreenSave);
                    if (updateUi)
                    {
                        stn.UpdateReferencedTreeNodes();
                    }
                    CodeWriter.GenerateCode(element);
                }
                else
                {
                    EntityTreeNode etn = GlueState.Self.Find.EntityTreeNode(element as EntitySave);
                    if (updateUi)
                    {
                        etn.UpdateReferencedTreeNodes();
                    }
                    CodeWriter.GenerateCode(element);

                    List<NamedObjectSave> entityNamedObjects = ObjectFinder.Self.GetAllNamedObjectsThatUseEntity(element.Name);

                    foreach (NamedObjectSave nos in entityNamedObjects)
                    {
                        nos.UpdateCustomProperties();
                    }
                }




            }

            if (performSave)
            {
                GluxCommands.Self.SaveGlux();
            }
        }