Index: src/net/sf/freecol/common/model/FreeColGameObject.java
===================================================================
--- src/net/sf/freecol/common/model/FreeColGameObject.java	(revision 9928)
+++ src/net/sf/freecol/common/model/FreeColGameObject.java	(working copy)
@@ -32,7 +32,6 @@
 
 import net.sf.freecol.common.util.Introspector;
 import net.sf.freecol.common.util.Utils;
-import net.sf.freecol.server.model.ServerGame;
 
 import org.w3c.dom.Element;
 
Index: src/net/sf/freecol/common/networking/ServerAPI.java
===================================================================
--- src/net/sf/freecol/common/networking/ServerAPI.java	(revision 9927)
+++ src/net/sf/freecol/common/networking/ServerAPI.java	(working copy)
@@ -30,7 +30,7 @@
 
 import javax.xml.stream.XMLStreamException;
 
-import net.sf.freecol.client.FreeColClient;
+
 import net.sf.freecol.common.debug.FreeColDebugger;
 import net.sf.freecol.common.model.AbstractUnit;
 import net.sf.freecol.common.model.BuildableType;
@@ -59,18 +59,17 @@
 import net.sf.freecol.common.model.WorkLocation;
 
 import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 
 /**
  * The API for client->server messaging.
  */
-public class ServerAPI {
+public abstract class ServerAPI {
 
     private static final Logger logger = Logger.getLogger(ServerAPI.class.getName());
 
-    private FreeColClient freeColClient; // cached client reference
+    private NetworkClient networkClient;
 
 
     /**
@@ -79,8 +78,8 @@
      * @param freeColClient The <code>FreeColClient</code> that is
      *     communicating with a server.
      */
-    public ServerAPI(FreeColClient freeColClient) {
-        this.freeColClient = freeColClient;
+    public ServerAPI(NetworkClient networkClient) {
+        this.networkClient = networkClient;
     }
 
 
@@ -120,7 +119,7 @@
      * @return True if the send succeeded.
      */
     private boolean send(DOMMessage message) {
-        freeColClient.getClient().send(message.toXMLElement());
+        networkClient.send(message.toXMLElement());
         return true;
     }
 
@@ -149,7 +148,7 @@
         Element request = message.toXMLElement();
         Element reply;
         try {
-            reply = freeColClient.getClient().getConnection()
+            reply = networkClient.getConnection()
                 .askDumping(request);
         } catch (IOException e) {
             logger.log(Level.WARNING, "Could not send \""
@@ -175,60 +174,15 @@
                                + ((messageId != null) ? messageId : "")
                                + "/" + ((messageText != null)
                                    ? messageText : ""));
-                handleReply(reply);
+                networkClient.handleReply(reply);
             }
             return null;
         }
 
-        // Success!
-        if (tag == null || tag.equals(reply.getTagName())) {
-            // Do the standard processing.
-            String sound = reply.getAttribute("sound");
-            if (sound != null && !sound.isEmpty()) {
-                freeColClient.getGUI().playSound(sound);
-            }
-            // Look for special attributes
-            if (results != null) {
-                if (results.containsKey("*")) {
-                    results.remove("*");
-                    int len = reply.getAttributes().getLength();
-                    for (int i = 0; i < len; i++) {
-                        Node n = reply.getAttributes().item(i);
-                        results.put(n.getNodeName(), n.getNodeValue());
-                    }
-                } else {
-                    for (String k : results.keySet()) {
-                        if (reply.hasAttribute(k)) {
-                            results.put(k, reply.getAttribute(k));
-                        }
-                    }
-                }
-            }
-            return reply;
-        }
-
-        // Unexpected reply.  Whine and fail.
-        String complaint = "Received reply with tag " + reply.getTagName()
-            + " which should have been " + tag
-            + " to message " + message;
-        logger.warning(complaint);
-        if (FreeColDebugger.isInDebugMode()) {
-            freeColClient.getGUI().errorMessage(null, complaint);
-        }
-        return null;
+        return handleSuccessfulReply(message.toString(), tag, results, reply);
     }
 
-    /**
-     * Handle a reply element using the client input handler.
-     *
-     * @param reply The reply <code>Element</code> to handle.
-     */
-    private void handleReply(Element reply) {
-        if (reply != null) {
-            freeColClient.getInGameInputHandler()
-                .handle(freeColClient.getClient().getConnection(), reply);
-        }
-    }
+    protected abstract Element handleSuccessfulReply(String message, String tag, HashMap<String, String> results, Element reply);
 
     /**
      * Extends askExpecting to also handle returns from the server.
@@ -243,7 +197,7 @@
         Element reply = askExpecting(message, tag, results);
         if (reply == null) return false;
 
-        handleReply(reply);
+        networkClient.handleReply(reply);
         return true;
     }
 
@@ -489,8 +443,8 @@
      * @param chat The text of the message.
      * @return True if the send succeeded.
      */
-    public boolean chat(String chat) {
-        return send(new ChatMessage(freeColClient.getMyPlayer(), chat, false));
+    public boolean chat(Player player, String chat) {
+        return send(new ChatMessage(player, chat, false));
     }
 
     /**
@@ -554,17 +508,16 @@
      * @param agreement The <code>DiplomaticTrade</code> agreement to propose.
      * @return The resulting agreement or null if none present.
      */
-    public DiplomaticTrade diplomacy(Unit unit, Settlement settlement,
+    public DiplomaticTrade diplomacy(Game game, Unit unit, Settlement settlement,
                                      DiplomaticTrade agreement) {
         Element reply = askExpecting(new DiplomacyMessage(unit, settlement,
                                                           agreement),
             null, null);
         if (reply == null) return null;
         if (DiplomacyMessage.getXMLElementTagName().equals(reply.getTagName())) {
-            Game game = freeColClient.getGame();
             return new DiplomacyMessage(game, reply).getAgreement();
         }
-        handleReply(reply);
+        networkClient.handleReply(reply);
         return null;
     }
 
@@ -711,7 +664,7 @@
      * @return The goods for sale in the settlement,
      *     or null if the server interaction failed.
      */
-    public List<Goods> getGoodsForSaleInSettlement(Unit unit,
+    public List<Goods> getGoodsForSaleInSettlement(Game game, Unit unit,
                                                    Settlement settlement) {
         GoodsForSaleMessage message
             = new GoodsForSaleMessage(unit, settlement, null);
@@ -719,7 +672,6 @@
             GoodsForSaleMessage.getXMLElementTagName(), null);
         if (reply == null) return null;
 
-        Game game = freeColClient.getGame();
         List<Goods> goodsOffered = new ArrayList<Goods>();
         NodeList childNodes = reply.getChildNodes();
         for (int i = 0; i < childNodes.getLength(); i++) {
Index: src/net/sf/freecol/common/networking/NetworkClient.java
===================================================================
--- src/net/sf/freecol/common/networking/NetworkClient.java	(revision 0)
+++ src/net/sf/freecol/common/networking/NetworkClient.java	(revision 0)
@@ -0,0 +1,81 @@
+package net.sf.freecol.common.networking;
+
+
+import org.w3c.dom.Element;
+
+public interface NetworkClient {
+
+    /**
+     * Gets the host used by the connection.
+     * Used in reconnect.
+     *
+     * @return The host.
+     */
+    public abstract String getHost();
+
+    /**
+     * Gets the port used by the connection.
+     * Used in reconnect.
+     *
+     * @return The port.
+     */
+    public abstract int getPort();
+
+    /**
+     * Gets the <code>Connection</code> this <code>Client</code> uses when
+     * communicating with the server.
+     *
+     * @return The {@link Connection}.
+     */
+    public abstract Connection getConnection();
+
+    /**
+     * Sets the <code>MessageHandler</code> for this <code>Client</code>.
+     * The <code>MessageHandler</code> is the class responsible for receiving
+     * and handling the network messages.
+     *
+     * @param mh The new <code>MessageHandler</code> for this client.
+     */
+    public abstract void setMessageHandler(MessageHandler mh);
+
+    /**
+     * Disconnects this client from the server.
+     */
+    public abstract void disconnect();
+
+    /**
+     * Sends the specified message to the server.
+     *
+     * @param element The element (root element in a DOM-parsed XML tree) that
+     *                holds all the information
+     * @see #sendAndWait(Element)
+     * @see #ask(Element)
+     */
+    public abstract void send(Element element);
+
+    /**
+     * Sends the specified message to the server and waits for the reply
+     * to be returned before returning from this method.
+     *
+     * @param element The element (root element in a DOM-parsed XML tree) that
+     *                holds all the information
+     * @see #send(Element)
+     * @see #ask(Element)
+     */
+    public abstract void sendAndWait(Element element);
+
+    /**
+     * Sends the specified message to the server and returns the reply.
+     *
+     * @param element The element (root element in a DOM-parsed XML tree)
+     *       that holds all the information
+     * @return The answer from the server or <code>null</code> if either
+     *       an error occured or the server did not send a reply.
+     * @see #sendAndWait
+     * @see #send
+     */
+    public abstract Element ask(Element element);
+
+    public abstract void handleReply(Element reply);
+
+}
\ No newline at end of file
Index: src/net/sf/freecol/client/control/InGameController.java
===================================================================
--- src/net/sf/freecol/client/control/InGameController.java	(revision 9929)
+++ src/net/sf/freecol/client/control/InGameController.java	(working copy)
@@ -2957,12 +2957,12 @@
                 agreement = ourAgreement;
             }
             if (agreement.getStatus() != TradeStatus.PROPOSE_TRADE) {
-                askServer().diplomacy(unit, settlement, agreement);
+                askServer().diplomacy(freeColClient.getGame(), unit, settlement, agreement);
                 gui.updateMenuBar();
                 break;
             }
 
-            agreement = askServer().diplomacy(unit, settlement, agreement);
+            agreement = askServer().diplomacy(freeColClient.getGame(), unit, settlement, agreement);
             status = (agreement == null) ? TradeStatus.REJECT_TRADE
                 : agreement.getStatus();
             switch (status) {
@@ -3086,7 +3086,7 @@
 
         // Get list of goods for sale
         List<Goods> forSale
-            = askServer().getGoodsForSaleInSettlement(unit, settlement);
+            = askServer().getGoodsForSaleInSettlement(freeColClient.getGame(), unit, settlement);
         for (;;) {
             if (forSale.isEmpty()) {
                 // There is nothing to sell to the player
@@ -3593,7 +3593,7 @@
      * @param chat The text of the message.
      */
     public void sendChat(String chat) {
-        askServer().chat(chat);
+        askServer().chat(freeColClient.getMyPlayer(), chat);
     }
 
     /**
Index: src/net/sf/freecol/client/control/ConnectController.java
===================================================================
--- src/net/sf/freecol/client/control/ConnectController.java	(revision 9929)
+++ src/net/sf/freecol/client/control/ConnectController.java	(working copy)
@@ -55,6 +55,7 @@
 import net.sf.freecol.common.networking.Connection;
 import net.sf.freecol.common.networking.DOMMessage;
 import net.sf.freecol.common.networking.LoginMessage;
+import net.sf.freecol.common.networking.NetworkClient;
 import net.sf.freecol.common.networking.NoRouteToServerException;
 import net.sf.freecol.common.option.OptionGroup;
 import net.sf.freecol.common.resources.ResourceManager;
@@ -266,9 +267,9 @@
      * @throws ConnectException
      * @throws IOException
      */
-    private Client connectClient(String threadName, String host, int port)
+    private NetworkClient connectClient(String threadName, String host, int port)
         throws ConnectException, IOException {
-        Client client = null;
+        NetworkClient client = null;
         int tries;
         if (port < 0) {
             port = FreeCol.getDefaultPort();
@@ -304,7 +305,7 @@
     public boolean login(String userName, String host, int port) {
         freeColClient.setMapEditor(false);
 
-        Client client = freeColClient.getClient();
+        NetworkClient client = freeColClient.getClient();
         if (client != null) client.disconnect();
 
         try {
Index: src/net/sf/freecol/client/networking/ClientServerAPI.java
===================================================================
--- src/net/sf/freecol/client/networking/ClientServerAPI.java	(revision 0)
+++ src/net/sf/freecol/client/networking/ClientServerAPI.java	(revision 0)
@@ -0,0 +1,71 @@
+package net.sf.freecol.client.networking;
+
+import java.util.HashMap;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import net.sf.freecol.client.FreeColClient;
+import net.sf.freecol.common.debug.FreeColDebugger;
+import net.sf.freecol.common.networking.NetworkClient;
+import net.sf.freecol.common.networking.ServerAPI;
+
+public class ClientServerAPI extends ServerAPI {
+
+    public static final String COPYRIGHT = "Copyright (C) 2003-2012 The FreeCol Team";
+
+    public static final String LICENSE = "http://www.gnu.org/licenses/gpl.html";
+
+    public static final String REVISION = "$Revision: 2763 $";
+
+    private static final Logger logger = Logger.getLogger(ClientServerAPI.class.getName());
+
+    private FreeColClient freeColClient;
+
+    public ClientServerAPI(FreeColClient freeColClient, NetworkClient networkClient) {
+        super(networkClient);
+        this.freeColClient = freeColClient;
+    }
+
+    @Override
+    protected Element handleSuccessfulReply(String message, String tag, HashMap<String, String> results, Element reply) {
+        // Success!
+        if (tag == null || tag.equals(reply.getTagName())) {
+            // Do the standard processing.
+            String sound = reply.getAttribute("sound");
+            if (sound != null && !sound.isEmpty()) {
+                freeColClient.getGUI().playSound(sound);
+            }
+            // Look for special attributes
+            if (results != null) {
+                if (results.containsKey("*")) {
+                    results.remove("*");
+                    int len = reply.getAttributes().getLength();
+                    for (int i = 0; i < len; i++) {
+                        Node n = reply.getAttributes().item(i);
+                        results.put(n.getNodeName(), n.getNodeValue());
+                    }
+                } else {
+                    for (String k : results.keySet()) {
+                        if (reply.hasAttribute(k)) {
+                            results.put(k, reply.getAttribute(k));
+                        }
+                    }
+                }
+            }
+            return reply;
+        }
+
+        // Unexpected reply.  Whine and fail.
+        String complaint = "Received reply with tag " + reply.getTagName()
+            + " which should have been " + tag
+            + " to message " + message;
+        logger.warning(complaint);
+        if (FreeColDebugger.isInDebugMode()) {
+            freeColClient.getGUI().errorMessage(null, complaint);
+        }
+        return null;
+    }
+
+}
Index: src/net/sf/freecol/client/networking/Client.java
===================================================================
--- src/net/sf/freecol/client/networking/Client.java	(revision 9927)
+++ src/net/sf/freecol/client/networking/Client.java	(working copy)
@@ -24,8 +24,10 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import net.sf.freecol.common.FreeColException;
 import net.sf.freecol.common.networking.Connection;
 import net.sf.freecol.common.networking.MessageHandler;
+import net.sf.freecol.common.networking.NetworkClient;
 
 import org.w3c.dom.Element;
 
@@ -33,7 +35,7 @@
 /**
  * The client connection to a server.
  */
-public final class Client {
+public final class Client implements NetworkClient {
     private static final Logger logger = Logger.getLogger(Client.class.getName());
 
     /**
@@ -69,6 +71,7 @@
      *
      * @return The host.
      */
+    @Override
     public String getHost() {
         return host;
     }
@@ -79,6 +82,7 @@
      *
      * @return The port.
      */
+    @Override
     public int getPort() {
         return port;
     }
@@ -89,6 +93,7 @@
      *
      * @return The {@link Connection}.
      */
+    @Override
     public Connection getConnection() {
         return c;
     }
@@ -100,6 +105,7 @@
      *
      * @param mh The new <code>MessageHandler</code> for this client.
      */
+    @Override
     public void setMessageHandler(MessageHandler mh) {
         c.setMessageHandler(mh);
     }
@@ -107,6 +113,7 @@
     /**
      * Disconnects this client from the server.
      */
+    @Override
     public void disconnect() {
         c.close();
     }
@@ -120,6 +127,7 @@
      * @see #sendAndWait(Element)
      * @see #ask(Element)
      */
+    @Override
     public void send(Element element) {
         try {
             c.sendDumping(element);
@@ -137,6 +145,7 @@
      * @see #send(Element)
      * @see #ask(Element)
      */
+    @Override
     public void sendAndWait(Element element) {
         try {
             c.sendAndWait(element);
@@ -155,6 +164,7 @@
      * @see #sendAndWait
      * @see #send
      */
+    @Override
     public Element ask(Element element) {
         try {
             return c.askDumping(element);
@@ -163,4 +173,22 @@
         }
         return null;
     }
+    
+
+    /**
+     * Handle a reply element using the client input handler.
+     *
+     * @param reply The reply <code>Element</code> to handle.
+     */
+    public void handleReply(Element reply) {
+        if (reply != null) {
+            try {
+                getConnection().getMessageHandler().handle(c, reply);
+            } catch (FreeColException e) {
+                logger.log(Level.WARNING, "Could not handle reply: " + reply, e);
+            }
+        }
+    }
+
+    
 }
Index: src/net/sf/freecol/client/FreeColClient.java
===================================================================
--- src/net/sf/freecol/client/FreeColClient.java	(revision 9929)
+++ src/net/sf/freecol/client/FreeColClient.java	(working copy)
@@ -40,7 +40,7 @@
 import net.sf.freecol.client.gui.GUI;
 import net.sf.freecol.client.gui.action.ActionManager;
 import net.sf.freecol.client.gui.plaf.FreeColLookAndFeel;
-import net.sf.freecol.client.networking.Client;
+import net.sf.freecol.client.networking.ClientServerAPI;
 import net.sf.freecol.common.FreeColException;
 import net.sf.freecol.common.FreeColSeed;
 import net.sf.freecol.common.io.FreeColDataFile;
@@ -52,6 +52,7 @@
 import net.sf.freecol.common.model.Player;
 import net.sf.freecol.common.model.Specification;
 import net.sf.freecol.common.networking.DOMMessage;
+import net.sf.freecol.common.networking.NetworkClient;
 import net.sf.freecol.common.networking.ServerAPI;
 import net.sf.freecol.common.resources.ResourceManager;
 import net.sf.freecol.common.resources.ResourceMapping;
@@ -91,7 +92,7 @@
      * The network <code>Client</code> that can be used to send messages to
      * the server.
      */
-    private Client client;
+    private NetworkClient client;
 
     // Model:
     private Game game;
@@ -270,7 +271,7 @@
      * @return A ServerAPI.
      */
     public ServerAPI askServer() {
-        if (serverAPI == null) serverAPI = new ServerAPI(this);
+        if (serverAPI == null) serverAPI = new ClientServerAPI(this, client);
         return serverAPI;
     }
 
@@ -330,7 +331,7 @@
      * @return the <code>Client</code>
      * @see #setClient
      */
-    public Client getClient() {
+    public NetworkClient getClient() {
         return client;
     }
 
@@ -550,7 +551,7 @@
      * @param client The <code>Client</code>.
      * @see #getClient
      */
-    public void setClient(Client client) {
+    public void setClient(NetworkClient client) {
         this.client = client;
     }
 
