static void RestoreCrossSceneReferences()
		{
			Scene activeScene = new Scene();
			AmsMultiSceneSetup activeSetup = null;
			List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>();

			GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes );
			if ( bakedScenes.Count < 1 )
				return;

			AmsDebug.Log( null, "Running RestoreCrossSceneReferences on Scene {0}", activeScene.name );

			// Do the merge (bake)
			var targetCrossRefs = AmsCrossSceneReferences.GetSceneSingleton( activeScene, false );
			if ( targetCrossRefs )
				targetCrossRefs.ResolvePendingCrossSceneReferences();

			foreach( var entry in bakedScenes )
			{
				if ( !entry.scene.isLoaded )
				{
					AmsDebug.LogError( activeSetup, "Could not restore cross-scene references for non-loaded scene: {0}", entry.scene.name );
					continue;
				}

				var sourceCrossRefs = AmsCrossSceneReferences.GetSceneSingleton( entry.scene.scene, false );
				if ( sourceCrossRefs )
					sourceCrossRefs.ResolvePendingCrossSceneReferences();
			}
		}
		static void MergeScenes()
		{
			Scene activeScene = new Scene();
			AmsMultiSceneSetup activeSetup = null;
			List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>();

			GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes );
			if ( bakedScenes.Count < 1 )
				return;

			AmsDebug.Log( null, "Running MergeScenes on Scene {0}", activeScene.name );

			foreach( var entry in bakedScenes )
			{
				if ( !entry.scene.isLoaded )
				{
					AmsDebug.LogError( activeSetup, "Could not merge non-loaded scene: {0}", entry.scene.name );
					continue;
				}

				var sourceCrossRefs = AmsCrossSceneReferences.GetSceneSingleton( entry.scene.scene, false );
				if ( sourceCrossRefs )
					GameObject.DestroyImmediate( sourceCrossRefs.gameObject, false );

				AmsDebug.Log( null, "Merging {0} into {1}", entry.scene.name, activeScene.name );
				EditorSceneManager.MergeScenes( entry.scene.scene, activeScene );
			}
		} // MergeScenes
		static void MergeScenes()
		{
			Scene activeScene = new Scene();
			AmsMultiSceneSetup activeSetup = null;
			List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>();

			GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes );
			if ( bakedScenes.Count < 1 )
				return;

			AmsDebug.Log( null, "Running AMS MergeScenes on Scene {0} ({1})", activeScene.name, activeSetup.scenePath );

			foreach( var entry in bakedScenes )
			{
				if ( !entry.scene.isLoaded )
				{
					AmsDebug.LogError( activeSetup, "Could not merge non-loaded scene: {0}", entry.scene.name );
					continue;
				}

				// Merge the cross-scene references (and keep track of the merges)
				var bakedSceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( entry.scene.scene, false );
				if ( bakedSceneSetup )
					AmsCrossSceneReferences.EditorBuildPipelineMergeScene( bakedSceneSetup, activeSetup );

				AmsDebug.Log( null, "Running Unity MergeScenes for {0} into {1}", entry.scene.name, activeScene.name );
				EditorSceneManager.MergeScenes( entry.scene.scene, activeScene );
			}
		} // MergeScenes
        public override void OnInspectorGUI()
        {
            AmsMultiSceneSetup target = (AmsMultiSceneSetup)this.target;

            // Help give us better hints at what the different SceneSetup modes refer to...
            if (target.sceneSetupMode == AmsMultiSceneSetup.SceneSetupManagement.Automatic)
            {
                bool isActiveScene = (SceneManager.GetActiveScene() == target.gameObject.scene);
                if (isActiveScene)
                {
                    EditorGUILayout.HelpBox("Scene Setup is automatically generated and saved with the scene based on the hierarchy.", MessageType.Info);
                }
                else
                {
                    EditorGUILayout.HelpBox("Scene Setup will not be updated or saved unless this Scene is set as Active", MessageType.Warning);
                }

                if (target.GetSceneSetup().Count < 1)
                {
                    DrawPropertiesExcluding(serializedObject, "m_Script", "_sceneSetup");
                    EditorGUILayout.HelpBox("This scene was never saved as the Active Scene.\nTherefore this Scene will not auto-load other scenes.", MessageType.Info);
                }
                else
                {
                    DrawPropertiesExcluding(serializedObject, "m_Script");
                }
            }
            else if (target.sceneSetupMode == AmsMultiSceneSetup.SceneSetupManagement.Manual)
            {
                EditorGUILayout.HelpBox("Scene Setup will not changed unless you modify it manually (or change Scene Setup Mode).", MessageType.Info);
                DrawPropertiesExcluding(serializedObject, "m_Script");
            }
            else
            {
                EditorGUILayout.HelpBox("Scene Setup will not be saved", MessageType.Warning);
                DrawPropertiesExcluding(serializedObject, "m_Script", "_sceneSetup");
            }

            EditorGUILayout.HelpBox("Note: This behaviour is always required for cross-scene referencing to work.", MessageType.Info);

            // Since we're not using SerializedProperties, we need to update the SerializedObject ourselves.
            serializedObject.ApplyModifiedProperties();
            serializedObject.Update();

            // If anything changed, we should resetup the SceneSetup and repaint the hierarchy
            if (GUI.changed)
            {
                AmsMultiSceneSetup.OnSceneSaving(target.gameObject.scene, target.scenePath);
                EditorApplication.RepaintHierarchyWindow();
            }
        }
		static void WarnOnAllMissingCrossSceneRefs()
		{
			Scene activeScene = new Scene();
			AmsMultiSceneSetup activeSetup = null;
			List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>();

			GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes );
			if ( !activeSetup )
				return;

			var crossSceneReferences = activeScene.GetSceneSingleton<AmsCrossSceneReferences>( false );
			if ( crossSceneReferences && crossSceneReferences.EditorWarnOnUnresolvedCrossSceneReferences() )
			{
				Debug.LogWarningFormat( "Previous Cross-Scene Reference Errors were in {0}", activeSetup.scenePath );
			}
		}
        internal static void LoadScenesForMerging()
		{
			Scene activeScene = new Scene();
			AmsMultiSceneSetup activeSetup = null;
			List<AmsMultiSceneSetup.SceneEntry> bakedScenes = new List<AmsMultiSceneSetup.SceneEntry>();

			GetCommonParameters( ref activeScene, ref activeSetup, bakedScenes );
			if ( bakedScenes.Count < 1 )
				return;

			AmsDebug.Log( null, "Running LoadScenesForBaking on Scene {0}", activeScene.name );

			// Now load all of the scenes
			foreach( var entry in bakedScenes )
			{
				var realScene = entry.scene.scene;
				if ( !realScene.IsValid() )
				{
					// This is good.  This means it's not loaded yet.
					realScene = EditorSceneManager.OpenScene( entry.scene.editorPath, OpenSceneMode.Additive );

					if ( !realScene.IsValid() )
					{
						AmsDebug.LogError( activeSetup, "BakeScene: Scene {0} ({1}) referenced from Multi-Scene Setup in {2} is invalid.", entry.scene.editorPath, entry.scene.name, activeScene.name );
						continue;
					}
				}

				// Let's catch this...
				if ( !realScene.isLoaded )
				{
					realScene = EditorSceneManager.OpenScene( realScene.path, OpenSceneMode.Additive );
					
					// if we're still not loaded, we're probably in trouble.
					if ( !realScene.isLoaded )
					{
						AmsDebug.LogError( activeSetup, "BakeScene: Scene {0} ({1}) referenced from Multi-Scene Setup in {2} could not load.", entry.scene.editorPath, entry.scene.name, activeScene.name );
						continue;
					}
				}
			}
		}
		private static void GetCommonParameters( ref Scene activeScene, ref AmsMultiSceneSetup activeSceneSetup, List<AmsMultiSceneSetup.SceneEntry> bakedScenes )
		{
			// We can only execute this when building the player.  Otherwise we expect entries to already be in the scene.
            if ( !BuildPipeline.isBuildingPlayer )
                return;

			// Get the SceneSetup for the Active Scene.
			activeScene = EditorSceneManager.GetActiveScene();
			activeSceneSetup = GameObjectEx.GetSceneSingleton<AmsMultiSceneSetup>( activeScene, false );
			if ( !activeSceneSetup )
				return;

			var scenesInSetup = activeSceneSetup.GetSceneSetup();
			foreach( var entry in scenesInSetup )
			{
                bool bShouldBake = entry.loadMethod == AmsMultiSceneSetup.LoadMethod.Baked;
				if ( bShouldBake )
					bakedScenes.Add( entry );
			}
		}
        public override void OnInspectorGUI()
        {
            AmsMultiSceneSetup target = (AmsMultiSceneSetup)this.target;

            if (!target.isMainScene)
            {
                DrawPropertiesExcluding(serializedObject, "m_Script", "_sceneSetup");
                EditorGUILayout.HelpBox("Since we are not configured as a Main Scene, we will NOT keep track of loaded scenes.\nThis behaviour is still required for cross-scene referencing to work.", MessageType.Info);
            }
            else
            {
                DrawPropertiesExcluding(serializedObject, "m_Script");
            }

            serializedObject.ApplyModifiedProperties();
            serializedObject.Update();

            if (GUI.changed)
            {
                EditorApplication.RepaintHierarchyWindow();
            }
        }