From 3019991473f16c645d83b0e9142d56f73aa6fe98 Mon Sep 17 00:00:00 2001
From: ingmargoudt <ingmargoudt@gmail.com>
Date: Thu, 15 Sep 2016 20:52:41 +0200
Subject: [PATCH] removed the Session out of local scope and introduced a
 static SessionHandler that acts as interface to remote.Session

---
 .../src/main/java/mage/client/MageFrame.java  |  50 ++-
 .../main/java/mage/client/SessionHandler.java | 311 ++++++++++++++++++
 .../src/main/java/mage/client/cards/Card.java |   3 +-
 .../java/mage/client/chat/ChatPanelBasic.java |  18 +-
 .../mage/client/chat/ChatPanelSeparated.java  |   6 +-
 .../components/ability/AbilityPicker.java     |   4 +-
 .../client/deckeditor/DeckEditorPanel.java    |   9 +-
 .../mage/client/dialog/FeedbackDialog.java    |   3 +-
 .../mage/client/dialog/JoinTableDialog.java   |   5 +-
 .../mage/client/dialog/NewTableDialog.java    |  24 +-
 .../client/dialog/NewTournamentDialog.java    |  27 +-
 .../mage/client/dialog/PreferencesDialog.java |   5 +-
 .../client/dialog/TableWaitingDialog.java     |  20 +-
 .../java/mage/client/draft/DraftPanel.java    |  10 +-
 .../java/mage/client/game/AbilityPicker.java  |  10 +-
 .../java/mage/client/game/FeedbackPanel.java  |  13 +-
 .../main/java/mage/client/game/GamePanel.java |  89 +++--
 .../java/mage/client/game/HelperPanel.java    |  13 +-
 .../java/mage/client/game/PlayAreaPanel.java  |  41 +--
 .../java/mage/client/game/PlayerPanelExt.java |   4 +-
 .../plugins/adapters/MageActionCallback.java  |  15 +-
 .../mage/client/table/TablePlayerPanel.java   |   7 +-
 .../java/mage/client/table/TablesPane.java    |   3 +-
 .../java/mage/client/table/TablesPanel.java   |  83 ++---
 .../client/table/TournamentPlayerPanel.java   |   7 +-
 .../client/tournament/TournamentPanel.java    |  24 +-
 .../mage/client/unusedFiles/PlayerPanel.java  |   5 +-
 .../client/util/DefaultActionCallback.java    |   7 +-
 28 files changed, 545 insertions(+), 271 deletions(-)
 create mode 100644 Mage.Client/src/main/java/mage/client/SessionHandler.java

diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java
index 03b2f5a272..44e539823d 100644
--- a/Mage.Client/src/main/java/mage/client/MageFrame.java
+++ b/Mage.Client/src/main/java/mage/client/MageFrame.java
@@ -167,7 +167,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
 
     private static MageFrame instance;
 
-    private static Session session;
     private ConnectDialog connectDialog;
     private final ErrorDialog errorDialog;
     private static CallbackClient callbackClient;
@@ -199,9 +198,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     /**
      * @return the session
      */
-    public static Session getSession() {
-        return session;
-    }
 
     public static JDesktopPane getDesktop() {
         return desktopPane;
@@ -308,7 +304,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
         DialogManager.updateParams(768, 1024, false);
         this.setExtendedState(JFrame.MAXIMIZED_BOTH);
 
-        session = new SessionImpl(this);
+        SessionHandler.startSession(this);
         callbackClient = new CallbackClientImpl(this);
         connectDialog = new ConnectDialog();
         desktopPane.add(connectDialog, JLayeredPane.POPUP_LAYER);
@@ -320,7 +316,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
         PING_TASK_EXECUTOR.scheduleAtFixedRate(new Runnable() {
             @Override
             public void run() {
-                session.ping();
+                SessionHandler.ping();
             }
         }, 60, 60, TimeUnit.SECONDS);
 
@@ -445,7 +441,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     private void setWindowTitle() {
         setTitle(TITLE_NAME + "  Client: "
                 + (VERSION == null ? "<not available>" : VERSION.toString()) + "  Server: "
-                + ((session != null && session.isConnected()) ? session.getVersionInfo() : "<not connected>"));
+                + ((SessionHandler.getSession() != null && SessionHandler.isConnected()) ? SessionHandler.getVersionInfo() : "<not connected>"));
     }
 
     private void addTooltipContainer() {
@@ -820,13 +816,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     }
 
     public static boolean connect(Connection connection) {
-        boolean result = session.connect(connection);
+        boolean result = SessionHandler.connect(connection);
         MageFrame.getInstance().setWindowTitle();
         return result;
     }
 
     public static boolean stopConnecting() {
-        return session.stopConnecting();
+        return SessionHandler.stopConnecting();
     }
 
     public boolean autoConnect() {
@@ -1056,7 +1052,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     }//GEN-LAST:event_btnExitActionPerformed
 
     private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed
-        if (session.isConnected()) {
+        if (SessionHandler.isConnected()) {
             UserRequestMessage message = new UserRequestMessage("Confirm disconnect", "Are you sure you want to disconnect?");
             message.setButton1("No", null);
             message.setButton2("Yes", PlayerAction.CLIENT_DISCONNECT);
@@ -1089,7 +1085,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     }//GEN-LAST:event_btnPreferencesActionPerformed
 
     public void btnSendFeedbackActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSendFeedbackActionPerformed
-        if (!session.isConnected()) {
+        if (!SessionHandler.isConnected()) {
             JOptionPane.showMessageDialog(null, "You may send us feedback only when connected to server.", "Information", JOptionPane.INFORMATION_MESSAGE);
             return;
         }
@@ -1097,7 +1093,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     }//GEN-LAST:event_btnSendFeedbackActionPerformed
 
     public void exitApp() {
-        if (session.isConnected()) {
+        if (SessionHandler.isConnected()) {
             UserRequestMessage message = new UserRequestMessage("Confirm disconnect", "You are currently connected.  Are you sure you want to disconnect?");
             message.setButton1("No", null);
             message.setButton2("Yes", PlayerAction.CLIENT_EXIT);
@@ -1424,7 +1420,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
                     disableButtons();
                     hideGames();
                     hideTables();
-                    session.disconnect(false);
+                    SessionHandler.disconnect(false);
                     if (errorCall) {
                         UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect?");
                         message.setButton1("No", null);
@@ -1441,14 +1437,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
     public void showMessage(String message) {
         final UserRequestMessage requestMessage = new UserRequestMessage("Message", message);
         requestMessage.setButton1("OK", null);
-        MageFrame.getInstance().showUserRequestDialog(requestMessage);
+        showUserRequestDialog(requestMessage);
     }
 
     @Override
     public void showError(final String message) {
         final UserRequestMessage requestMessage = new UserRequestMessage("Error", message);
         requestMessage.setButton1("OK", null);
-        MageFrame.getInstance().showUserRequestDialog(requestMessage);
+        showUserRequestDialog(requestMessage);
     }
 
     @Override
@@ -1465,26 +1461,26 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
                 DownloadPictures.startDownload(null, missingCards);
                 break;
             case CLIENT_DISCONNECT:
-                session.disconnect(false);
+                SessionHandler.disconnect(false);
                 tablesPane.clearChat();
                 showMessage("You have disconnected");
                 setWindowTitle();
                 break;
             case CLIENT_QUIT_TOURNAMENT:
-                MageFrame.getSession().quitTournament(userRequestMessage.getTournamentId());
+                SessionHandler.quitTournament(userRequestMessage.getTournamentId());
                 break;
             case CLIENT_QUIT_DRAFT_TOURNAMENT:
-                MageFrame.getSession().quitDraft(userRequestMessage.getTournamentId());
+                SessionHandler.quitDraft(userRequestMessage.getTournamentId());
                 MageFrame.removeDraft(userRequestMessage.getTournamentId());
                 break;
             case CLIENT_CONCEDE_GAME:
-                MageFrame.getSession().sendPlayerAction(PlayerAction.CONCEDE, userRequestMessage.getGameId(), null);
+                SessionHandler.sendPlayerAction(PlayerAction.CONCEDE, userRequestMessage.getGameId(), null);
                 break;
             case CLIENT_CONCEDE_MATCH:
-                MageFrame.getSession().quitMatch(userRequestMessage.getGameId());
+                SessionHandler.quitMatch(userRequestMessage.getGameId());
                 break;
             case CLIENT_STOP_WATCHING:
-                session.stopWatching(userRequestMessage.getGameId());
+                SessionHandler.stopWatching(userRequestMessage.getGameId());
                 GamePanel gamePanel = getGame(userRequestMessage.getGameId());
                 if (gamePanel != null) {
                     gamePanel.removeGame();
@@ -1492,8 +1488,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
                 removeGame(userRequestMessage.getGameId());
                 break;
             case CLIENT_EXIT:
-                if (session.isConnected()) {
-                    session.disconnect(false);
+                if (SessionHandler.isConnected()) {
+                    SessionHandler.disconnect(false);
                 }
                 CardRepository.instance.closeDB();
                 tablesPane.cleanUp();
@@ -1502,7 +1498,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
                 System.exit(0);
                 break;
             case CLIENT_REMOVE_TABLE:
-                session.removeTable(userRequestMessage.getRoomId(), userRequestMessage.getTableId());
+                SessionHandler.removeTable(userRequestMessage.getRoomId(), userRequestMessage.getTableId());
                 break;
             case CLIENT_RECONNECT:
                 if (performConnect()) {
@@ -1510,11 +1506,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
                 }
                 break;
             case CLIENT_REPLAY_ACTION:
-                session.stopReplay(userRequestMessage.getGameId());
+                SessionHandler.stopReplay(userRequestMessage.getGameId());
                 break;
             default:
-                if (session != null && playerAction != null) {
-                    session.sendPlayerAction(playerAction, userRequestMessage.getGameId(), userRequestMessage.getRelatedUserId());
+                if (SessionHandler.getSession() != null && playerAction != null) {
+                    SessionHandler.sendPlayerAction(playerAction, userRequestMessage.getGameId(), userRequestMessage.getRelatedUserId());
                 }
 
         }
diff --git a/Mage.Client/src/main/java/mage/client/SessionHandler.java b/Mage.Client/src/main/java/mage/client/SessionHandler.java
new file mode 100644
index 0000000000..3eecd416a2
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/SessionHandler.java
@@ -0,0 +1,311 @@
+package mage.client;
+
+import mage.cards.decks.DeckCardLists;
+import mage.constants.PlayerAction;
+import mage.game.match.MatchOptions;
+import mage.game.tournament.TournamentOptions;
+import mage.players.net.UserData;
+import mage.remote.Connection;
+import mage.remote.MageRemoteException;
+import mage.remote.Session;
+import mage.remote.SessionImpl;
+import mage.view.*;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Created by IGOUDT on 15-9-2016.
+ */
+public class SessionHandler {
+
+    private static Session session;
+
+    public static void startSession(MageFrame mageFrame) {
+
+        session = new SessionImpl(mageFrame);
+    }
+
+    public static void ping() {
+        session.ping();
+    }
+
+    public static Session getSession() {
+        return session;
+    }
+
+    public static boolean isConnected() {
+        return session.isConnected();
+    }
+
+    public static String getVersionInfo() {
+        return session.getVersionInfo();
+    }
+
+    public static boolean connect(Connection connection) {
+     return   session.connect(connection);
+    }
+
+    public static boolean stopConnecting() {
+        return session.stopConnecting();
+    }
+
+    public static void disconnect(boolean showmessage) {
+        session.disconnect(showmessage);
+    }
+
+    public static void sendPlayerAction(PlayerAction playerAction, UUID gameId, Object relatedUserId) {
+        session.sendPlayerAction(playerAction, gameId, relatedUserId);
+    }
+
+    public static void quitTournament(UUID tournamentId) {
+            session.quitTournament(tournamentId);
+    }
+
+    public static void quitDraft(UUID tournamentId) {
+        session.quitDraft(tournamentId);
+    }
+
+    public static void quitMatch(UUID gameId) {
+        session.quitMatch(gameId);
+    }
+
+    public static void stopWatching(UUID gameId) {
+        session.stopWatching(gameId);
+    }
+
+    public static void removeTable(UUID roomId, UUID tableId) {
+            session.removeTable(roomId, tableId);
+    }
+
+    public static void stopReplay(UUID gameId) {
+        session.stopReplay(gameId);
+    }
+
+    public static void sendPlayerUUID(UUID gameId, UUID id) {
+            session.sendPlayerUUID(gameId, id);
+    }
+
+    public static void sendPlayerBoolean(UUID gameId, boolean b) {
+        session.sendPlayerBoolean(gameId, b);
+    }
+
+    public static String[] getPlayerTypes() {
+        return session.getPlayerTypes();
+    }
+
+    public static boolean joinTournamentTable(UUID roomId, UUID tableId, String text, String selectedItem, Integer integer, DeckCardLists deckCardLists, String s) {
+        return session.joinTournamentTable(roomId, tableId, text, selectedItem, integer, deckCardLists, s);
+    }
+
+    public static void sendPlayerInteger(UUID gameId, int data) {
+            session.sendPlayerInteger(gameId, data);
+    }
+
+    public static void sendPlayerString(UUID gameId, String data) {
+        session.sendPlayerString(gameId, data);
+    }
+
+    public static boolean sendFeedback(String title, String type, String message, String email) {
+      return  session.sendFeedback(title, type, message, email);
+    }
+
+    public static void swapSeats(UUID roomId, UUID tableId, int row, int targetrow) {
+        session.swapSeats(roomId, tableId, row, targetrow);
+    }
+
+    public static boolean leaveTable(UUID roomId, UUID tableId) {
+        return session.leaveTable(roomId, tableId);
+    }
+
+    public static void updatePreferencesForServer(UserData userData) {
+            session.updatePreferencesForServer(userData);
+    }
+
+    public static boolean isTableOwner(UUID roomId, UUID tableId) {
+            return session.isTableOwner(roomId, tableId);
+    }
+
+    public static UUID getTableChatId(UUID tableId) {
+        return session.getTableChatId(tableId);
+    }
+
+    public static boolean startTournament(UUID roomId, UUID tableId) {
+            return session.startTournament(roomId, tableId);
+    }
+
+    public static boolean startMatch(UUID roomId, UUID tableId) {
+        return session.startMatch(roomId, tableId);
+    }
+
+    public static UUID getGameChatId(UUID gameId) {
+        return session.getGameChatId(gameId);
+    }
+
+    public static boolean joinGame(UUID gameId) {
+        return session.joinGame(gameId);
+    }
+
+    public static boolean startReplay(UUID gameId) {
+        return session.startReplay(gameId);
+    }
+
+    public static void watchTournamentTable(UUID tableId) {
+            session.watchTournamentTable(tableId);
+    }
+
+    public static boolean joinTournament(UUID tournamentId) {
+        return session.joinTournament(tournamentId);
+    }
+
+    public static UUID getTournamentChatId(UUID tournamentId) {
+            return session.getTournamentChatId(tournamentId);
+    }
+
+    public static TournamentView getTournament(UUID tournamentId) {
+        try {
+            return session.getTournament(tournamentId);
+        } catch (MageRemoteException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+    public static String getUserName() {
+            return session.getUserName();
+    }
+
+    public static boolean watchGame(UUID gameId) {
+        return session.watchGame(gameId);
+    }
+
+    public static void nextPlay(UUID gameId) {
+        session.nextPlay(gameId);
+    }
+
+    public static void previousPlay(UUID gameId) {
+        session.previousPlay(gameId);
+    }
+
+    public static void skipForward(UUID gameId, int i) {
+        session.skipForward(gameId, i);
+    }
+
+    public static boolean isTestMode() {
+            return session.isTestMode();
+    }
+
+    public static void cheat(UUID gameId, UUID playerId, DeckCardLists deckCardLists) {
+        session.cheat(gameId, playerId, deckCardLists);
+    }
+
+    public static String getSessionId() {
+                return session.getSessionId();
+    }
+
+    public static List<TournamentTypeView> getTournamentTypes() {
+        return session.getTournamentTypes();
+    }
+
+    public static boolean submitDeck(UUID tableId, DeckCardLists deckCardLists) {
+        return session.submitDeck(tableId, deckCardLists);
+    }
+
+    public static String[] getDeckTypes() {
+                return session.getDeckTypes();
+    }
+
+    public static String[] getDraftCubes() {
+        return session.getDraftCubes();
+    }
+
+    public static List<GameTypeView> getTournamentGameTypes() {
+        return session.getTournamentGameTypes();
+    }
+
+    public static TableView createTournamentTable(UUID roomId, TournamentOptions tOptions) {
+        return session.createTournamentTable(roomId, tOptions);
+    }
+
+    public static TableView createTable(UUID roomId, MatchOptions options) {
+        return session.createTable(roomId, options);
+    }
+
+    public static boolean joinTable(UUID roomId, UUID tableId, String playerName, String human, int skill, DeckCardLists deckCardLists, String text) {
+        return session.joinTable(roomId, tableId, playerName, human, skill, deckCardLists, text);
+    }
+
+    public static List<GameTypeView> getGameTypes() {
+            return session.getGameTypes();
+    }
+
+    public static boolean joinDraft(UUID draftId) {
+        return session.joinDraft(draftId);
+    }
+
+    public static DraftPickView sendCardPick(UUID draftId, UUID id, Set<UUID> cardsHidden) {
+        return session.sendCardPick(draftId, id, cardsHidden);
+    }
+
+    public static void sendCardMark(UUID draftId, UUID id) {
+        session.sendCardMark(draftId, id);
+    }
+
+    public static UUID getRoomChatId(UUID roomId) {
+        return session.getRoomChatId(roomId);
+    }
+
+    public static Collection<RoomUsersView> getRoomUsers(UUID roomId) {
+        try {
+            return session.getRoomUsers(roomId);
+        } catch (MageRemoteException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static Collection<MatchView> getFinishedMatches(UUID roomId) {
+        try {
+            return session.getFinishedMatches(roomId);
+        } catch (MageRemoteException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static void replayGame(UUID id) {
+        session.replayGame(id);
+    }
+
+    public static void watchTable(UUID roomId, UUID tableId) {
+        session.watchTable(roomId, tableId);
+    }
+
+    public static Collection<TableView> getTables(UUID roomId) {
+        try {
+            return session.getTables(roomId);
+        } catch (MageRemoteException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static List<String> getServerMessages() {
+            return session.getServerMessages();
+    }
+
+    public static boolean joinChat(UUID chatId) {
+        return session.joinChat(chatId);
+    }
+
+    public static boolean leaveChat(UUID chatId) {
+            return session.leaveChat(chatId);
+    }
+
+    public static boolean sendChatMessage(UUID chatId, String text) {
+        return session.sendChatMessage(chatId, text);
+    }
+}
diff --git a/Mage.Client/src/main/java/mage/client/cards/Card.java b/Mage.Client/src/main/java/mage/client/cards/Card.java
index ddfbc789e9..f87c03bbeb 100644
--- a/Mage.Client/src/main/java/mage/client/cards/Card.java
+++ b/Mage.Client/src/main/java/mage/client/cards/Card.java
@@ -101,7 +101,6 @@ import org.apache.log4j.Logger;
 @SuppressWarnings("serial")
 public class Card extends MagePermanent implements MouseMotionListener, MouseListener, FocusListener, ComponentListener {
 
-    protected static Session session = MageFrame.getSession();
     protected static DefaultActionCallback callback = DefaultActionCallback.getInstance();
 
     protected Point p;
@@ -401,7 +400,7 @@ public class Card extends MagePermanent implements MouseMotionListener, MouseLis
     @Override
     public void mousePressed(MouseEvent e) {
         requestFocusInWindow();
-        callback.mouseClicked(e, gameId, session, card);
+        callback.mouseClicked(e, gameId, card);
     }
 
     @Override
diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java b/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java
index 932a5bc3ee..26f0ab1a0f 100644
--- a/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java
+++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanelBasic.java
@@ -40,8 +40,8 @@ import java.awt.event.KeyEvent;
 import java.util.UUID;
 import javax.swing.JTextField;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.util.GUISizeHelper;
-import mage.remote.Session;
 import mage.view.ChatMessage.MessageColor;
 import mage.view.ChatMessage.MessageType;
 import org.mage.card.arcane.ManaSymbols;
@@ -53,7 +53,6 @@ import org.mage.card.arcane.ManaSymbols;
 public class ChatPanelBasic extends javax.swing.JPanel {
 
     protected UUID chatId;
-    protected Session session;
     /**
      * Chat message color for opponents.
      */
@@ -172,16 +171,15 @@ public class ChatPanelBasic extends javax.swing.JPanel {
     }
 
     public void connect(UUID chatId) {
-        session = MageFrame.getSession();
         this.chatId = chatId;
-        if (session.joinChat(chatId)) {
+        if (SessionHandler.joinChat(chatId)) {
             MageFrame.addChat(chatId, this);
         }
     }
 
     public void disconnect() {
-        if (session != null) {
-            session.leaveChat(chatId);
+        if (SessionHandler.getSession() != null) {
+            SessionHandler.leaveChat(chatId);
             MageFrame.removeChat(chatId);
         }
     }
@@ -216,9 +214,9 @@ public class ChatPanelBasic extends javax.swing.JPanel {
                 break;
             default:
                 if (parentChatRef != null) {
-                    userColor = parentChatRef.session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
+                    userColor = SessionHandler.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
                 } else {
-                    userColor = session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
+                    userColor = SessionHandler.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
                 }
                 textColor = MESSAGE_COLOR;
                 userSeparator = ": ";
@@ -343,9 +341,9 @@ public class ChatPanelBasic extends javax.swing.JPanel {
     public void handleKeyTyped(java.awt.event.KeyEvent evt) {
         if (evt.getKeyChar() == KeyEvent.VK_ENTER) {
             if (parentChatRef != null) {
-                parentChatRef.session.sendChatMessage(parentChatRef.chatId, this.txtMessage.getText());
+                SessionHandler.sendChatMessage(parentChatRef.chatId, this.txtMessage.getText());
             } else {
-                session.sendChatMessage(chatId, this.txtMessage.getText());
+                SessionHandler.sendChatMessage(chatId, this.txtMessage.getText());
             }
             this.txtMessage.setText("");
             this.txtMessage.repaint();
diff --git a/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java b/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java
index 197af97dd2..cfae0931f9 100644
--- a/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java
+++ b/Mage.Client/src/main/java/mage/client/chat/ChatPanelSeparated.java
@@ -28,6 +28,8 @@
 package mage.client.chat;
 
 import java.awt.Font;
+
+import mage.client.SessionHandler;
 import mage.client.components.ColorPane;
 import mage.client.util.GUISizeHelper;
 import mage.view.ChatMessage;
@@ -78,9 +80,9 @@ public class ChatPanelSeparated extends ChatPanelBasic {
                 break;
             default:
                 if (parentChatRef != null) {
-                    userColor = parentChatRef.session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
+                    userColor = SessionHandler.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
                 } else {
-                    userColor = session.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
+                    userColor = SessionHandler.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
                 }
                 textColor = MESSAGE_COLOR;
                 userSeparator = ": ";
diff --git a/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java b/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java
index 19c23b4ec7..87cc8a32fa 100644
--- a/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java
+++ b/Mage.Client/src/main/java/mage/client/components/ability/AbilityPicker.java
@@ -78,8 +78,8 @@ public class AbilityPicker extends JXPanel implements MouseWheelListener {
         jScrollPane2.getVerticalScrollBar().setUI(new MageScrollbarUI());
     }
 
-    public void init(Session session, UUID gameId) {
-        this.session = session;
+    public void init(UUID gameId) {
+
         this.gameId = gameId;
     }
 
diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java
index e7ba99792f..55742aff30 100644
--- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java
+++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java
@@ -35,6 +35,7 @@ import mage.cards.decks.importer.DeckImporterUtil;
 import mage.cards.repository.CardInfo;
 import mage.cards.repository.CardRepository;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.cards.BigCard;
 import mage.client.cards.ICardGrid;
 import mage.client.constants.Constants.DeckEditorMode;
@@ -168,7 +169,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
                 this.btnExit.setVisible(false);
                 this.btnImport.setVisible(false);
                 this.btnGenDeck.setVisible(false);
-                if (!MageFrame.getSession().isTestMode()) {
+                if (!SessionHandler.isTestMode()) {
                     this.btnLoad.setVisible(false);
                 }
                 this.deckArea.showSideboard(false);
@@ -178,7 +179,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
                 if (timeout != 0) {
                     countdown.start();
                     if (updateDeckTask == null || updateDeckTask.isDone()) {
-                        updateDeckTask = new UpdateDeckTask(MageFrame.getSession(), tableId, deck);
+                        updateDeckTask = new UpdateDeckTask(SessionHandler.getSession(), tableId, deck);
                         updateDeckTask.execute();
                     }
                 }
@@ -192,7 +193,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
                 this.btnExit.setVisible(true);
                 this.btnImport.setVisible(true);
                 this.btnGenDeck.setVisible(true);
-                if (!MageFrame.getSession().isTestMode()) {
+                if (!SessionHandler.isTestMode()) {
                     this.btnLoad.setVisible(true);
                 }
                 this.deckArea.showSideboard(true);
@@ -841,7 +842,7 @@ public class DeckEditorPanel extends javax.swing.JPanel {
             updateDeckTask.cancel(true);
         }
 
-        if (MageFrame.getSession().submitDeck(tableId, deck.getDeckCardLists())) {
+        if (SessionHandler.submitDeck(tableId, deck.getDeckCardLists())) {
             removeDeckEditor();
         }
     }//GEN-LAST:event_btnSubmitActionPerformed
diff --git a/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java
index dfe0a23309..864a4103f5 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/FeedbackDialog.java
@@ -29,6 +29,7 @@
 package mage.client.dialog;
 
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import org.apache.log4j.Logger;
 
 import javax.swing.*;
@@ -254,7 +255,7 @@ public class FeedbackDialog extends javax.swing.JDialog {
         if (email.length() > 100) {
             email = email.substring(0, 100);
         }
-        if (MageFrame.getSession().sendFeedback(title, type, message, email)) {
+        if (SessionHandler.sendFeedback(title, type, message, email)) {
             JOptionPane.showMessageDialog(null, "Feedback was sent. Thank you!", "Success", JOptionPane.INFORMATION_MESSAGE);
             reset();
             dialog.setVisible(false);
diff --git a/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java
index 706fe30e78..44ca907a1e 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/JoinTableDialog.java
@@ -31,6 +31,7 @@ import java.util.UUID;
 import javax.swing.JOptionPane;
 import mage.cards.decks.importer.DeckImporterUtil;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.remote.Session;
 import org.apache.log4j.Logger;
 
@@ -58,7 +59,7 @@ public class JoinTableDialog extends MageDialog {
         this.roomId = roomId;
         this.tableId = tableId;
         this.isTournament = isTournament;
-        this.newPlayerPanel.setPlayerName(MageFrame.getSession().getUserName());
+        this.newPlayerPanel.setPlayerName(SessionHandler.getUserName());
         this.newPlayerPanel.showDeckElements(!isLimited);
         this.setModal(true);
         this.setLocation(100, 100);
@@ -146,7 +147,7 @@ public class JoinTableDialog extends MageDialog {
     }//GEN-LAST:event_btnCancelActionPerformed
 
     private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
-        Session session = MageFrame.getSession();
+        Session session = SessionHandler.getSession();
         try {
             PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PASSWORD_JOIN, txtPassword.getText());
             if (isTournament) {
diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
index 89cdff4f2c..7fa024953d 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/NewTableDialog.java
@@ -38,6 +38,7 @@ import javax.swing.*;
 
 import mage.cards.decks.importer.DeckImporterUtil;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.components.MageComponents;
 import mage.client.table.TablePlayerPanel;
 import mage.client.util.Event;
@@ -47,7 +48,6 @@ import mage.constants.MultiplayerAttackOption;
 import mage.constants.RangeOfInfluence;
 import mage.constants.SkillLevel;
 import mage.game.match.MatchOptions;
-import mage.remote.Session;
 import mage.view.GameTypeView;
 import mage.view.TableView;
 import org.apache.log4j.Logger;
@@ -63,7 +63,6 @@ public class NewTableDialog extends MageDialog {
     private TableView table;
     private UUID playerId;
     private UUID roomId;
-    private final Session session;
     private String lastSessionId;
     private final List<TablePlayerPanel> players = new ArrayList<>();
     private final List<String> prefPlayerTypes = new ArrayList<>();
@@ -74,7 +73,6 @@ public class NewTableDialog extends MageDialog {
      * Creates new form NewTableDialog
      */
     public NewTableDialog() {
-        session = MageFrame.getSession();
         lastSessionId = "";
         initComponents();
         player1Panel.showLevel(false);
@@ -402,13 +400,13 @@ public class NewTableDialog extends MageDialog {
         }
         saveGameSettingsToPrefs(options, this.player1Panel.getDeckFile());
 
-        table = session.createTable(roomId, options);
+        table = SessionHandler.createTable(roomId, options);
         if (table == null) {
             JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error creating table.", "Error", JOptionPane.ERROR_MESSAGE);
             return;
         }
         try {
-            if (session.joinTable(
+            if (SessionHandler.joinTable(
                     roomId,
                     table.getTableId(),
                     this.player1Panel.getPlayerName(),
@@ -419,7 +417,7 @@ public class NewTableDialog extends MageDialog {
                     if (!player.getPlayerType().equals("Human")) {
                         if (!player.joinTable(roomId, table.getTableId())) {
                             // error message must be send by the server
-                            session.removeTable(roomId, table.getTableId());
+                            SessionHandler.removeTable(roomId, table.getTableId());
                             table = null;
                             return;
                         }
@@ -436,7 +434,7 @@ public class NewTableDialog extends MageDialog {
             handleError(ex);
         }
         // JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error joining table.", "Error", JOptionPane.ERROR_MESSAGE);
-        session.removeTable(roomId, table.getTableId());
+        SessionHandler.removeTable(roomId, table.getTableId());
         table = null;
     }//GEN-LAST:event_btnOKActionPerformed
 
@@ -560,11 +558,11 @@ public class NewTableDialog extends MageDialog {
 
     public void showDialog(UUID roomId) {
         this.roomId = roomId;
-        if (!lastSessionId.equals(MageFrame.getSession().getSessionId())) {
-            lastSessionId = session.getSessionId();
-            this.player1Panel.setPlayerName(session.getUserName());
-            cbGameType.setModel(new DefaultComboBoxModel(session.getGameTypes().toArray()));
-            cbDeckType.setModel(new DefaultComboBoxModel(session.getDeckTypes()));
+        if (!lastSessionId.equals(SessionHandler.getSessionId())) {
+            lastSessionId = SessionHandler.getSessionId();
+            this.player1Panel.setPlayerName(SessionHandler.getUserName());
+            cbGameType.setModel(new DefaultComboBoxModel(SessionHandler.getGameTypes().toArray()));
+            cbDeckType.setModel(new DefaultComboBoxModel(SessionHandler.getDeckTypes()));
             selectLimitedByDefault();
             cbTimeLimit.setModel(new DefaultComboBoxModel(MatchTimeLimit.values()));
             cbRange.setModel(new DefaultComboBoxModel(RangeOfInfluence.values()));
@@ -614,7 +612,7 @@ public class NewTableDialog extends MageDialog {
         this.spnNumPlayers.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_PLAYERS, "2")));
 
         String gameTypeName = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_GAME_TYPE, "Two Player Duel");
-        for (GameTypeView gtv : session.getGameTypes()) {
+        for (GameTypeView gtv : SessionHandler.getGameTypes()) {
             if (gtv.getName().equals(gameTypeName)) {
                 cbGameType.setSelectedItem(gtv);
                 break;
diff --git a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java
index 5417be3087..6ad35039fb 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/NewTournamentDialog.java
@@ -54,6 +54,7 @@ import mage.cards.decks.importer.DeckImporterUtil;
 import mage.cards.repository.ExpansionInfo;
 import mage.cards.repository.ExpansionRepository;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.table.TournamentPlayerPanel;
 import mage.constants.MatchTimeLimit;
 import mage.constants.MultiplayerAttackOption;
@@ -81,7 +82,6 @@ public class NewTournamentDialog extends MageDialog {
     private TableView table;
     private UUID playerId;
     private UUID roomId;
-    private final Session session;
     private String lastSessionId;
     private RandomPacksSelectorDialog randomPackSelector;
     private JTextArea txtRandomPacks;
@@ -97,7 +97,6 @@ public class NewTournamentDialog extends MageDialog {
     /** Creates new form NewTournamentDialog */
     public NewTournamentDialog() {
         initComponents();
-        session = MageFrame.getSession();
         lastSessionId = "";
         txtName.setText("Tournament");
         this.spnNumWins.setModel(new SpinnerNumberModel(2, 1, 5, 1));
@@ -109,18 +108,18 @@ public class NewTournamentDialog extends MageDialog {
 
     public void showDialog(UUID roomId) {
         this.roomId = roomId;
-        if (!lastSessionId.equals(MageFrame.getSession().getSessionId())) {
-            lastSessionId = session.getSessionId();
-            this.player1Panel.setPlayerName(session.getUserName());
+        if (!lastSessionId.equals(SessionHandler.getSessionId())) {
+            lastSessionId = SessionHandler.getSessionId();
+            this.player1Panel.setPlayerName(SessionHandler.getUserName());
             this.player1Panel.showLevel(false); // no computer
-            cbTournamentType.setModel(new DefaultComboBoxModel(session.getTournamentTypes().toArray()));
+            cbTournamentType.setModel(new DefaultComboBoxModel(SessionHandler.getTournamentTypes().toArray()));
 
-            cbGameType.setModel(new DefaultComboBoxModel(session.getTournamentGameTypes().toArray()));
-            cbDeckType.setModel(new DefaultComboBoxModel(session.getDeckTypes()));
+            cbGameType.setModel(new DefaultComboBoxModel(SessionHandler.getTournamentGameTypes().toArray()));
+            cbDeckType.setModel(new DefaultComboBoxModel(SessionHandler.getDeckTypes()));
 
             cbTimeLimit.setModel(new DefaultComboBoxModel(MatchTimeLimit.values()));
             cbSkillLevel.setModel(new DefaultComboBoxModel(SkillLevel.values()));
-            cbDraftCube.setModel(new DefaultComboBoxModel(session.getDraftCubes()));
+            cbDraftCube.setModel(new DefaultComboBoxModel(SessionHandler.getDraftCubes()));
             cbDraftTiming.setModel(new DefaultComboBoxModel(DraftOptions.TimingOption.values()));
             // update player types
             int i=2;
@@ -618,12 +617,12 @@ public class NewTournamentDialog extends MageDialog {
         tOptions.getMatchOptions().setRated(this.chkRated.isSelected());
         saveTournamentSettingsToPrefs(tOptions);
 
-        table = session.createTournamentTable(roomId, tOptions);
+        table = SessionHandler.createTournamentTable(roomId, tOptions);
         if (table == null) {
             // message must be send by server!
             return;
         }
-        if (session.joinTournamentTable(
+        if (SessionHandler.joinTournamentTable(
                 roomId,
                 table.getTableId(),
                 this.player1Panel.getPlayerName(),
@@ -634,7 +633,7 @@ public class NewTournamentDialog extends MageDialog {
                 if (!player.getPlayerType().toString().equals("Human")) {
                     if (!player.joinTournamentTable(roomId, table.getTableId(), DeckImporterUtil.importDeck(this.player1Panel.getDeckFile()))) {
                         // error message must be send by sever
-                        session.removeTable(roomId, table.getTableId());
+                        SessionHandler.removeTable(roomId, table.getTableId());
                         table = null;
                         return;
                     }
@@ -644,7 +643,7 @@ public class NewTournamentDialog extends MageDialog {
             return;
         }
         JOptionPane.showMessageDialog(MageFrame.getDesktop(), "Error joining tournament.", "Error", JOptionPane.ERROR_MESSAGE);
-        session.removeTable(roomId, table.getTableId());
+        SessionHandler.removeTable(roomId, table.getTableId());
         table = null;
     }//GEN-LAST:event_btnOkActionPerformed
 
@@ -978,7 +977,7 @@ public class NewTournamentDialog extends MageDialog {
         }
         this.spnConstructTime.setValue(constructionTime);
         String tournamentTypeName = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TOURNAMENT_TYPE, "Sealed Elimination");
-        for (TournamentTypeView tournamentTypeView : session.getTournamentTypes()) {
+        for (TournamentTypeView tournamentTypeView : SessionHandler.getTournamentTypes()) {
             if (tournamentTypeView.getName().equals(tournamentTypeName)) {
                 cbTournamentType.setSelectedItem(tournamentTypeView);
                 break;
diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
index 74ba0968fa..a491ecd085 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java
@@ -59,6 +59,7 @@ import javax.swing.JTextField;
 import javax.swing.border.Border;
 import javax.swing.filechooser.FileFilter;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.util.Config;
 import mage.client.util.GUISizeHelper;
 import mage.client.util.ImageHelper;
@@ -2627,7 +2628,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
         updateCache(KEY_AVATAR, String.valueOf(selectedAvatarId));
 
         try {
-            MageFrame.getSession().updatePreferencesForServer(getUserData());
+            SessionHandler.updatePreferencesForServer(getUserData());
 
             prefs.flush();
         } catch (BackingStoreException ex) {
@@ -3428,7 +3429,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
                 public void mousePressed(MouseEvent e) {
                     if (selectedAvatarId != id) {
                         setSelectedId(id);
-                        MageFrame.getSession().updatePreferencesForServer(getUserData());
+                        SessionHandler.updatePreferencesForServer(getUserData());
                     }
                 }
             });
diff --git a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java
index 83effb5455..a2565bf717 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/TableWaitingDialog.java
@@ -42,6 +42,7 @@ import javax.swing.Icon;
 import javax.swing.SwingWorker;
 import javax.swing.table.AbstractTableModel;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.chat.ChatPanelBasic;
 import mage.client.components.MageComponents;
 import mage.client.components.tray.MageTray;
@@ -68,7 +69,6 @@ public class TableWaitingDialog extends MageDialog {
     private UUID tableId;
     private UUID roomId;
     private boolean isTournament;
-    private Session session;
     private final TableWaitModel tableWaitModel;
     private UpdateSeatsTask updateTask;
 
@@ -77,7 +77,6 @@ public class TableWaitingDialog extends MageDialog {
      */
     public TableWaitingDialog() {
 
-        session = MageFrame.getSession();
         tableWaitModel = new TableWaitModel();
 
         initComponents();
@@ -150,9 +149,8 @@ public class TableWaitingDialog extends MageDialog {
         this.roomId = roomId;
         this.tableId = tableId;
         this.isTournament = isTournament;
-        session = MageFrame.getSession();
-        updateTask = new UpdateSeatsTask(session, roomId, tableId, this);
-        if (session.isTableOwner(roomId, tableId)) {
+        updateTask = new UpdateSeatsTask(SessionHandler.getSession(), roomId, tableId, this);
+        if (SessionHandler.isTableOwner(roomId, tableId)) {
             this.btnStart.setVisible(true);
             this.btnMoveDown.setVisible(true);
             this.btnMoveUp.setVisible(true);
@@ -161,7 +159,7 @@ public class TableWaitingDialog extends MageDialog {
             this.btnMoveDown.setVisible(false);
             this.btnMoveUp.setVisible(false);
         }
-        UUID chatId = session.getTableChatId(tableId);
+        UUID chatId = SessionHandler.getTableChatId(tableId);
         if (chatId != null) {
             this.chatPanel.connect(chatId);
             updateTask.execute();
@@ -283,17 +281,17 @@ public class TableWaitingDialog extends MageDialog {
 
     private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartActionPerformed
         if (!isTournament) {
-            if (session.startMatch(roomId, tableId)) {
+            if (SessionHandler.startMatch(roomId, tableId)) {
                 closeDialog();
             }
-        } else if (session.startTournament(roomId, tableId)) {
+        } else if (SessionHandler.startTournament(roomId, tableId)) {
             closeDialog();
         }
     }//GEN-LAST:event_btnStartActionPerformed
 
     private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
         try {
-            if (!session.leaveTable(roomId, tableId)) {
+            if (!SessionHandler.leaveTable(roomId, tableId)) {
                 return; // already started, so leave no more possible
             }
         } catch (Exception e) {
@@ -306,7 +304,7 @@ public class TableWaitingDialog extends MageDialog {
     private void btnMoveDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveDownActionPerformed
         int row = this.tableSeats.getSelectedRow();
         if (row < this.tableSeats.getRowCount() - 1) {
-            session.swapSeats(roomId, tableId, row, row + 1);
+            SessionHandler.swapSeats(roomId, tableId, row, row + 1);
             this.tableSeats.getSelectionModel().setSelectionInterval(row + 1, row + 1);
         }
 
@@ -315,7 +313,7 @@ public class TableWaitingDialog extends MageDialog {
     private void btnMoveUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMoveUpActionPerformed
         int row = this.tableSeats.getSelectedRow();
         if (row > 0) {
-            session.swapSeats(roomId, tableId, row, row - 1);
+            SessionHandler.swapSeats(roomId, tableId, row, row - 1);
             this.tableSeats.getSelectionModel().setSelectionInterval(row - 1, row - 1);
         }
     }//GEN-LAST:event_btnMoveUpActionPerformed
diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java
index e55588b743..788cbeceee 100644
--- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java
+++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java
@@ -63,6 +63,7 @@ import javax.swing.Timer;
 import mage.cards.repository.CardInfo;
 import mage.cards.repository.CardRepository;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.components.tray.MageTray;
 import mage.client.deckeditor.SortSettingDraft;
 import mage.client.dialog.PreferencesDialog;
@@ -75,7 +76,6 @@ import mage.client.util.Listener;
 import mage.client.util.audio.AudioManager;
 import mage.client.util.gui.BufferedImageBuilder;
 import mage.constants.PlayerAction;
-import mage.remote.Session;
 import mage.view.CardsView;
 import mage.view.DraftPickView;
 import mage.view.DraftView;
@@ -93,7 +93,6 @@ public class DraftPanel extends javax.swing.JPanel {
     private static final Logger LOGGER = Logger.getLogger(DraftPanel.class);
 
     private UUID draftId;
-    private Session session;
     private Timer countdown;
     private int timeout;
 
@@ -183,9 +182,8 @@ public class DraftPanel extends javax.swing.JPanel {
 
     public synchronized void showDraft(UUID draftId) {
         this.draftId = draftId;
-        session = MageFrame.getSession();
         MageFrame.addDraft(draftId, this);
-        if (!session.joinDraft(draftId)) {
+        if (!SessionHandler.joinDraft(draftId)) {
             hideDraft();
         }
 
@@ -334,7 +332,7 @@ public class DraftPanel extends javax.swing.JPanel {
             public void event(Event event) {
                 if (event.getEventName().equals("pick-a-card")) {
                     SimpleCardView source = (SimpleCardView) event.getSource();
-                    DraftPickView view = session.sendCardPick(draftId, source.getId(), cardsHidden);
+                    DraftPickView view = SessionHandler.sendCardPick(draftId, source.getId(), cardsHidden);
                     if (view != null) {
                         loadCardsToPickedCardsArea(view.getPicks());
                         draftBooster.loadBooster(EMPTY_VIEW, bigCard);
@@ -344,7 +342,7 @@ public class DraftPanel extends javax.swing.JPanel {
                 }
                 if (event.getEventName().equals("mark-a-card")) {
                     SimpleCardView source = (SimpleCardView) event.getSource();
-                    session.sendCardMark(draftId, source.getId());
+                    SessionHandler.sendCardMark(draftId, source.getId());
                 }
             }
         }
diff --git a/Mage.Client/src/main/java/mage/client/game/AbilityPicker.java b/Mage.Client/src/main/java/mage/client/game/AbilityPicker.java
index d8937a35b1..536e63bd1a 100644
--- a/Mage.Client/src/main/java/mage/client/game/AbilityPicker.java
+++ b/Mage.Client/src/main/java/mage/client/game/AbilityPicker.java
@@ -29,8 +29,8 @@
 package mage.client.game;
 
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.util.gui.GuiDisplayUtil;
-import mage.remote.Session;
 import mage.view.AbilityPickerView;
 
 import javax.swing.*;
@@ -49,15 +49,13 @@ import java.util.UUID;
  */
 public class AbilityPicker extends JPopupMenu implements PopupMenuListener {
 
-    private Session session;
     private UUID gameId;
 
     public AbilityPicker(String ThisIsnotUsedAnymore) {
         this.addPopupMenuListener(this);
     }
 
-    public void init(Session session, UUID gameId) {
-        this.session = session;
+    public void init(UUID gameId) {
         this.gameId = gameId;
     }
 
@@ -85,7 +83,7 @@ public class AbilityPicker extends JPopupMenu implements PopupMenuListener {
 
     @Override
     public void popupMenuCanceled(PopupMenuEvent e) {
-        session.sendPlayerBoolean(gameId, false);
+        SessionHandler.sendPlayerBoolean(gameId, false);
     }
 
     private class AbilityPickerAction extends AbstractAction {
@@ -99,7 +97,7 @@ public class AbilityPicker extends JPopupMenu implements PopupMenuListener {
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            session.sendPlayerUUID(gameId, id);
+            SessionHandler.sendPlayerUUID(gameId, id);
             setVisible(false);
         }
 
diff --git a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java
index 085200b02a..45ee23a874 100644
--- a/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java
+++ b/Mage.Client/src/main/java/mage/client/game/FeedbackPanel.java
@@ -42,6 +42,7 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.chat.ChatPanelBasic;
 import mage.client.dialog.MageDialog;
 import mage.client.util.GUISizeHelper;
@@ -68,7 +69,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
     }
 
     private UUID gameId;
-    private Session session;
     private FeedbackMode mode;
     private MageDialog connectedDialog;
     private ChatPanelBasic connectedChatPanel;
@@ -86,7 +86,6 @@ public class FeedbackPanel extends javax.swing.JPanel {
 
     public void init(UUID gameId) {
         this.gameId = gameId;
-        session = MageFrame.getSession();
         helper.init(gameId);
         setGUISize();
     }
@@ -295,29 +294,29 @@ public class FeedbackPanel extends javax.swing.JPanel {
             connectedDialog = null;
         }
         if (mode == FeedbackMode.SELECT && (evt.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK) {
-            session.sendPlayerInteger(gameId, 0);
+            SessionHandler.sendPlayerInteger(gameId, 0);
         } else if (mode == FeedbackMode.END) {
             GamePanel gamePanel = MageFrame.getGame(gameId);
             if (gamePanel != null) {
                 gamePanel.removeGame();
             }
         } else {
-            session.sendPlayerBoolean(gameId, false);
+            SessionHandler.sendPlayerBoolean(gameId, false);
         }
         //AudioManager.playButtonOk();
     }//GEN-LAST:event_btnRightActionPerformed
 
     private void btnLeftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLeftActionPerformed
-        session.sendPlayerBoolean(gameId, true);
+        SessionHandler.sendPlayerBoolean(gameId, true);
         AudioManager.playButtonCancel();
     }//GEN-LAST:event_btnLeftActionPerformed
 
     private void btnSpecialActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSpecialActionPerformed
-        session.sendPlayerString(gameId, "special");
+        SessionHandler.sendPlayerString(gameId, "special");
     }//GEN-LAST:event_btnSpecialActionPerformed
 
     private void btnUndoActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.UNDO, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.UNDO, gameId, null);
     }
 
     public void setHelperPanel(HelperPanel helper) {
diff --git a/Mage.Client/src/main/java/mage/client/game/GamePanel.java b/Mage.Client/src/main/java/mage/client/game/GamePanel.java
index d916871a9c..3597ba0b40 100644
--- a/Mage.Client/src/main/java/mage/client/game/GamePanel.java
+++ b/Mage.Client/src/main/java/mage/client/game/GamePanel.java
@@ -85,6 +85,7 @@ import mage.cards.Card;
 import mage.cards.action.ActionCallback;
 import mage.choices.Choice;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.cards.BigCard;
 import mage.client.chat.ChatPanelBasic;
 import mage.client.combat.CombatManager;
@@ -124,7 +125,6 @@ import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_NAME_LAST;
 import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
 import mage.constants.Zone;
 import mage.game.events.PlayerQueryEvent;
-import mage.remote.Session;
 import mage.view.AbilityPickerView;
 import mage.view.CardView;
 import mage.view.CardsView;
@@ -170,7 +170,6 @@ public final class GamePanel extends javax.swing.JPanel {
     private final ArrayList<ShowCardsDialog> pickTarget = new ArrayList<>();
     private UUID gameId;
     private UUID playerId; // playerId of the player
-    private Session session;
     GamePane gamePane;
     private ReplayTask replayTask;
     private final PickNumberDialog pickNumber;
@@ -488,11 +487,10 @@ public final class GamePanel extends javax.swing.JPanel {
         this.gameId = gameId;
         this.gamePane = gamePane;
         this.playerId = playerId;
-        session = MageFrame.getSession();
         MageFrame.addGame(gameId, this);
         this.feedbackPanel.init(gameId);
         this.feedbackPanel.clear();
-        this.abilityPicker.init(session, gameId);
+        this.abilityPicker.init(gameId);
 
         this.btnConcede.setVisible(true);
         this.btnStopWatching.setVisible(false);
@@ -509,8 +507,8 @@ public final class GamePanel extends javax.swing.JPanel {
         this.pnlReplay.setVisible(false);
 
         this.gameChatPanel.clear();
-        this.gameChatPanel.connect(session.getGameChatId(gameId));
-        if (!session.joinGame(gameId)) {
+        this.gameChatPanel.connect(SessionHandler.getGameChatId(gameId));
+        if (!SessionHandler.joinGame(gameId)) {
             removeGame();
         } else {
             // play start sound
@@ -522,7 +520,6 @@ public final class GamePanel extends javax.swing.JPanel {
         this.gameId = gameId;
         this.gamePane = gamePane;
         this.playerId = null;
-        session = MageFrame.getSession();
         MageFrame.addGame(gameId, this);
         this.feedbackPanel.init(gameId);
         this.feedbackPanel.clear();
@@ -542,8 +539,8 @@ public final class GamePanel extends javax.swing.JPanel {
 
         this.pnlReplay.setVisible(false);
         this.gameChatPanel.clear();
-        this.gameChatPanel.connect(session.getGameChatId(gameId));
-        if (!session.watchGame(gameId)) {
+        this.gameChatPanel.connect(SessionHandler.getGameChatId(gameId));
+        if (!SessionHandler.watchGame(gameId)) {
             removeGame();
         }
         for (PlayAreaPanel panel : getPlayers().values()) {
@@ -554,7 +551,6 @@ public final class GamePanel extends javax.swing.JPanel {
     public synchronized void replayGame(UUID gameId) {
         this.gameId = gameId;
         this.playerId = null;
-        session = MageFrame.getSession();
         MageFrame.addGame(gameId, this);
         this.feedbackPanel.init(gameId);
         this.feedbackPanel.clear();
@@ -564,7 +560,7 @@ public final class GamePanel extends javax.swing.JPanel {
         this.btnStopWatching.setVisible(false);
         this.pnlReplay.setVisible(true);
         this.gameChatPanel.clear();
-        if (!session.startReplay(gameId)) {
+        if (!SessionHandler.startReplay(gameId)) {
             removeGame();
         }
         for (PlayAreaPanel panel : getPlayers().values()) {
@@ -1286,9 +1282,9 @@ public final class GamePanel extends javax.swing.JPanel {
     public void getAmount(int min, int max, String message) {
         pickNumber.showDialog(min, max, message);
         if (pickNumber.isCancel()) {
-            session.sendPlayerBoolean(gameId, false);
+            SessionHandler.sendPlayerBoolean(gameId, false);
         } else {
-            session.sendPlayerInteger(gameId, pickNumber.getAmount());
+            SessionHandler.sendPlayerInteger(gameId, pickNumber.getAmount());
         }
     }
 
@@ -1298,12 +1294,12 @@ public final class GamePanel extends javax.swing.JPanel {
         pickChoice.showDialog(choice, objectId, choiceWindowState);
         if (choice.isKeyChoice()) {
             if (pickChoice.isAutoSelect()) {
-                session.sendPlayerString(gameId, "#" + choice.getChoiceKey());
+                SessionHandler.sendPlayerString(gameId, "#" + choice.getChoiceKey());
             } else {
-                session.sendPlayerString(gameId, choice.getChoiceKey());
+                SessionHandler.sendPlayerString(gameId, choice.getChoiceKey());
             }
         } else {
-            session.sendPlayerString(gameId, choice.getChoice());
+            SessionHandler.sendPlayerString(gameId, choice.getChoice());
         }
         choiceWindowState = new MageDialogState(pickChoice);
         pickChoice.removeDialog();
@@ -1313,7 +1309,7 @@ public final class GamePanel extends javax.swing.JPanel {
         hideAll();
         PickPileDialog pickPileDialog = new PickPileDialog();
         pickPileDialog.loadCards(message, pile1, pile2, bigCard, gameId);
-        session.sendPlayerBoolean(gameId, pickPileDialog.isPickedPile1());
+        SessionHandler.sendPlayerBoolean(gameId, pickPileDialog.isPickedPile1());
         pickPileDialog.cleanUp();
         pickPileDialog.removeDialog();
     }
@@ -1685,7 +1681,7 @@ public final class GamePanel extends javax.swing.JPanel {
         this.getActionMap().put("USEFIRSTMANAABILITY", new AbstractAction() {
             @Override
             public void actionPerformed(ActionEvent actionEvent) {
-                session.sendPlayerAction(PlayerAction.USE_FIRST_MANA_ABILITY_ON, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.USE_FIRST_MANA_ABILITY_ON, gameId, null);
                 setMenuStates(
                         PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
                         PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
@@ -1729,7 +1725,7 @@ public final class GamePanel extends javax.swing.JPanel {
         this.getActionMap().put("USEFIRSTMANAABILITY_RELEASE", new AbstractAction() {
             @Override
             public void actionPerformed(ActionEvent actionEvent) {
-                session.sendPlayerAction(PlayerAction.USE_FIRST_MANA_ABILITY_OFF, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.USE_FIRST_MANA_ABILITY_OFF, gameId, null);
                 setMenuStates(
                         PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT, "true").equals("true"),
                         PreferencesDialog.getCachedValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, "true").equals("true"),
@@ -2113,49 +2109,49 @@ public final class GamePanel extends javax.swing.JPanel {
     }
 
     private void btnEndTurnActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(true, false, false, false, false, false);
     }
 
     private void btnUntilEndOfTurnActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(false, true, false, false, false, false);
     }
 
     private void btnEndTurnSkipStackActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(true, false, false, false, true, false);
     }
 
     private void btnUntilNextMainPhaseActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(false, false, true, false, false, false);
     }
 
     private void btnPassPriorityUntilNextYourTurnActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(false, false, false, true, false, false);
     }
 
     private void btnPassPriorityUntilStackResolvedActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_STACK_RESOLVED, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_STACK_RESOLVED, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(false, false, false, false, true, false);
     }
 
     private void btnSkipToEndStepBeforeYourTurnActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_END_STEP_BEFORE_MY_NEXT_TURN, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_END_STEP_BEFORE_MY_NEXT_TURN, gameId, null);
         AudioManager.playOnSkipButton();
         updateSkipButtons(false, false, false, false, false, true);
     }
 
     private void restorePriorityActionPerformed(java.awt.event.ActionEvent evt) {
-        session.sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null);
+        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null);
         AudioManager.playOnSkipButtonCancel();
         updateSkipButtons(false, false, false, false, false, false);
     }
@@ -2205,22 +2201,22 @@ public final class GamePanel extends javax.swing.JPanel {
     }//GEN-LAST:event_btnStopReplayActionPerformed
 
     private void btnNextPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNextPlayActionPerformed
-        session.nextPlay(gameId);
+        SessionHandler.nextPlay(gameId);
     }//GEN-LAST:event_btnNextPlayActionPerformed
 
     private void btnPreviousPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPreviousPlayActionPerformed
-        session.previousPlay(gameId);
+        SessionHandler.previousPlay(gameId);
     }//GEN-LAST:event_btnPreviousPlayActionPerformed
 
     private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayActionPerformed
         if (replayTask == null || replayTask.isDone()) {
-            replayTask = new ReplayTask(session, gameId);
+            replayTask = new ReplayTask(gameId);
             replayTask.execute();
         }
     }//GEN-LAST:event_btnPlayActionPerformed
 
     private void btnSkipForwardActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSkipForwardActionPerformed
-        session.skipForward(gameId, 10);
+        SessionHandler.skipForward(gameId, 10);
     }//GEN-LAST:event_btnSkipForwardActionPerformed
 
     public void setJLayeredPane(JLayeredPane jLayeredPane) {
@@ -2279,27 +2275,27 @@ public final class GamePanel extends javax.swing.JPanel {
         }
         switch (e.getActionCommand()) {
             case CMD_AUTO_ORDER_FIRST:
-                session.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_FIRST, gameId, abilityId);
-                session.sendPlayerUUID(gameId, abilityId);
+                SessionHandler.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_FIRST, gameId, abilityId);
+                SessionHandler.sendPlayerUUID(gameId, abilityId);
                 break;
             case CMD_AUTO_ORDER_LAST:
-                session.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_LAST, gameId, abilityId);
-                session.sendPlayerUUID(gameId, null); // Don't use this but refresh the displayed abilities
+                SessionHandler.sendPlayerAction(TRIGGER_AUTO_ORDER_ABILITY_LAST, gameId, abilityId);
+                SessionHandler.sendPlayerUUID(gameId, null); // Don't use this but refresh the displayed abilities
                 break;
             case CMD_AUTO_ORDER_NAME_FIRST:
                 if (abilityRuleText != null) {
-                    session.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_FIRST, gameId, abilityRuleText);
-                    session.sendPlayerUUID(gameId, abilityId);
+                    SessionHandler.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_FIRST, gameId, abilityRuleText);
+                    SessionHandler.sendPlayerUUID(gameId, abilityId);
                 }
                 break;
             case CMD_AUTO_ORDER_NAME_LAST:
                 if (abilityRuleText != null) {
-                    session.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_LAST, gameId, abilityRuleText);
-                    session.sendPlayerUUID(gameId, null); // Don't use this but refresh the displayed abilities
+                    SessionHandler.sendPlayerAction(TRIGGER_AUTO_ORDER_NAME_LAST, gameId, abilityRuleText);
+                    SessionHandler.sendPlayerUUID(gameId, null); // Don't use this but refresh the displayed abilities
                 }
                 break;
             case CMD_AUTO_ORDER_RESET_ALL:
-                session.sendPlayerAction(TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null);
+                SessionHandler.sendPlayerAction(TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null);
                 break;
         }
         for (ShowCardsDialog dialog : pickTarget) {
@@ -2350,9 +2346,6 @@ public final class GamePanel extends javax.swing.JPanel {
         return gameChatPanel.getText();
     }
 
-    public Session getSession() {
-        return session;
-    }
 
     public Map<String, Card> getLoadedCards() {
         return loadedCards;
@@ -2401,9 +2394,9 @@ public final class GamePanel extends javax.swing.JPanel {
             holdingPriority = holdPriority;
             txtHoldPriority.setVisible(holdPriority);
             if (holdPriority) {
-                session.sendPlayerAction(PlayerAction.HOLD_PRIORITY, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.HOLD_PRIORITY, gameId, null);
             } else {
-                session.sendPlayerAction(PlayerAction.UNHOLD_PRIORITY, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.UNHOLD_PRIORITY, gameId, null);
             }
         }
     }
@@ -2474,20 +2467,18 @@ public final class GamePanel extends javax.swing.JPanel {
 
 class ReplayTask extends SwingWorker<Void, Collection<MatchView>> {
 
-    private final Session session;
     private final UUID gameId;
 
     private static final Logger logger = Logger.getLogger(ReplayTask.class);
 
-    ReplayTask(Session session, UUID gameId) {
-        this.session = session;
+    ReplayTask(UUID gameId) {
         this.gameId = gameId;
     }
 
     @Override
     protected Void doInBackground() throws Exception {
         while (!isCancelled()) {
-            session.nextPlay(gameId);
+            SessionHandler.nextPlay(gameId);
             Thread.sleep(1000);
         }
         return null;
diff --git a/Mage.Client/src/main/java/mage/client/game/HelperPanel.java b/Mage.Client/src/main/java/mage/client/game/HelperPanel.java
index e4873596b3..0aae26c5d3 100644
--- a/Mage.Client/src/main/java/mage/client/game/HelperPanel.java
+++ b/Mage.Client/src/main/java/mage/client/game/HelperPanel.java
@@ -49,6 +49,7 @@ import javax.swing.SwingUtilities;
 import javax.swing.ToolTipManager;
 import javax.swing.UIManager;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.components.MageTextArea;
 import mage.client.game.FeedbackPanel.FeedbackMode;
 import static mage.client.game.FeedbackPanel.FeedbackMode.QUESTION;
@@ -100,7 +101,6 @@ public class HelperPanel extends JPanel {
     private String message;
 
     private UUID gameId;
-    private Session session;
 
     public HelperPanel() {
         initComponents();
@@ -108,7 +108,6 @@ public class HelperPanel extends JPanel {
 
     public void init(UUID gameId) {
         this.gameId = gameId;
-        session = MageFrame.getSession();
     }
 
     public void changeGUISize() {
@@ -414,23 +413,23 @@ public class HelperPanel extends JPanel {
     public void handleAutoAnswerPopupMenuEvent(ActionEvent e) {
         switch (e.getActionCommand()) {
             case CMD_AUTO_ANSWER_ID_YES:
-                session.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_YES, gameId, originalId.toString() + "#" + message);
+                SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_YES, gameId, originalId.toString() + "#" + message);
                 clickButton(btnLeft);
                 break;
             case CMD_AUTO_ANSWER_ID_NO:
-                session.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_NO, gameId, originalId.toString() + "#" + message);
+                SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_ID_NO, gameId, originalId.toString() + "#" + message);
                 clickButton(btnRight);
                 break;
             case CMD_AUTO_ANSWER_NAME_YES:
-                session.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_YES, gameId, message);
+                SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_YES, gameId, message);
                 clickButton(btnLeft);
                 break;
             case CMD_AUTO_ANSWER_NAME_NO:
-                session.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_NO, gameId, message);
+                SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_TEXT_NO, gameId, message);
                 clickButton(btnRight);
                 break;
             case CMD_AUTO_ANSWER_RESET_ALL:
-                session.sendPlayerAction(REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
+                SessionHandler.sendPlayerAction(REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
                 break;
         }
     }
diff --git a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java
index c4ff4264f3..e8001fee6c 100644
--- a/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java
+++ b/Mage.Client/src/main/java/mage/client/game/PlayAreaPanel.java
@@ -49,6 +49,7 @@ import javax.swing.MenuSelectionManager;
 import javax.swing.event.ChangeListener;
 import mage.cards.decks.importer.DeckImporterUtil;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.cards.BigCard;
 import mage.client.dialog.PreferencesDialog;
 import static mage.client.dialog.PreferencesDialog.KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS;
@@ -168,31 +169,31 @@ public class PlayAreaPanel extends javax.swing.JPanel {
                         break;
                     }
                     case "F3": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS, gameId, null);
                         break;
                     }
                     case "F4": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN, gameId, null);
                         break;
                     }
                     case "F5": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP, gameId, null);
                         break;
                     }
                     case "F6": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN_SKIP_STACK, gameId, null);
                         break;
                     }
                     case "F7": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE, gameId, null);
                         break;
                     }
                     case "F9": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN, gameId, null);
                         break;
                     }
                     case "F11": {
-                        gamePanel.getSession().sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_END_STEP_BEFORE_MY_NEXT_TURN, gameId, null);
+                        SessionHandler.sendPlayerAction(PlayerAction.PASS_PRIORITY_UNTIL_END_STEP_BEFORE_MY_NEXT_TURN, gameId, null);
                         break;
                     }
                 }
@@ -292,7 +293,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
                 boolean manaPoolAutomatic = ((JCheckBoxMenuItem) e.getSource()).getState();
                 PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT, manaPoolAutomatic ? "true" : "false");
                 gamePanel.setMenuStates(manaPoolAutomatic, manaPoolMenuItem2.getState(), useFirstManaAbilityItem.getState(), holdPriorityMenuItem.getState());
-                gamePanel.getSession().sendPlayerAction(manaPoolAutomatic ? PlayerAction.MANA_AUTO_PAYMENT_ON : PlayerAction.MANA_AUTO_PAYMENT_OFF, gameId, null);
+                SessionHandler.sendPlayerAction(manaPoolAutomatic ? PlayerAction.MANA_AUTO_PAYMENT_ON : PlayerAction.MANA_AUTO_PAYMENT_OFF, gameId, null);
             }
         });
 
@@ -310,7 +311,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
                 boolean manaPoolAutomaticRestricted = ((JCheckBoxMenuItem) e.getSource()).getState();
                 PreferencesDialog.saveValue(KEY_GAME_MANA_AUTOPAYMENT_ONLY_ONE, manaPoolAutomaticRestricted ? "true" : "false");
                 gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolAutomaticRestricted, useFirstManaAbilityItem.getState(), holdPriorityMenuItem.getState());
-                gamePanel.getSession().sendPlayerAction(manaPoolAutomaticRestricted ? PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_ON : PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_OFF, gameId, null);
+                SessionHandler.sendPlayerAction(manaPoolAutomaticRestricted ? PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_ON : PlayerAction.MANA_AUTO_PAYMENT_RESTRICTED_OFF, gameId, null);
             }
         });
 
@@ -328,7 +329,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
                 boolean useFirstManaAbility = ((JCheckBoxMenuItem) e.getSource()).getState();
                 PreferencesDialog.saveValue(KEY_USE_FIRST_MANA_ABILITY, useFirstManaAbility ? "true" : "false");
                 gamePanel.setMenuStates(manaPoolMenuItem1.getState(), manaPoolMenuItem2.getState(), useFirstManaAbility, holdPriorityMenuItem.getState());
-                gamePanel.getSession().sendPlayerAction(useFirstManaAbility ? PlayerAction.USE_FIRST_MANA_ABILITY_ON : PlayerAction.USE_FIRST_MANA_ABILITY_OFF, gameId, null);
+                SessionHandler.sendPlayerAction(useFirstManaAbility ? PlayerAction.USE_FIRST_MANA_ABILITY_ON : PlayerAction.USE_FIRST_MANA_ABILITY_OFF, gameId, null);
             }
         });
 
@@ -344,7 +345,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
         menuItem.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                gamePanel.getSession().sendPlayerAction(PlayerAction.RESET_AUTO_SELECT_REPLACEMENT_EFFECTS, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.RESET_AUTO_SELECT_REPLACEMENT_EFFECTS, gameId, null);
             }
         });
 
@@ -356,7 +357,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
         menuItem.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                gamePanel.getSession().sendPlayerAction(PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL, gameId, null);
             }
         });
 
@@ -368,7 +369,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
         menuItem.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                gamePanel.getSession().sendPlayerAction(PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
+                SessionHandler.sendPlayerAction(PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL, gameId, null);
             }
         });
 
@@ -385,7 +386,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
             menuItem.addActionListener(new ActionListener() {
                 @Override
                 public void actionPerformed(ActionEvent e) {
-                    gamePanel.getSession().sendPlayerAction(PlayerAction.REQUEST_PERMISSION_TO_SEE_HAND_CARDS, gameId, playerId);
+                    SessionHandler.sendPlayerAction(PlayerAction.REQUEST_PERMISSION_TO_SEE_HAND_CARDS, gameId, playerId);
                 }
             });
         } else {
@@ -400,7 +401,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
                 public void actionPerformed(ActionEvent e) {
                     boolean requestsAllowed = ((JCheckBoxMenuItem) e.getSource()).getState();
                     PreferencesDialog.setPrefValue(KEY_GAME_ALLOW_REQUEST_SHOW_HAND_CARDS, requestsAllowed);
-                    gamePanel.getSession().sendPlayerAction(requestsAllowed ? PlayerAction.PERMISSION_REQUESTS_ALLOWED_ON : PlayerAction.PERMISSION_REQUESTS_ALLOWED_OFF, gameId, null);
+                    SessionHandler.sendPlayerAction(requestsAllowed ? PlayerAction.PERMISSION_REQUESTS_ALLOWED_ON : PlayerAction.PERMISSION_REQUESTS_ALLOWED_OFF, gameId, null);
                 }
             });
 
@@ -413,7 +414,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
             menuItem.addActionListener(new ActionListener() {
                 @Override
                 public void actionPerformed(ActionEvent e) {
-                    gamePanel.getSession().sendPlayerAction(PlayerAction.REVOKE_PERMISSIONS_TO_SEE_HAND_CARDS, gameId, null);
+                    SessionHandler.sendPlayerAction(PlayerAction.REVOKE_PERMISSIONS_TO_SEE_HAND_CARDS, gameId, null);
                 }
             });
         }
@@ -423,7 +424,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
                 @Override
                 public void actionPerformed(ActionEvent e) {
                     int turnsToRollBack = Integer.parseInt(e.getActionCommand());
-                    gamePanel.getSession().sendPlayerAction(PlayerAction.ROLLBACK_TURNS, gameId, turnsToRollBack);
+                    SessionHandler.sendPlayerAction(PlayerAction.ROLLBACK_TURNS, gameId, turnsToRollBack);
                 }
             };
 
@@ -548,7 +549,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
         menuItem.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                gamePanel.getSession().sendPlayerAction(PlayerAction.REQUEST_PERMISSION_TO_SEE_HAND_CARDS, gameId, playerId);
+                SessionHandler.sendPlayerAction(PlayerAction.REQUEST_PERMISSION_TO_SEE_HAND_CARDS, gameId, playerId);
             }
         });
 
@@ -578,7 +579,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
         this.battlefieldPanel.init(gameId, bigCard);
         this.gameId = gameId;
         this.playerId = player.getPlayerId();
-        if (MageFrame.getSession().isTestMode()) {
+        if (SessionHandler.isTestMode()) {
             this.btnCheat.setVisible(true);
         } else {
             this.btnCheat.setVisible(false);
@@ -646,7 +647,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
     }
 
     private void btnCheatActionPerformed(java.awt.event.ActionEvent evt) {
-        MageFrame.getSession().cheat(gameId, playerId, DeckImporterUtil.importDeck("cheat.dck"));
+        SessionHandler.cheat(gameId, playerId, DeckImporterUtil.importDeck("cheat.dck"));
     }
 
     public boolean isSmallMode() {
diff --git a/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java b/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java
index 7f454e5269..3a0c17c400 100644
--- a/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java
+++ b/Mage.Client/src/main/java/mage/client/game/PlayerPanelExt.java
@@ -61,6 +61,7 @@ import javax.swing.border.LineBorder;
 import mage.MageException;
 import mage.cards.decks.importer.DckDeckImporter;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.cards.BigCard;
 import mage.client.components.HoverButton;
 import mage.client.components.MageRoundPane;
@@ -134,8 +135,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
         this.gameId = gameId;
         this.playerId = playerId;
         this.bigCard = bigCard;
-        session = MageFrame.getSession();
-        cheat.setVisible(session.isTestMode());
+        cheat.setVisible(SessionHandler.isTestMode());
         cheat.setFocusable(false);
         flagName = null;
         if (priorityTime > 0) {
diff --git a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java
index 4c18ca7fb2..4b628f2465 100644
--- a/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java
+++ b/Mage.Client/src/main/java/mage/client/plugins/adapters/MageActionCallback.java
@@ -27,6 +27,7 @@ import mage.cards.MageCard;
 import mage.cards.action.ActionCallback;
 import mage.cards.action.TransferData;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.cards.BigCard;
 import mage.client.components.MageComponents;
 import mage.client.dialog.PreferencesDialog;
@@ -38,7 +39,6 @@ import mage.client.util.gui.ArrowUtil;
 import mage.client.util.gui.GuiDisplayUtil;
 import mage.components.CardInfoPane;
 import mage.constants.EnlargeMode;
-import mage.remote.Session;
 import mage.utils.ThreadUtils;
 import mage.view.CardView;
 import mage.view.PermanentView;
@@ -69,7 +69,7 @@ public class MageActionCallback implements ActionCallback {
     private JPopupMenu jPopupMenu;
     private BigCard bigCard;
     protected static final DefaultActionCallback defaultCallback = DefaultActionCallback.getInstance();
-    protected static Session session = MageFrame.getSession();
+
     private CardView tooltipCard;
     private TransferData popupData;
     private JComponent cardInfoPane;
@@ -104,9 +104,6 @@ public class MageActionCallback implements ActionCallback {
     }
 
     public synchronized void refreshSession() {
-        if (session == null) {
-            session = MageFrame.getSession();
-        }
         if (cardInfoPane == null) {
             cardInfoPane = Plugins.getInstance().getCardInfoPane();
         }
@@ -173,7 +170,7 @@ public class MageActionCallback implements ActionCallback {
             public void run() {
                 ThreadUtils.sleep(tooltipDelay);
 
-                if (tooltipCard == null || !tooltipCard.equals(data.card) || session == null || !popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) {
+                if (tooltipCard == null || !tooltipCard.equals(data.card) || SessionHandler.getSession() == null || !popupTextWindowOpen || !enlargedWindowState.equals(EnlargedWindowState.CLOSED)) {
                     return;
                 }
 
@@ -253,14 +250,14 @@ public class MageActionCallback implements ActionCallback {
             this.startedDragging = false;
             if (maxXOffset < MIN_X_OFFSET_REQUIRED) { // we need this for protection from small card movements
                 transferData.component.requestFocusInWindow();
-                defaultCallback.mouseClicked(e, transferData.gameId, session, transferData.card);
+                defaultCallback.mouseClicked(e, transferData.gameId, transferData.card);
                 // Closes popup & enlarged view if a card/Permanent is selected
                 hideTooltipPopup();
             }
             e.consume();
         } else {
             transferData.component.requestFocusInWindow();
-            defaultCallback.mouseClicked(e, transferData.gameId, session, transferData.card);
+            defaultCallback.mouseClicked(e, transferData.gameId, transferData.card);
             // Closes popup & enlarged view if a card/Permanent is selected
             hideTooltipPopup();
             e.consume();
@@ -423,7 +420,7 @@ public class MageActionCallback implements ActionCallback {
             jPopupMenu.setVisible(false);
         }
         try {
-            if (session == null) {
+            if (SessionHandler.getSession() == null) {
                 return;
             }
             // set enlarged card display to visible = false
diff --git a/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java
index 99f0bed425..aefca569cf 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablePlayerPanel.java
@@ -40,6 +40,7 @@ import java.util.UUID;
 import javax.swing.DefaultComboBoxModel;
 import mage.cards.decks.importer.DeckImporterUtil;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.util.Config;
 import mage.client.util.Event;
 import mage.client.util.Listener;
@@ -53,7 +54,6 @@ public class TablePlayerPanel extends javax.swing.JPanel {
 
     protected PlayerTypeEventSource playerTypeEventSource = new PlayerTypeEventSource();
 
-    private Session session;
 
     /** Creates new form TablePlayerPanel */
     public TablePlayerPanel() {
@@ -62,8 +62,7 @@ public class TablePlayerPanel extends javax.swing.JPanel {
     }
 
     public void init(int playerNum, String playerType) {
-        session = MageFrame.getSession();
-        cbPlayerType.setModel(new DefaultComboBoxModel(session.getPlayerTypes()));
+        cbPlayerType.setModel(new DefaultComboBoxModel(SessionHandler.getPlayerTypes()));
         this.lblPlayerNum.setText("Player " + playerNum);
         if (Config.defaultOtherPlayerIndex != null) {
             if (Integer.valueOf(Config.defaultOtherPlayerIndex) >= cbPlayerType.getItemCount()) {
@@ -81,7 +80,7 @@ public class TablePlayerPanel extends javax.swing.JPanel {
 
     public boolean joinTable(UUID roomId, UUID tableId) throws FileNotFoundException, IOException, ClassNotFoundException {
         if (!this.cbPlayerType.getSelectedItem().equals("Human")) {
-            return session.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (String)this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()),"");
+            return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (String)this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporterUtil.importDeck(this.newPlayerPanel.getDeckFile()),"");
          }
         return true;
     }
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPane.java b/Mage.Client/src/main/java/mage/client/table/TablesPane.java
index 7e4739aa72..b2754f06f7 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablesPane.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablesPane.java
@@ -31,6 +31,7 @@ import java.util.UUID;
 import javax.swing.JComponent;
 import mage.client.MageFrame;
 import mage.client.MagePane;
+import mage.client.SessionHandler;
 import mage.client.plugins.impl.Plugins;
 
 /**
@@ -70,7 +71,7 @@ public class TablesPane extends MagePane {
     }
 
     public void showTables() {
-        UUID roomId = MageFrame.getSession().getMainRoomId();
+        UUID roomId = SessionHandler.getSession().getMainRoomId();
         if (roomId != null) {
             this.setTitle("Tables");
             tablesPanel.showTables(roomId);
diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
index 0e08570077..253a3e08cc 100644
--- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
+++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java
@@ -72,6 +72,7 @@ import javax.swing.SwingWorker;
 import javax.swing.table.AbstractTableModel;
 import mage.cards.decks.importer.DeckImporterUtil;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.chat.ChatPanelBasic;
 import mage.client.components.MageComponents;
 import mage.client.dialog.JoinTableDialog;
@@ -93,7 +94,6 @@ import mage.constants.RangeOfInfluence;
 import mage.constants.SkillLevel;
 import mage.game.match.MatchOptions;
 import mage.remote.MageRemoteException;
-import mage.remote.Session;
 import mage.view.MatchView;
 import mage.view.RoomUsersView;
 import mage.view.TableView;
@@ -119,7 +119,6 @@ public class TablesPanel extends javax.swing.JPanel {
     private NewTableDialog newTableDialog;
     private NewTournamentDialog newTournamentDialog;
     private GameChooser gameChooser;
-    private Session session;
     private List<String> messages;
     private int currentMessage;
     private MageTableRowSorter activeTablesSorter;
@@ -139,7 +138,7 @@ public class TablesPanel extends javax.swing.JPanel {
         gameChooser = new GameChooser();
 
         initComponents();
-        tableModel.setSession(session);
+      //  tableModel.setSession(session);
 
         tableTables.createDefaultColumnsFromModel();
 
@@ -186,7 +185,7 @@ public class TablesPanel extends javax.swing.JPanel {
                 String owner = (String) tableModel.getValueAt(modelRow, TableTableModel.COLUMN_OWNER);
                 switch (action) {
                     case "Join":
-                        if (owner.equals(session.getUserName()) || owner.startsWith(session.getUserName() + ",")) {
+                        if (owner.equals(SessionHandler.getUserName()) || owner.startsWith(SessionHandler.getUserName() + ",")) {
                             try {
                                 JDesktopPane desktopPane = (JDesktopPane) MageFrame.getUI().getComponent(MageComponents.DESKTOP_PANE);
                                 JInternalFrame[] windows = desktopPane.getAllFramesInLayer(javax.swing.JLayeredPane.DEFAULT_LAYER);
@@ -211,7 +210,7 @@ public class TablesPanel extends javax.swing.JPanel {
                             LOGGER.info("Joining tournament " + tableId);
                             if (deckType.startsWith("Limited")) {
                                 if (!status.endsWith("PW")) {
-                                    session.joinTournamentTable(roomId, tableId, session.getUserName(), "Human", 1, null, "");
+                                    SessionHandler.joinTournamentTable(roomId, tableId, SessionHandler.getUserName(), "Human", 1, null, "");
                                 } else {
                                     joinTableDialog.showDialog(roomId, tableId, true, deckType.startsWith("Limited"));
                                 }
@@ -232,18 +231,18 @@ public class TablesPanel extends javax.swing.JPanel {
                     case "Show":
                         if (isTournament) {
                             LOGGER.info("Showing tournament table " + tableId);
-                            session.watchTable(roomId, tableId);
+                            SessionHandler.watchTable(roomId, tableId);
                         }
                         break;
                     case "Watch":
                         if (!isTournament) {
                             LOGGER.info("Watching table " + tableId);
-                            session.watchTable(roomId, tableId);
+                            SessionHandler.watchTable(roomId, tableId);
                         }
                         break;
                     case "Replay":
                         LOGGER.info("Replaying game " + gameId);
-                        session.replayGame(gameId);
+                        SessionHandler.replayGame(gameId);
                         break;
                 }
             }
@@ -260,7 +259,7 @@ public class TablesPanel extends javax.swing.JPanel {
                         List<UUID> gameList = matchesModel.getListofGames(modelRow);
                         if (gameList != null && gameList.size() > 0) {
                             if (gameList.size() == 1) {
-                                session.replayGame(gameList.get(0));
+                                SessionHandler.replayGame(gameList.get(0));
                             } else {
                                 gameChooser.show(gameList, MageFrame.getDesktop().getMousePosition());
                             }
@@ -270,7 +269,7 @@ public class TablesPanel extends javax.swing.JPanel {
                     case "Show":;
                         if (matchesModel.isTournament(modelRow)) {
                             LOGGER.info("Showing tournament table " + matchesModel.getTableId(modelRow));
-                            session.watchTable(roomId, matchesModel.getTableId(modelRow));
+                            SessionHandler.watchTable(roomId, matchesModel.getTableId(modelRow));
                         }
                         break;
                 }
@@ -439,18 +438,18 @@ public class TablesPanel extends javax.swing.JPanel {
     }
 
     public void startTasks() {
-        if (session != null) {
+        if (SessionHandler.getSession() != null) {
             if (updateTablesTask == null || updateTablesTask.isDone()) {
-                updateTablesTask = new UpdateTablesTask(session, roomId, this);
+                updateTablesTask = new UpdateTablesTask(roomId, this);
                 updateTablesTask.execute();
             }
             if (updatePlayersTask == null || updatePlayersTask.isDone()) {
-                updatePlayersTask = new UpdatePlayersTask(session, roomId, this.chatPanelMain);
+                updatePlayersTask = new UpdatePlayersTask(roomId, this.chatPanelMain);
                 updatePlayersTask.execute();
             }
             if (this.btnStateFinished.isSelected()) {
                 if (updateMatchesTask == null || updateMatchesTask.isDone()) {
-                    updateMatchesTask = new UpdateMatchesTask(session, roomId, this);
+                    updateMatchesTask = new UpdateMatchesTask(roomId, this);
                     updateMatchesTask.execute();
                 }
             } else if (updateMatchesTask != null) {
@@ -473,12 +472,11 @@ public class TablesPanel extends javax.swing.JPanel {
 
     public void showTables(UUID roomId) {
         this.roomId = roomId;
-        session = MageFrame.getSession();
         UUID chatRoomId = null;
-        if (session != null) {
-            btnQuickStart.setVisible(session.isTestMode());
-            gameChooser.init(session);
-            chatRoomId = session.getRoomChatId(roomId);
+        if (SessionHandler.getSession() != null) {
+            btnQuickStart.setVisible(SessionHandler.isTestMode());
+            gameChooser.init();
+            chatRoomId = SessionHandler.getRoomChatId(roomId);
         }
         if (newTableDialog == null) {
             newTableDialog = new NewTableDialog();
@@ -500,7 +498,7 @@ public class TablesPanel extends javax.swing.JPanel {
         } else {
             hideTables();
         }
-        tableModel.setSession(session);
+        //tableModel.setSession(session);
 
         reloadMessages();
 
@@ -518,7 +516,7 @@ public class TablesPanel extends javax.swing.JPanel {
 
     protected void reloadMessages() {
         // reload server messages
-        List<String> serverMessages = session.getServerMessages();
+        List<String> serverMessages = SessionHandler.getServerMessages();
         synchronized (this) {
             this.messages = serverMessages;
             this.currentMessage = 0;
@@ -1286,11 +1284,11 @@ public class TablesPanel extends javax.swing.JPanel {
             options.setSkillLevel(SkillLevel.CASUAL);
             options.setRollbackTurnsAllowed(true);
             options.setQuitRatio(100);
-            table = session.createTable(roomId, options);
+            table = SessionHandler.createTable(roomId, options);
 
-            session.joinTable(roomId, table.getTableId(), "Human", "Human", 1, DeckImporterUtil.importDeck("test.dck"), "");
-            session.joinTable(roomId, table.getTableId(), "Computer", "Computer - mad", 5, DeckImporterUtil.importDeck("test.dck"), "");
-            session.startMatch(roomId, table.getTableId());
+            SessionHandler.joinTable(roomId, table.getTableId(), "Human", "Human", 1, DeckImporterUtil.importDeck("test.dck"), "");
+            SessionHandler.joinTable(roomId, table.getTableId(), "Computer", "Computer - mad", 5, DeckImporterUtil.importDeck("test.dck"), "");
+            SessionHandler.startMatch(roomId, table.getTableId());
         } catch (HeadlessException ex) {
             handleError(ex);
         }
@@ -1404,7 +1402,6 @@ class TableTableModel extends AbstractTableModel {
     private static final DateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss");
     ;
 
-    private Session session;
 
     public void loadData(Collection<TableView> tables) throws MageRemoteException {
         this.tables = tables.toArray(new TableView[0]);
@@ -1421,9 +1418,6 @@ class TableTableModel extends AbstractTableModel {
         return columnNames.length;
     }
 
-    public void setSession(Session session) {
-        this.session = session;
-    }
 
     @Override
     public Object getValueAt(int arg0, int arg1) {
@@ -1455,7 +1449,7 @@ class TableTableModel extends AbstractTableModel {
 
                     case WAITING:
                         String owner = tables[arg0].getControllerName();
-                        if (session != null && owner.equals(session.getUserName())) {
+                        if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
                             return "";
                         }
                         return "Join";
@@ -1469,7 +1463,7 @@ class TableTableModel extends AbstractTableModel {
                             return "Show";
                         } else {
                             owner = tables[arg0].getControllerName();
-                            if (session != null && owner.equals(session.getUserName())) {
+                            if (SessionHandler.getSession() != null && owner.equals(SessionHandler.getUserName())) {
                                 return "";
                             }
                             return "Watch";
@@ -1522,7 +1516,6 @@ class TableTableModel extends AbstractTableModel {
 
 class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
 
-    private final Session session;
     private final UUID roomId;
     private final TablesPanel panel;
 
@@ -1530,8 +1523,8 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
 
     private int count = 0;
 
-    UpdateTablesTask(Session session, UUID roomId, TablesPanel panel) {
-        this.session = session;
+    UpdateTablesTask(UUID roomId, TablesPanel panel) {
+
         this.roomId = roomId;
         this.panel = panel;
     }
@@ -1539,7 +1532,7 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
     @Override
     protected Void doInBackground() throws Exception {
         while (!isCancelled()) {
-            Collection<TableView> tables = session.getTables(roomId);
+            Collection<TableView> tables = SessionHandler.getTables(roomId);
             if (tables != null) {
                 this.publish(tables);
             }
@@ -1572,14 +1565,13 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
 
 class UpdatePlayersTask extends SwingWorker<Void, Collection<RoomUsersView>> {
 
-    private final Session session;
     private final UUID roomId;
     private final PlayersChatPanel chat;
 
     private static final Logger logger = Logger.getLogger(UpdatePlayersTask.class);
 
-    UpdatePlayersTask(Session session, UUID roomId, PlayersChatPanel chat) {
-        this.session = session;
+    UpdatePlayersTask( UUID roomId, PlayersChatPanel chat) {
+
         this.roomId = roomId;
         this.chat = chat;
     }
@@ -1587,7 +1579,7 @@ class UpdatePlayersTask extends SwingWorker<Void, Collection<RoomUsersView>> {
     @Override
     protected Void doInBackground() throws Exception {
         while (!isCancelled()) {
-            this.publish(session.getRoomUsers(roomId));
+            this.publish(SessionHandler.getRoomUsers(roomId));
             Thread.sleep(3000);
         }
         return null;
@@ -1713,14 +1705,12 @@ class MatchesTableModel extends AbstractTableModel {
 
 class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
 
-    private final Session session;
     private final UUID roomId;
     private final TablesPanel panel;
 
     private static final Logger logger = Logger.getLogger(UpdateTablesTask.class);
 
-    UpdateMatchesTask(Session session, UUID roomId, TablesPanel panel) {
-        this.session = session;
+    UpdateMatchesTask(UUID roomId, TablesPanel panel) {
         this.roomId = roomId;
         this.panel = panel;
     }
@@ -1728,7 +1718,7 @@ class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
     @Override
     protected Void doInBackground() throws Exception {
         while (!isCancelled()) {
-            Collection<MatchView> matches = session.getFinishedMatches(roomId);
+            Collection<MatchView> matches = SessionHandler.getFinishedMatches(roomId);
             if (matches != null) {
                 this.publish(matches);
             }
@@ -1756,10 +1746,9 @@ class UpdateMatchesTask extends SwingWorker<Void, Collection<MatchView>> {
 
 class GameChooser extends JPopupMenu {
 
-    private Session session;
 
-    public void init(Session session) {
-        this.session = session;
+    public void init() {
+
     }
 
     public void show(List<UUID> games, Point p) {
@@ -1785,7 +1774,7 @@ class GameChooser extends JPopupMenu {
 
         @Override
         public void actionPerformed(ActionEvent e) {
-            session.replayGame(id);
+            SessionHandler.replayGame(id);
             setVisible(false);
         }
 
diff --git a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java
index 295c360b98..a32c3b5851 100644
--- a/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java
+++ b/Mage.Client/src/main/java/mage/client/table/TournamentPlayerPanel.java
@@ -39,6 +39,7 @@ import javax.swing.DefaultComboBoxModel;
 import javax.swing.JComboBox;
 import mage.cards.decks.DeckCardLists;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.remote.Session;
 
 /**
@@ -47,7 +48,6 @@ import mage.remote.Session;
  */
 public class TournamentPlayerPanel extends javax.swing.JPanel {
 
-    private Session session;
 
     /** Creates new form TournamentPlayerPanel */
     public TournamentPlayerPanel() {
@@ -56,8 +56,7 @@ public class TournamentPlayerPanel extends javax.swing.JPanel {
     }
 
     public void init(int playerNum) {
-        session = MageFrame.getSession();
-        cbPlayerType.setModel(new DefaultComboBoxModel(session.getPlayerTypes()));
+        cbPlayerType.setModel(new DefaultComboBoxModel(SessionHandler.getPlayerTypes()));
         this.lblPlayerNum.setText("Player " + playerNum);
     }
 
@@ -67,7 +66,7 @@ public class TournamentPlayerPanel extends javax.swing.JPanel {
 
     public boolean joinTournamentTable(UUID roomId, UUID tableId, DeckCardLists deckCardLists) {
         if (!this.cbPlayerType.getSelectedItem().equals("Human")) {
-            return session.joinTournamentTable(
+            return SessionHandler.joinTournamentTable(
                     roomId,
                     tableId,
                     this.txtPlayerName.getText(),
diff --git a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java
index 713933b496..01ed13a76a 100644
--- a/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java
+++ b/Mage.Client/src/main/java/mage/client/tournament/TournamentPanel.java
@@ -49,6 +49,7 @@ import javax.swing.Icon;
 import javax.swing.SwingWorker;
 import javax.swing.table.AbstractTableModel;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.chat.ChatPanelBasic;
 import mage.client.dialog.PreferencesDialog;
 import static mage.client.dialog.PreferencesDialog.KEY_TOURNAMENT_MATCH_COLUMNS_ORDER;
@@ -61,7 +62,6 @@ import mage.client.util.GUISizeHelper;
 import mage.client.util.gui.TableUtil;
 import mage.client.util.gui.countryBox.CountryCellRenderer;
 import mage.constants.PlayerAction;
-import mage.remote.Session;
 import mage.view.RoundView;
 import mage.view.TournamentGameView;
 import mage.view.TournamentPlayerView;
@@ -82,7 +82,7 @@ public class TournamentPanel extends javax.swing.JPanel {
 
     private UUID tournamentId;
     private boolean firstInitDone = false;
-    private Session session;
+
     private final TournamentPlayersTableModel playersModel;
     private TournamentMatchesTableModel matchesModel;
     private UpdateTournamentTask updateTask;
@@ -129,7 +129,7 @@ public class TournamentPanel extends javax.swing.JPanel {
 //                }
                 if (state.startsWith("Dueling") && actionText.equals("Watch")) {
                     LOGGER.info("Watching game " + gameId);
-                    session.watchTournamentTable(tableId);
+                    SessionHandler.watchTournamentTable(tableId);
                 }
             }
         };
@@ -201,10 +201,9 @@ public class TournamentPanel extends javax.swing.JPanel {
 
     public synchronized void showTournament(UUID tournamentId) {
         this.tournamentId = tournamentId;
-        session = MageFrame.getSession();
         // MageFrame.addTournament(tournamentId, this);
-        UUID chatRoomId = session.getTournamentChatId(tournamentId);
-        if (session.joinTournament(tournamentId) && chatRoomId != null) {
+        UUID chatRoomId = SessionHandler.getTournamentChatId(tournamentId);
+        if (SessionHandler.joinTournament(tournamentId) && chatRoomId != null) {
             this.chatPanel1.connect(chatRoomId);
             startTasks();
             this.setVisible(true);
@@ -292,7 +291,7 @@ public class TournamentPanel extends javax.swing.JPanel {
         btnQuitTournament.setVisible(false);
         if (tournament.getEndTime() == null) {
             for (TournamentPlayerView player : tournament.getPlayers()) {
-                if (player.getName().equals(session.getUserName())) {
+                if (player.getName().equals(SessionHandler.getUserName())) {
                     if (!player.hasQuit()) {
                         btnQuitTournament.setVisible(true);
                     }
@@ -304,9 +303,9 @@ public class TournamentPanel extends javax.swing.JPanel {
     }
 
     public void startTasks() {
-        if (session != null) {
+        if (SessionHandler.getSession() != null) {
             if (updateTask == null || updateTask.isDone()) {
-                updateTask = new UpdateTournamentTask(session, tournamentId, this);
+                updateTask = new UpdateTournamentTask(tournamentId, this);
                 updateTask.execute();
             }
         }
@@ -725,14 +724,13 @@ class TournamentMatchesTableModel extends AbstractTableModel {
 
 class UpdateTournamentTask extends SwingWorker<Void, TournamentView> {
 
-    private final Session session;
     private final UUID tournamentId;
     private final TournamentPanel panel;
 
     private static final Logger logger = Logger.getLogger(UpdateTournamentTask.class);
 
-    UpdateTournamentTask(Session session, UUID tournamentId, TournamentPanel panel) {
-        this.session = session;
+    UpdateTournamentTask(UUID tournamentId, TournamentPanel panel) {
+
         this.tournamentId = tournamentId;
         this.panel = panel;
     }
@@ -740,7 +738,7 @@ class UpdateTournamentTask extends SwingWorker<Void, TournamentView> {
     @Override
     protected Void doInBackground() throws Exception {
         while (!isCancelled()) {
-            this.publish(session.getTournament(tournamentId));
+            this.publish(SessionHandler.getTournament(tournamentId));
             Thread.sleep(2000);
         }
         return null;
diff --git a/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java b/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java
index 4028cb4048..2b46f47ea0 100644
--- a/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java
+++ b/Mage.Client/src/main/java/mage/client/unusedFiles/PlayerPanel.java
@@ -37,6 +37,7 @@ package mage.client.unusedFiles;
 import java.awt.Color;
 import java.util.UUID;
 import mage.client.MageFrame;
+import mage.client.SessionHandler;
 import mage.client.cards.BigCard;
 import mage.client.dialog.ShowCardsDialog;
 import mage.remote.Session;
@@ -50,7 +51,6 @@ public class PlayerPanel extends javax.swing.JPanel {
 
     private UUID playerId;
     private UUID gameId;
-    private Session session;
     private PlayerView player;
 
     private ShowCardsDialog graveyard;
@@ -67,7 +67,6 @@ public class PlayerPanel extends javax.swing.JPanel {
         this.gameId = gameId;
         this.playerId = playerId;
         this.bigCard = bigCard;
-        session = MageFrame.getSession();
     }
 
     public void update(PlayerView player) {
@@ -192,7 +191,7 @@ public class PlayerPanel extends javax.swing.JPanel {
     }// </editor-fold>//GEN-END:initComponents
 
     private void btnPlayerNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayerNameActionPerformed
-        session.sendPlayerUUID(gameId, playerId);
+        SessionHandler.sendPlayerUUID(gameId, playerId);
     }//GEN-LAST:event_btnPlayerNameActionPerformed
 
     private void btnGraveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGraveActionPerformed
diff --git a/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java b/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java
index 08d36e7ee4..9723a4b8c7 100644
--- a/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java
+++ b/Mage.Client/src/main/java/mage/client/util/DefaultActionCallback.java
@@ -3,6 +3,7 @@ package mage.client.util;
 import java.awt.event.MouseEvent;
 import java.util.UUID;
 
+import mage.client.SessionHandler;
 import mage.remote.Session;
 import mage.view.CardView;
 
@@ -17,12 +18,12 @@ public class DefaultActionCallback {
         return INSTANCE;
     }
 
-    public void mouseClicked(MouseEvent e, UUID gameId, Session session, CardView card) {
+    public void mouseClicked(MouseEvent e, UUID gameId,  CardView card) {
         if (gameId != null) {
             if (card.isAbility() && card.getAbility() != null) {
-                session.sendPlayerUUID(gameId, card.getAbility().getId());
+                SessionHandler.sendPlayerUUID(gameId, card.getAbility().getId());
             } else {
-                session.sendPlayerUUID(gameId, card.getId());
+                SessionHandler.sendPlayerUUID(gameId, card.getId());
             }
         }
     }