private static void WriteGetterForProperty(CustomVariable customVariable, IElement element, ICodeBlock prop)
        {
            var getter = prop.Get();

            if (customVariable.GetIsSourceFile(element))
            {
                getter.Line("return " + customVariable.SourceObject +";");
            }
            else
            {

                string relativeVersionOfProperty = InstructionManager.GetRelativeForAbsolute(customVariable.SourceObjectProperty);

                if (!string.IsNullOrEmpty(relativeVersionOfProperty))
                {
                    getter = getter.If(customVariable.SourceObject + ".Parent == null");
                }

                string valueToReturn = customVariable.SourceObject + "." + customVariable.SourceObjectProperty;
                if (!string.IsNullOrEmpty(customVariable.OverridingPropertyType) &&
                    // If overriding to the same type, no conversion can be performed
                    customVariable.OverridingPropertyType != customVariable.Type)
                {
                    valueToReturn = TypeConverterHelper.Convert(
                        customVariable, GetterOrSetter.Getter, valueToReturn);
                }
                if (!string.IsNullOrEmpty(valueToReturn))
                {
                    getter.Line("return " + valueToReturn + ";");
                }
                else
                {
                    getter.Line("throw new System.Exception();");
                }



                if (!string.IsNullOrEmpty(relativeVersionOfProperty))
                {
                    getter = getter.End().Else();

                    valueToReturn = customVariable.SourceObject + "." + relativeVersionOfProperty;
                    if (!string.IsNullOrEmpty(customVariable.OverridingPropertyType))
                    {
                        valueToReturn = TypeConverterHelper.Convert(
                            customVariable, GetterOrSetter.Getter, valueToReturn);
                    }


                    getter.Line("return " + valueToReturn + ";");
                    getter.End();
                }
            }
        }
        private static void WriteSetterForProperty(IElement saveObject, CustomVariable customVariable, ICodeBlock prop, bool isVisibleSetterOnList)
        {
            var setter = prop.Set();

            if (EventCodeGenerator.ShouldGenerateEventsForVariable(customVariable, saveObject))
            {
                EventCodeGenerator.GenerateEventRaisingCode(setter, BeforeOrAfter.Before, customVariable.Name, saveObject);
            }

            NamedObjectSave nos = saveObject.GetNamedObjectRecursively(customVariable.SourceObject);

            bool addOrRemoveOnValueChange = nos.RemoveFromManagersWhenInvisible && customVariable.SourceObjectProperty == "Visible";

            if (isVisibleSetterOnList)
            {
                setter.Line(customVariable.SourceObject + ".SetVisible(value);");
            }
            else if(customVariable.GetIsSourceFile(saveObject))
            {
                // We need to assign the property here on the NamedObjectSave, as if it's done in code in the AddToManagersBottomUp

                // We need to temporarily make the NOS act as if it's using the argument file as its SourceFile
                var oldSourceType = nos.SourceType;
                var oldSourceFile = nos.SourceFile;
                var oldSourceName = nos.SourceName;
                nos.SourceType = SourceType.File;
                nos.SourceFile = "value";
                nos.SourceName = "Entire File (" + customVariable.Type  + ")";

                
                NamedObjectSaveCodeGenerator.WriteCodeForNamedObjectInitialize(nos, saveObject, setter, "value");//WriteAddToManagersForNamedObject(saveObject, nos, setter);

                bool storeOldValue = nos.RemoveFromManagersWhenInvisible && customVariable.SourceObjectProperty == "Visible";

                bool canBeLayered = false;
                if (nos.GetAssetTypeInfo() != null)
                {
                    canBeLayered = nos.GetAssetTypeInfo().LayeredAddToManagersMethod.Count != 0;
                }


                if (canBeLayered)
                {
                    // This object may be 
                    // added to a Layer.  We
                    // will add it to the NOS's
                    // Layer if there is one.  If 
                    // not, we'll use the object's
                    // Layer
                    string layerName;
                    if (!string.IsNullOrEmpty(nos.LayerOn))
                    {
                        layerName = nos.LayerOn;
                    }
                    else if (saveObject is EntitySave)
                    {
                        layerName = "LayerProvidedByContainer";
                    }
                    else
                    {
                        // I don't remember if Screens
                        // have a Layer that they use by
                        // default.  If so, this has probably
                        // fallen out of style because of Glue.
                        layerName = "null";
                    }

                    // Glue has no way of knowing whether this property will be used or not:
                    setter.Line("#pragma warning disable");
                    setter.Line("");
                    setter.Line("FlatRedBall.Graphics.Layer layerToAddTo = " + layerName + ";");
                    setter.Line("#pragma warning enable");
                    // Wow, so crazy, but the automated
                    // tests revealed that the line following
                    // the #pragma wasn't ever being run on iOS.
                    // I suspect it has to do with line endings after
                    // the #pragma line?  Anyway, putting a new line in
                    // seems to fix the bug.
                    setter.Line("");
                }

                NamedObjectSaveCodeGenerator.WriteAddToManagersForNamedObject(saveObject, nos, setter, true);

                nos.SourceType = oldSourceType;
                nos.SourceFile = oldSourceFile;
                nos.SourceName = oldSourceName;
            }
            else
            {

                string relativeVersionOfProperty = InstructionManager.GetRelativeForAbsolute(customVariable.SourceObjectProperty);
                if (!string.IsNullOrEmpty(relativeVersionOfProperty))
                {
                    setter = setter.If(customVariable.SourceObject + ".Parent == null");
                }

                string value = "value";

                if (!string.IsNullOrEmpty(customVariable.OverridingPropertyType) &&
                    // If the overriding type is the same as the variable type then no conversion can be performed
                    customVariable.OverridingPropertyType != customVariable.Type)
                {
                    value = TypeConverterHelper.Convert(
                        customVariable, GetterOrSetter.Setter, value);
                }

                bool recordChange = nos.RemoveFromManagersWhenInvisible;

                

                string leftSide = customVariable.SourceObject + "." + customVariable.SourceObjectProperty;


                if (addOrRemoveOnValueChange)
                {
                    setter.Line("var oldValue = " + leftSide + ";");
                }
                setter.Line(leftSide + " = " + value + ";");

                if (!string.IsNullOrEmpty(relativeVersionOfProperty))
                {
                    setter = setter.End().Else();
                    setter.Line(customVariable.SourceObject + "." + relativeVersionOfProperty + " = " + value + ";");
                    setter = setter.End();
                }
            }

            if (addOrRemoveOnValueChange)
            {
                string leftSide = customVariable.SourceObject + "." + customVariable.SourceObjectProperty;

                var outerIf = setter.If("oldValue != " + leftSide);
                var ifNotValue = outerIf.If("!value");

                // write remove from managers!


                NamedObjectSaveCodeGenerator.GenerateRemoveFromManagersForNamedObject(
                    saveObject,
                    nos,
                    ifNotValue);
                // remove from managers

                var elseIfValue = outerIf.Else();
                NamedObjectSaveCodeGenerator.WriteAddToManagersForNamedObject(
                    saveObject,
                    nos,
                    elseIfValue,
                    false, false);
                //NamedObjectSaveCodeGenerator

            }

            if (EventCodeGenerator.ShouldGenerateEventsForVariable(customVariable, saveObject))
            {

                EventCodeGenerator.GenerateEventRaisingCode(setter, BeforeOrAfter.After, customVariable.Name, saveObject);
            }
        }