public override void BeforeInvoke(InvocationInfo info)
        {
            if (info.target.GetType () == typeof(BattleMode) && info.targetMethod.Equals ("handleInput")) {
                if (info.target.GetType () == typeof(BattleMode) && battleMode == null) {
                    battleMode = new BattleModeWrapper ((BattleMode)info.target);
                    handManager = new HandManagerWrapper (battleMode.GetHandManager ());
                    battleModeMenu = new GUIBattleModeMenuWrapper (battleMode.GetMenu());
                }
                if (settingsMenu == null) {
                    settingsMenu = new SettingsMenuWrapper (configManager, configGUI);
                }
                if (battleMode.Validate ((BattleMode)info.target)) {
                    battleModeMenu.Initialize (battleMode.GetMenu ());
                }
                handManager.Validate (battleMode.GetHandManager ());

                if (popups.IsShowingPopup ()) {
                    HandlePopupsControls ();
                } else {
                    HandleBattleModeControls ();
                    if (battleMode.ShowingMenu()) {
                        HandleSettingsMenuControls ();
                        HandleBattleModeMenuControls ();
                    }
                }
                // Cache the currently selected tile (used to display a custom tinted hover indicator).
                //if (battleMode.InControlOfBoard ()) {
                //	selectedTile = battleMode.GetTile ();
                //}
            } else if (info.target.GetType () == typeof(EndGameScreen) && info.targetMethod.Equals ("OnGUI")) {
                if (endGameScreen == null) {
                    endGameScreen = new EndGameScreenWrapper ((EndGameScreen)info.target);
                }
                endGameScreen.Validate ((EndGameScreen)info.target);
                HandleEndGameScreenControls ();
            } else if (info.target.GetType () == typeof(LobbyMenu) && info.targetMethod.Equals ("Update")) {
                if (lobbyMenu == null) {
                    lobbyMenu = new LobbyMenuWrapper ();
                    if (configGUI == null) {
                        ShowConfigGUI ();
                    }
                }
                // Let popups leech of LobbyMenu's update function.
                if (popups.IsShowingPopup ()) {
                    HandlePopupsControls ();
                } else {
                    HandleLobbyMenuControls ();
                    if (lobbyMenu.GetCurrentSceneName () == "_Settings") {
                        HandleSettingsMenuControls ();
                    }
                }
            } else if (info.target.GetType () == typeof(LobbyMenu) && info.targetMethod.Equals ("fadeOutScene")) {
                if (lobbyMenu == null) {
                    lobbyMenu = new LobbyMenuWrapper ();
                }
                lobbyMenu.RegisterCurrentScene ();
            } else if (info.target.GetType () == typeof(Login) && info.targetMethod.Equals ("OnGUI")) {
                if (login == null) {
                    login = new LoginWrapper ((Login)info.target);
                }
                HandleLoginControls ();
            }
        }
        public void TileClicked(HandManagerWrapper handManagerWrapper)
        {
            Tile tile = GetTile ();
            if (tile != null) {
                object tileSelector = ReflectionsManager.GetValue (battleMode, "tileSelector");
                bool didPlayCard = false;
                bool didActivateAbility = false;
                bool didSelectFirstTarget = false;

                // Check if we are trying to play a card from hand on the battlefield (i.e. units / targeted spells / enchantments).
                if (handManager.GetSelectedCard () != null && tileSelector != null) {
                    if ((bool)ReflectionsManager.GetMethod(tileSelector, "pick").Invoke(tileSelector, new object[] { battleMode.getPosition(tile) })) {
                        if ((bool)ReflectionsManager.GetMethod (tileSelector, "hasPickedAll").Invoke (tileSelector, new object[] { })) {
                            if ((bool)ReflectionsManager.GetMethod (tileSelector, "isValid").Invoke (tileSelector, new object[] { })) {
                                battleMode.confirmPlayCard (handManager.GetSelectedCard (), (List<TilePosition>)ReflectionsManager.GetValue (tileSelector, "_picked"));
                                didPlayCard = true;
                            }
                        } else {
                            // We haven't picked 'all' needed options (for instance the 2nd target for Flip or Transposition), mark every viable option.
                            ReflectionsManager.GetMethod(battleMode, "markTiles").Invoke(battleMode, new object[]{ReflectionsManager.GetMethod(tileSelector, "getChoiceTiles").Invoke(tileSelector, new object[]{}), Tile.SelectionType.Selected});
                            didSelectFirstTarget = true;
                        }
                    }
                } else {
                    // Get the position of the currently active ability and check if it is the same as the currently selected tile.
                    TilePosition activeAbilityPosition = (TilePosition)ReflectionsManager.GetValue (battleMode, "activeAbilityPosition");
                    if (activeAbilityPosition.Equals (battleMode.getPosition (tile))) {
                        GameObject cardRule = (GameObject)ReflectionsManager.GetValue (battleMode, "cardRule");
                        if (cardRule != null) {
                            CardView cardView = cardRule.GetComponent<CardView> ();
                            if (cardView != null) {
                                // Disect the scroll's activatable abilities from it. If it contains a non-move ability (i.e. summon wolf), activate it.
                                ActiveAbility[] activeAbilities = cardView.getCardInfo ().getActiveAbilities ();
                                if (activeAbilities != null) {
                                    for (int j = 0; j < activeAbilities.Length; j++) {
                                        ActiveAbility activeAbility = activeAbilities [j];
                                        if (!(activeAbility.name == "Move")) {
                                            TilePosition pos = (TilePosition)ReflectionsManager.GetValue (cardView, "pos");
                                            if (pos != null) {
                                                battleMode.ActivateTriggeredAbility (activeAbility.id, pos);
                                                battleMode.HideCardView ();
                                                didActivateAbility = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                // Reserve the next card if we will place a unit on the board with this click.
                if (didPlayCard) {
                    handManagerWrapper.ReserveNextCard ();
                }
                // 'Click' on the currently highlighted tile if we didn't activate a unit's activated ability.
                if (!didActivateAbility && !didPlayCard && !didSelectFirstTarget) {
                    battleMode.tileClicked(tile);
                }
                // Return control back to the hand if we placed a unit.
                if (didPlayCard) {
                    TakeControlOfHand ();
                }
            }
        }