/// <summary>
        /// Initialize the controller
        /// </summary>
        /// <param name="attachToVe">If true then the game is attached to the virtual environment</param>
        public void Initialise(bool attachToVe)
        {
            AttachedToVe = attachToVe;

            ModelFactory = new ModelFactory(this);
            Game = ModelFactory.CreateGame(UUID.Random(), "Game1");

            Commands = new WaterWarsCommands(this);
            Resolver = new OpenSimResolver(this);
            ViewerWebServices = new ViewerWebServices(this);
            HudManager = new HudViewManager(this);
            Events = new WaterWars.Events.Events(this);
            Feeds = new WaterWars.Feeds.Feeds(this);
            GameDateManager = new GameDateManager(this);
            RoundManager = new RoundManager(this);
            StageTimer = new StageTimer(this);

            RainfallGenerator.Initialize(EventManager);
            WaterDistributor.Initialize(EventManager);

            if (null != Persister)
                Persister.Initialize(this);

            if (null != m_recorder)
                m_recorder.Initialize(this);

            // This has to be called before we establish a game state so that the persisted game object
            // can first be created
            EventManager.TriggerSystemInitialized();

            new RegistrationState(this).Activate();

            if (AttachedToVe)
            {
                Groups = new OpenSimGroupsMediator(this);

                CheckVeRequirements();

                foreach (Scene scene in Scenes)
                {
                    // Stop players deleting or editing objects they 'own'
                    scene.Permissions.OnRezObject += delegate(int objectCount, UUID owner, Vector3 objectPosition, Scene myScene) {
                        return Groups.IsPlayerAnAdmin(owner);
                    };
                    scene.Permissions.OnDeleteObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return Groups.IsPlayerAnAdmin(userID);
                    };
                    scene.Permissions.OnTakeObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return Groups.IsPlayerAnAdmin(userID);
                    };
                    scene.Permissions.OnTakeCopyObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return Groups.IsPlayerAnAdmin(userID);
                    };
                    scene.Permissions.OnEditObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return Groups.IsPlayerAnAdmin(userID);
                    };
                    scene.Permissions.OnMoveObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return Groups.IsPlayerAnAdmin(userID);
                    };

                    EntityBase[] entities = scene.Entities.GetAllByType<SceneObjectGroup>();

                    // Pass 1 - pick up the game manager view (first level of the hierarchy)
                    foreach (EntityBase e in entities)
                    {
                        SceneObjectGroup so = (SceneObjectGroup)e;

            //                    m_log.InfoFormat(
            //                        "[WATER WARS]: Pass 1 - processing {0} {1} at {2} in existing scene",
            //                        so.Name, so.LocalId, so.AbsolutePosition);

                        // This is messy, but there's actually only one game manager from which objects can come.
                        if (so.Name == GameManagerView.IN_WORLD_NAME)
                        {
                            GameManagerView = new GameManagerView(this, scene);
                            GameManagerView.Initialize(so);
                            Dispatcher.RegisterGameManagerView(GameManagerView);
                        }
                        else if (
                            so.Name == StepBuiltDecorator.IN_WORLD_NAME
                            || so.Name == WaterAllocationDecorator.IN_WORLD_NAME)
                        {
                            // FIXME: Temporarily, just delete our one decorator by name.
                            // Eventually, the decorators will need to be re-registered with their game asset view.
                            so.Scene.DeleteSceneObject(so, false);
                        }
                    }
                }

                if (GameManagerView == null)
                    throw new Exception(
                        string.Format(
                            "Could not find GameManagerView named {0} in any of the scenes.  ABORTING.",
                            GameManagerView.IN_WORLD_NAME));

                foreach (Scene scene in Scenes)
                {
                    m_log.InfoFormat("[WATER WARS]: Processing buypoints on scene {0}", scene.RegionInfo.RegionName);

                    // We'll keep track of these so that we can use them in pass 3
                    Dictionary<UUID, BuyPointView> buyPointViews = new Dictionary<UUID, BuyPointView>();

                    EntityBase[] entities = scene.Entities.GetAllByType<SceneObjectGroup>();

                    // Pass 2 - pick up the buy points (second level of the hierarchy)
                    foreach (EntityBase e in entities)
                    {
                        SceneObjectGroup so = (SceneObjectGroup)e;

                        try
                        {
            //                    m_log.InfoFormat(
            //                        "[WATER WARS]: Pass 2 - processing {0} {1} at {2} in existing scene",
            //                        so.Name, so.LocalId, so.AbsolutePosition);

                            IConfig config = GetPrimConfig(so);

                            if (config != null)
                            {
                                AbstractGameAssetType modelType = GetModelTypeFromPrimConfig(config);

                                if (modelType == AbstractGameAssetType.Parcel)
                                {
                                    // We're using in-world buy point positioning to register them - not taking these from an
                                    // internal database and pushing them back up to the ve
                                    //
                                    // FIXME: The below might be old advice since I have now changed things such that
                                    // we can specify the uuid upfront
                                    //
                                    // We can't incorporate the first update buy point call within bpv.Initialize() because it
                                    // won't yet have registered with the dispatcher (which forms an intermediate layer between the
                                    // game logic and the view code).
                                    // We can't register with the dispatcher before initializing the view because no UUID will yet
                                    // exist for the dispatcher to record.
                                    // It might be possible to simplify this if we adapt OpenSim to allow us to specify the UUID
                                    // up-front.  But other VE systems may not allow this.
                                    BuyPoint bp = Resolver.RegisterBuyPoint(so);
                                    BuyPointView bpv = GameManagerView.CreateBuyPointView(so, bp);
                                    buyPointViews.Add(bpv.Uuid, bpv);
                                    State.UpdateBuyPointStatus(bp);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_log.Error(
                                string.Format(
                                    "[WATER WARS]: Could not register {0} at {1} in {2}, ",
                                    so.Name, so.AbsolutePosition, so.Scene.RegionInfo.RegionName),
                                ex);
                        }
                    }

                    // Pass 3 - pick up the fields and game assets (third level of the hierarchy)
                    foreach (EntityBase e in entities)
                    {
                        SceneObjectGroup so = (SceneObjectGroup)e;

                        try
                        {
                            IConfig config = GetPrimConfig(so);

                            if (config != null)
                            {
                                AbstractGameAssetType modelType = GetModelTypeFromPrimConfig(config);

                                if (modelType == AbstractGameAssetType.Field)
                                {
                                    Field f = Resolver.RegisterField(so);
                                    BuyPointView bpv = null;
                                    if (buyPointViews.TryGetValue(f.BuyPoint.Uuid, out bpv))
                                        bpv.CreateFieldView(so);
                                    else
                                        throw new Exception(
                                            string.Format(
                                                "Could not find BuyPointView for field {0}, parcel {1} at {2}",
                                                f.Name, f.BuyPoint.Name, f.BuyPoint.Location.LocalPosition));
                                }
                                else if (
                                    modelType == AbstractGameAssetType.Crops
                                    || modelType == AbstractGameAssetType.Houses
                                    || modelType == AbstractGameAssetType.Factory)
                                {
                                    // For now, just delete any existing game assets immediately.
                                    so.Scene.DeleteSceneObject(so, false);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_log.Error(
                                string.Format(
                                    "[WATER WARS]: Could not register {0} at {1} in {2}, ",
                                    so.Name, so.AbsolutePosition, so.Scene.RegionInfo.RegionName),
                                ex);
                        }
                    }
                }

                HudManager.Initialise();

                // Register in-game objects as they are created
                //m_scene.EventManager.OnObjectBeingAddedToScene += OnObjectAddedToScene;

                // At the moment, reset the game immediately on restarting so that we have a blank slate
                State.ResetGame();

            //                string statePath = Path.Combine(WaterWarsConstants.STATE_PATH, WaterWarsConstants.STATE_FILE_NAME);
            //                if (File.Exists(statePath))
            //                    RestoreGame(statePath);
            }
        }
        /// <summary>
        /// Initialize the controller
        /// </summary>
        /// <param name="attachToVe">If true then the game is attached to the virtual environment</param>
        public void Initialise(bool attachToVe)
        {
            AttachedToVe = attachToVe;

            ModelFactory = new ModelFactory(this);
            Game         = ModelFactory.CreateGame(UUID.Random(), "Game1");

            Commands          = new WaterWarsCommands(this);
            Resolver          = new OpenSimResolver(this);
            ViewerWebServices = new ViewerWebServices(this);
            HudManager        = new HudViewManager(this);
            Events            = new WaterWars.Events.Events(this);
            Feeds             = new WaterWars.Feeds.Feeds(this);
            GameDateManager   = new GameDateManager(this);
            RoundManager      = new RoundManager(this);
            StageTimer        = new StageTimer(this);

            RainfallGenerator.Initialize(EventManager);
            WaterDistributor.Initialize(EventManager);

            if (null != Persister)
            {
                Persister.Initialize(this);
            }

            if (null != m_recorder)
            {
                m_recorder.Initialize(this);
            }

            // This has to be called before we establish a game state so that the persisted game object
            // can first be created
            EventManager.TriggerSystemInitialized();

            new RegistrationState(this).Activate();

            if (AttachedToVe)
            {
                Groups = new OpenSimGroupsMediator(this);

                CheckVeRequirements();

                foreach (Scene scene in Scenes)
                {
                    // Stop players deleting or editing objects they 'own'
                    scene.Permissions.OnRezObject += delegate(int objectCount, UUID owner, Vector3 objectPosition, Scene myScene) {
                        return(Groups.IsPlayerAnAdmin(owner));
                    };
                    scene.Permissions.OnDeleteObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return(Groups.IsPlayerAnAdmin(userID));
                    };
                    scene.Permissions.OnTakeObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return(Groups.IsPlayerAnAdmin(userID));
                    };
                    scene.Permissions.OnTakeCopyObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return(Groups.IsPlayerAnAdmin(userID));
                    };
                    scene.Permissions.OnEditObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return(Groups.IsPlayerAnAdmin(userID));
                    };
                    scene.Permissions.OnMoveObject += delegate(UUID objectID, UUID userID, Scene myScene) {
                        return(Groups.IsPlayerAnAdmin(userID));
                    };

                    EntityBase[] entities = scene.Entities.GetAllByType <SceneObjectGroup>();

                    // Pass 1 - pick up the game manager view (first level of the hierarchy)
                    foreach (EntityBase e in entities)
                    {
                        SceneObjectGroup so = (SceneObjectGroup)e;

                        //                    m_log.InfoFormat(
                        //                        "[WATER WARS]: Pass 1 - processing {0} {1} at {2} in existing scene",
                        //                        so.Name, so.LocalId, so.AbsolutePosition);

                        // This is messy, but there's actually only one game manager from which objects can come.
                        if (so.Name == GameManagerView.IN_WORLD_NAME)
                        {
                            GameManagerView = new GameManagerView(this, scene);
                            GameManagerView.Initialize(so);
                            Dispatcher.RegisterGameManagerView(GameManagerView);
                        }
                        else if (
                            so.Name == StepBuiltDecorator.IN_WORLD_NAME ||
                            so.Name == WaterAllocationDecorator.IN_WORLD_NAME)
                        {
                            // FIXME: Temporarily, just delete our one decorator by name.
                            // Eventually, the decorators will need to be re-registered with their game asset view.
                            so.Scene.DeleteSceneObject(so, false);
                        }
                    }
                }

                if (GameManagerView == null)
                {
                    throw new Exception(
                              string.Format(
                                  "Could not find GameManagerView named {0} in any of the scenes.  ABORTING.",
                                  GameManagerView.IN_WORLD_NAME));
                }

                foreach (Scene scene in Scenes)
                {
                    m_log.InfoFormat("[WATER WARS]: Processing buypoints on scene {0}", scene.RegionInfo.RegionName);

                    // We'll keep track of these so that we can use them in pass 3
                    Dictionary <UUID, BuyPointView> buyPointViews = new Dictionary <UUID, BuyPointView>();

                    EntityBase[] entities = scene.Entities.GetAllByType <SceneObjectGroup>();

                    // Pass 2 - pick up the buy points (second level of the hierarchy)
                    foreach (EntityBase e in entities)
                    {
                        SceneObjectGroup so = (SceneObjectGroup)e;

                        try
                        {
                            //                    m_log.InfoFormat(
                            //                        "[WATER WARS]: Pass 2 - processing {0} {1} at {2} in existing scene",
                            //                        so.Name, so.LocalId, so.AbsolutePosition);

                            IConfig config = GetPrimConfig(so);

                            if (config != null)
                            {
                                AbstractGameAssetType modelType = GetModelTypeFromPrimConfig(config);

                                if (modelType == AbstractGameAssetType.Parcel)
                                {
                                    // We're using in-world buy point positioning to register them - not taking these from an
                                    // internal database and pushing them back up to the ve
                                    //
                                    // FIXME: The below might be old advice since I have now changed things such that
                                    // we can specify the uuid upfront
                                    //
                                    // We can't incorporate the first update buy point call within bpv.Initialize() because it
                                    // won't yet have registered with the dispatcher (which forms an intermediate layer between the
                                    // game logic and the view code).
                                    // We can't register with the dispatcher before initializing the view because no UUID will yet
                                    // exist for the dispatcher to record.
                                    // It might be possible to simplify this if we adapt OpenSim to allow us to specify the UUID
                                    // up-front.  But other VE systems may not allow this.
                                    BuyPoint     bp  = Resolver.RegisterBuyPoint(so);
                                    BuyPointView bpv = GameManagerView.CreateBuyPointView(so, bp);
                                    buyPointViews.Add(bpv.Uuid, bpv);
                                    State.UpdateBuyPointStatus(bp);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_log.Error(
                                string.Format(
                                    "[WATER WARS]: Could not register {0} at {1} in {2}, ",
                                    so.Name, so.AbsolutePosition, so.Scene.RegionInfo.RegionName),
                                ex);
                        }
                    }

                    // Pass 3 - pick up the fields and game assets (third level of the hierarchy)
                    foreach (EntityBase e in entities)
                    {
                        SceneObjectGroup so = (SceneObjectGroup)e;

                        try
                        {
                            IConfig config = GetPrimConfig(so);

                            if (config != null)
                            {
                                AbstractGameAssetType modelType = GetModelTypeFromPrimConfig(config);

                                if (modelType == AbstractGameAssetType.Field)
                                {
                                    Field        f   = Resolver.RegisterField(so);
                                    BuyPointView bpv = null;
                                    if (buyPointViews.TryGetValue(f.BuyPoint.Uuid, out bpv))
                                    {
                                        bpv.CreateFieldView(so);
                                    }
                                    else
                                    {
                                        throw new Exception(
                                                  string.Format(
                                                      "Could not find BuyPointView for field {0}, parcel {1} at {2}",
                                                      f.Name, f.BuyPoint.Name, f.BuyPoint.Location.LocalPosition));
                                    }
                                }
                                else if (
                                    modelType == AbstractGameAssetType.Crops ||
                                    modelType == AbstractGameAssetType.Houses ||
                                    modelType == AbstractGameAssetType.Factory)
                                {
                                    // For now, just delete any existing game assets immediately.
                                    so.Scene.DeleteSceneObject(so, false);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            m_log.Error(
                                string.Format(
                                    "[WATER WARS]: Could not register {0} at {1} in {2}, ",
                                    so.Name, so.AbsolutePosition, so.Scene.RegionInfo.RegionName),
                                ex);
                        }
                    }
                }

                HudManager.Initialise();

                // Register in-game objects as they are created
                //m_scene.EventManager.OnObjectBeingAddedToScene += OnObjectAddedToScene;

                // At the moment, reset the game immediately on restarting so that we have a blank slate
                State.ResetGame();

//                string statePath = Path.Combine(WaterWarsConstants.STATE_PATH, WaterWarsConstants.STATE_FILE_NAME);
//                if (File.Exists(statePath))
//                    RestoreGame(statePath);
            }
        }