public XcodeFrameworkRef(XcodeFramework InFramework)
 {
     Guid = XcodeProjectFileGenerator.MakeXcodeGuid();
     Framework = InFramework;
 }
        /// <summary>
        /// Writes the project files to disk
        /// </summary>
        /// <returns>True if successful</returns>
        protected override bool WriteProjectFiles()
        {
            Log.TraceInformation("Generating project file...");

            // Setup project file content
            var XcodeProjectFileContent = new StringBuilder();

            XcodeProjectFileContent.Append(
                "// !$*UTF8*$!" + ProjectFileGenerator.NewLine +
                "{" + ProjectFileGenerator.NewLine +
                "\tarchiveVersion = 1;" + ProjectFileGenerator.NewLine +
                "\tclasses = {" + ProjectFileGenerator.NewLine +
                "\t};" + ProjectFileGenerator.NewLine +
                "\tobjectVersion = 46;" + ProjectFileGenerator.NewLine +
                "\tobjects = {" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            // attempt to determine targets for the project
            List<XcodeProjectTarget> ProjectTargets = new List<XcodeProjectTarget>();
            // add mandatory ones
            XcodeProjectTarget UE4ProjectTarget = new XcodeProjectTarget("UE4", "UE4", XcodeTargetType.Project, "");
            XcodeProjectTarget UE4XcodeHelperTarget = new XcodeProjectTarget("UE4XcodeHelper", "UE4XcodeHelper", XcodeTargetType.XcodeHelper, "", "libUE4XcodeHelper.a");
            ProjectTargets.AddRange(new XcodeProjectTarget[] { UE4ProjectTarget, UE4XcodeHelperTarget });

            if (ProjectFilePlatform.HasFlag(XcodeProjectFilePlatform.iOS))
            {
                XcodeProjectTarget UE4CmdLineRunTarget = new XcodeProjectTarget("UE4CmdLineRun", "UE4CmdLineRun", XcodeTargetType.XCTest, "", "UE4CmdLineRun.xctest", STTargetPlatform.IOS);
                ProjectTargets.Add(UE4CmdLineRunTarget);
                // This GUID will be referenced by each app's test action.
                UE4CmdLineGuid = UE4CmdLineRunTarget.Guid;
            }

            List<XcodeTargetDependency> TargetDependencies = new List<XcodeTargetDependency>();
            List<XcodeContainerItemProxy> ContainerItemProxies = new List<XcodeContainerItemProxy>();
            List<XcodeFramework> Frameworks = new List<XcodeFramework>();
            Frameworks.Add(new XcodeFramework("OpenGLES.framework", "System/Library/Frameworks/OpenGLES.framework", "SDKROOT"));
            // @todo metal: putting this into the project will make for VERY slow Metal runtime by default...
            //			Frameworks.Add(new XcodeFramework("Metal.framework", "System/Library/Frameworks/Metal.framework", "SDKROOT"));

            XcodeFramework XCTestFramework = new XcodeFramework("XCTest.framework", "Library/Frameworks/XCTest.framework", "DEVELOPER_DIR");
            Frameworks.Add(XCTestFramework);

            var AllTargets = DiscoverTargets();

            PopulateTargets(AllTargets, ProjectTargets, ContainerItemProxies, TargetDependencies, UE4ProjectTarget, Frameworks);

            Log.TraceInformation(string.Format("Found {0} targets!", ProjectTargets.Count));

            string PBXBuildFileSection = "/* Begin PBXBuildFile section */" + ProjectFileGenerator.NewLine;
            string PBXFileReferenceSection = "/* Begin PBXFileReference section */" + ProjectFileGenerator.NewLine;
            string PBXResourcesBuildPhaseSection = "/* Begin PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine;
            string PBXSourcesBuildPhaseSection = "/* Begin PBXSourcesBuildPhase section */" + ProjectFileGenerator.NewLine;
            string PBXFrameworksBuildPhaseSection = "/* Begin PBXFrameworksBuildPhase section */" + ProjectFileGenerator.NewLine;
            string PBXShellScriptBuildPhaseSection = "/* Begin PBXShellScriptBuildPhase section */" + ProjectFileGenerator.NewLine;
            Dictionary<string, XcodeFileGroup> Groups = new Dictionary<string, XcodeFileGroup>();
            List<string> IncludeDirectories = new List<string>();
            List<string> SystemIncludeDirectories = new List<string>();
            List<string> PreprocessorDefinitions = new List<string>();

            foreach (XcodeFramework Framework in Frameworks)
            {
                // Add file references.
                PBXFileReferenceSection += "\t\t" + Framework.Guid + " /* " + Framework.Name + " */ = {"
                                         + "isa = PBXFileReference; "
                                         + "lastKnownFileType = wrapper.framework; "
                                         + "name = " + Framework.Name + "; "
                                         + "path = " + Framework.Path + "; "
                                         + "sourceTree = " + Framework.SourceTree + "; "
                                         + "};" + ProjectFileGenerator.NewLine;
            }

            // Set up all the test guids that need to be explicitly referenced later
            string UE4CmdLineRunMFileGuid = MakeXcodeGuid();
            UE4CmdLineRunMFileRefGuid = MakeXcodeGuid();
            string XCTestBuildFileGUID = MakeXcodeGuid();

            string TestFrameworkFiles = "\t\t\t\t" + XCTestBuildFileGUID + " /* XCTest.framework in Frameworks */," + ProjectFileGenerator.NewLine;
            PBXBuildFileSection += "\t\t" + XCTestBuildFileGUID + " /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; "
                + "fileRef = " + XCTestFramework.Guid + " /* UE4CmdLineRun.m */; };" + ProjectFileGenerator.NewLine;

            AppendBuildPhases(ProjectTargets, ref PBXBuildFileSection, ref PBXFileReferenceSection, ref PBXSourcesBuildPhaseSection, ref PBXResourcesBuildPhaseSection, ref PBXFrameworksBuildPhaseSection,
                ref PBXShellScriptBuildPhaseSection, TestFrameworkFiles, UE4CmdLineRunMFileGuid);

            AppendSourceFiles(ProjectTargets, ref PBXBuildFileSection, ref PBXFileReferenceSection, ref PBXSourcesBuildPhaseSection, ref Groups, UE4XcodeHelperTarget, UE4CmdLineRunMFileGuid,
                ref IncludeDirectories, ref SystemIncludeDirectories, ref PreprocessorDefinitions);

            foreach (XcodeProjectTarget Target in ProjectTargets)
            {
                if ((Target.Type == XcodeTargetType.Native || Target.Type == XcodeTargetType.XCTest))
                {
                    string FileType = Target.Type == XcodeTargetType.Native ? "wrapper.application" : "wrapper.cfbundle";
                    string PayloadDir = "Engine";
                    if (Target.Type == XcodeTargetType.Native && Target.TargetName != "UE4Game")
                    {
                        PayloadDir = Target.TargetName;
                    }

                    PBXFileReferenceSection += "\t\t" + Target.ProductGuid + " /* " + Target.ProductName + " */ = {isa = PBXFileReference; explicitFileType = " + FileType + "; includeInIndex = 0; path = " + PayloadDir + "/Binaries/IOS/Payload/" + Target.ProductName + "; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
                    if (!string.IsNullOrEmpty(Target.PlistGuid))
                    {
                        PBXFileReferenceSection += "\t\t" + Target.PlistGuid + " /* " + Target.TargetName + "-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"" + Target.TargetName + "-Info.plist\"; path = " + Target.TargetName + "/Build/IOS/" + Target.TargetName + "-Info.plist; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
                    }
                }
            }

            if (bGeneratingRunIOSProject)
            {
                AppendReferenceGroups(ref PBXFileReferenceSection, ref Groups);
            }

            PBXBuildFileSection += "/* End PBXBuildFile section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXFileReferenceSection += "/* End PBXFileReference section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            PBXResourcesBuildPhaseSection += "/* End PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXSourcesBuildPhaseSection += "/* End PBXSourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXFrameworksBuildPhaseSection += "/* End PBXFrameworksBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXShellScriptBuildPhaseSection += "/* End PBXShellScriptBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            string PBXTargetDependencySection = "/* Begin PBXTargetDependency section */" + ProjectFileGenerator.NewLine;
            CreateTargetDependencySection(ref PBXTargetDependencySection, TargetDependencies);
            PBXTargetDependencySection += "/* End PBXTargetDependency section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            string PBXContainerItemProxySection = "/* Begin PBXContainerItemProxy section */" + ProjectFileGenerator.NewLine;
            CreateContainerItemProxySection(ref PBXContainerItemProxySection, ContainerItemProxies);
            PBXContainerItemProxySection += "/* End PBXContainerItemProxy section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            XcodeProjectFileContent.Append(PBXBuildFileSection);
            XcodeProjectFileContent.Append(PBXFileReferenceSection);
            XcodeProjectFileContent.Append(PBXContainerItemProxySection);
            XcodeProjectFileContent.Append(PBXTargetDependencySection);

            AppendGroups(ref XcodeProjectFileContent, ref Groups, ProjectTargets, Frameworks);

            XcodeProjectFileContent.Append(PBXShellScriptBuildPhaseSection);
            XcodeProjectFileContent.Append(PBXSourcesBuildPhaseSection);
            XcodeProjectFileContent.Append(PBXFrameworksBuildPhaseSection);

            XcodeProjectFileContent.Append("/* Begin PBXLegacyTarget section */" + ProjectFileGenerator.NewLine);
            foreach (var Target in ProjectTargets)
            {
                if (Target.Type == XcodeTargetType.Legacy)
                {
                    AppendTarget(ref XcodeProjectFileContent, Target);
                }
            }
            XcodeProjectFileContent.Append("/* End PBXLegacyTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append("/* Begin PBXNativeTarget section */" + ProjectFileGenerator.NewLine);
            AppendTarget(ref XcodeProjectFileContent, UE4XcodeHelperTarget);

            foreach (XcodeProjectTarget Target in ProjectTargets)
            {
                if (Target.Type == XcodeTargetType.Native || Target.Type == XcodeTargetType.XCTest)
                {
                    AppendTarget(ref XcodeProjectFileContent, Target);
                }
            }
            XcodeProjectFileContent.Append("/* End PBXNativeTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append(
                "/* Begin PBXProject section */" + ProjectFileGenerator.NewLine +
                "\t\t" + UE4ProjectTarget.Guid + " /* Project object */ = {" + ProjectFileGenerator.NewLine +
                "\t\t\tisa = PBXProject;" + ProjectFileGenerator.NewLine +
                "\t\t\tattributes = {" + ProjectFileGenerator.NewLine +
                "\t\t\t\tLastUpgradeCheck = 0510;" + ProjectFileGenerator.NewLine +
                "\t\t\t\tORGANIZATIONNAME = EpicGames;" + ProjectFileGenerator.NewLine +
                "\t\t\t};" + ProjectFileGenerator.NewLine +
                "\t\t\tbuildConfigurationList = " + UE4ProjectTarget.BuildConfigGuild + " /* Build configuration list for PBXProject \"" + UE4ProjectTarget.DisplayName + "\" */;" + ProjectFileGenerator.NewLine +
                "\t\t\tcompatibilityVersion = \"Xcode 3.2\";" + ProjectFileGenerator.NewLine +
                "\t\t\tdevelopmentRegion = English;" + ProjectFileGenerator.NewLine +
                "\t\t\thasScannedForEncodings = 0;" + ProjectFileGenerator.NewLine +
                "\t\t\tknownRegions = (" + ProjectFileGenerator.NewLine +
                "\t\t\t\ten," + ProjectFileGenerator.NewLine +
                "\t\t\t);" + ProjectFileGenerator.NewLine +
                "\t\t\tmainGroup = " + MainGroupGuid + ";" + ProjectFileGenerator.NewLine +
                "\t\t\tproductRefGroup = " + ProductRefGroupGuid + " /* Products */;" + ProjectFileGenerator.NewLine +
                "\t\t\tprojectDirPath = \"\";" + ProjectFileGenerator.NewLine +
                "\t\t\tprojectRoot = \"\";" + ProjectFileGenerator.NewLine +
                "\t\t\ttargets = (" + ProjectFileGenerator.NewLine
            );

            foreach (var Target in ProjectTargets)
            {
                if (Target != UE4ProjectTarget)
                {
                    XcodeProjectFileContent.AppendLine(string.Format("\t\t\t\t{0} /* {1} */,", Target.Guid, Target.DisplayName));
                }
            }

            XcodeProjectFileContent.Append(
                "\t\t\t);" + ProjectFileGenerator.NewLine +
                "\t\t};" + ProjectFileGenerator.NewLine +
                "/* End PBXProject section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine
            );

            string PreprocessorDefinitionsString = "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (" + ProjectFileGenerator.NewLine;
            foreach (string Definition in PreprocessorDefinitions)
            {
                PreprocessorDefinitionsString += "\t\t\t\t\t\"" + Definition + "\"," + ProjectFileGenerator.NewLine;
            }
            PreprocessorDefinitionsString += "\t\t\t\t\t\"MONOLITHIC_BUILD=1\"," + ProjectFileGenerator.NewLine;
            PreprocessorDefinitionsString += "\t\t\t\t);" + ProjectFileGenerator.NewLine;

            string HeaderSearchPaths = "\t\t\t\tHEADER_SEARCH_PATHS = (" + ProjectFileGenerator.NewLine;
            foreach (string Path in SystemIncludeDirectories)
            {
                HeaderSearchPaths += "\t\t\t\t\t\"" + Path + "\"," + ProjectFileGenerator.NewLine;
            }
            HeaderSearchPaths += "\t\t\t\t);" + ProjectFileGenerator.NewLine;
            HeaderSearchPaths += "\t\t\t\tUSER_HEADER_SEARCH_PATHS = (" + ProjectFileGenerator.NewLine;
            foreach (string Path in IncludeDirectories)
            {
                HeaderSearchPaths += "\t\t\t\t\t\"" + Path + "\"," + ProjectFileGenerator.NewLine;
            }
            HeaderSearchPaths += "\t\t\t\t);" + ProjectFileGenerator.NewLine;

            XcodeProjectFileContent.Append("/* Begin XCBuildConfiguration section */" + ProjectFileGenerator.NewLine);
            AppendBuildConfigs(ref XcodeProjectFileContent, UE4ProjectTarget, HeaderSearchPaths, PreprocessorDefinitionsString);
            foreach (var Target in ProjectTargets)
            {
                if (Target.Type != XcodeTargetType.Project && Target.Type != XcodeTargetType.XcodeHelper)
                {
                    AppendBuildConfigs(ref XcodeProjectFileContent, Target);
                }
            }

            AppendBuildConfigs(ref XcodeProjectFileContent, UE4XcodeHelperTarget);

            XcodeProjectFileContent.Append("/* End XCBuildConfiguration section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append("/* Begin XCConfigurationList section */" + ProjectFileGenerator.NewLine);

            foreach (var Target in ProjectTargets)
            {
                if (Target.Type != XcodeTargetType.XcodeHelper)
                {
                    AppendConfigList(ref XcodeProjectFileContent, Target);
                }
            }

            AppendConfigList(ref XcodeProjectFileContent, UE4XcodeHelperTarget);

            XcodeProjectFileContent.Append("/* End XCConfigurationList section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append(
                "\t};" + ProjectFileGenerator.NewLine +
                "\trootObject = " + UE4ProjectTarget.Guid + " /* Project object */;" + ProjectFileGenerator.NewLine +
                "}" + ProjectFileGenerator.NewLine);

            WriteProject(XcodeProjectFileContent, ProjectTargets);

            // TODO: add any content for any files in the workspace here
            WriteWorkspace();

            return true;
        }