Index: /applications/editors/josm/plugins/geochat/src/geochat/ChatPaneManager.java
===================================================================
--- /applications/editors/josm/plugins/geochat/src/geochat/ChatPaneManager.java	(revision 29575)
+++ /applications/editors/josm/plugins/geochat/src/geochat/ChatPaneManager.java	(revision 29576)
@@ -1,4 +1,5 @@
 package geochat;
 
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Font;
@@ -72,5 +73,10 @@
     }
 
-    private void addLineToChatPane( String userName, String line, boolean italic ) {
+    public static int MESSAGE_TYPE_DEFAULT = 0;
+    public static int MESSAGE_TYPE_INFORMATION = 1;
+    public static int MESSAGE_TYPE_ATTENTION = 2;
+    private static Color COLOR_ATTENTION = new Color(0, 0, 192);
+
+    private void addLineToChatPane( String userName, String line, int messageType ) {
         if( line.length() == 0 )
             return;
@@ -82,7 +88,10 @@
         try {
             SimpleAttributeSet attrs = null;
-            if( italic ) {
+            if( messageType != MESSAGE_TYPE_DEFAULT ) {
                 attrs = new SimpleAttributeSet();
-                StyleConstants.setItalic(attrs, true);
+                if( messageType == MESSAGE_TYPE_INFORMATION )
+                    StyleConstants.setItalic(attrs, true);
+                else if( messageType == MESSAGE_TYPE_ATTENTION )
+                    StyleConstants.setForeground(attrs, COLOR_ATTENTION);
             }
             doc.insertString(doc.getLength(), line, attrs);
@@ -94,5 +103,5 @@
 
     public void addLineToChatPane( String userName, String line ) {
-        addLineToChatPane(userName, line, false);
+        addLineToChatPane(userName, line, MESSAGE_TYPE_DEFAULT);
     }
 
@@ -101,19 +110,10 @@
     }
 
+    public void addLineToPublic( String line, int messageType ) {
+        addLineToChatPane(PUBLIC_PANE, line, messageType);
+    }
+
     public void clearPublicChatPane() {
         chatPanes.get(PUBLIC_PANE).pane.setText("");
-        showNearbyUsers();
-    }
-
-    private void showNearbyUsers() {
-        if( !panel.users.isEmpty() ) {
-            StringBuilder sb = new StringBuilder(tr("Users mapping nearby:"));
-            boolean first = true;
-            for( String user : panel.users.keySet() ) {
-                sb.append(first ? " " : ", ");
-                sb.append(user);
-            }
-            addLineToPublic(sb.toString());
-        }
     }
 
@@ -192,4 +192,19 @@
     }
     
+    public boolean hasSelectedText() {
+        String user = getActiveChatPane();
+        if( user != null ) {
+            JTextPane pane = chatPanes.get(user).pane;
+            return pane.getSelectedText() != null;
+        }
+        return false;
+    }
+
+    public void copySelectedText() {
+        String user = getActiveChatPane();
+        if( user != null )
+            chatPanes.get(user).pane.copy();
+    }
+    
 
     private class ChatTabTitleComponent extends JLabel {
Index: /applications/editors/josm/plugins/geochat/src/geochat/ChatServerConnection.java
===================================================================
--- /applications/editors/josm/plugins/geochat/src/geochat/ChatServerConnection.java	(revision 29575)
+++ /applications/editors/josm/plugins/geochat/src/geochat/ChatServerConnection.java	(revision 29576)
@@ -1,8 +1,8 @@
 package geochat;
 
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.*;
-import javax.swing.SwingUtilities;
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -143,4 +143,13 @@
     }
 
+    /**
+     * Unregister the current user and do not call listeners.
+     * Makes synchronous request to the server.
+     */
+    public void bruteLogout() throws IOException {
+        if( isLoggedIn() )
+            JsonQueryUtil.query("logout&uid=" + userId);
+    }
+
     private void fireMessageFailed( String reason ) {
         for( ChatServerConnectionListener listener : listeners )
@@ -248,4 +257,5 @@
 
         public void run() {
+//            lastId = Main.pref.getLong("geochat.lastid", 0);
             int interval = Main.pref.getInteger("geochat.interval", 2);
             while( !stopping ) {
@@ -281,4 +291,5 @@
                 // reset messages
                 lastId = 0;
+//                Main.pref.put("geochat.lastid", null);
                 needReset = true;
             } else
@@ -322,4 +333,6 @@
                         }
                     }
+//                    if( lastId > 0 && Main.pref.getBoolean("geochat.store.lastid", true) )
+//                        Main.pref.putLong("geochat.lastid", lastId);
                 }
             });
Index: /applications/editors/josm/plugins/geochat/src/geochat/GeoChatPanel.java
===================================================================
--- /applications/editors/josm/plugins/geochat/src/geochat/GeoChatPanel.java	(revision 29575)
+++ /applications/editors/josm/plugins/geochat/src/geochat/GeoChatPanel.java	(revision 29576)
@@ -52,6 +52,6 @@
 
             @Override
-            protected String autoComplete( String word ) {
-                return autoCompleteUser(word);
+            protected String autoComplete( String word, boolean atStart ) {
+                return autoCompleteUser(word, atStart);
             }
         };
@@ -103,6 +103,20 @@
     }
 
-    private String autoCompleteUser( String word ) {
+    @Override
+    public void destroy() {
+        try {
+            if( Main.pref.getBoolean("geochat.logout.on.close", true) ) {
+                connection.removeListener(this);
+                connection.bruteLogout();
+            }
+        } catch( Throwable e ) {
+            Main.warn("Failed to logout from geochat server: " + e.getMessage());
+        }
+        super.destroy();
+    }
+
+    private String autoCompleteUser( String word, boolean atStart ) {
         String result = null;
+        boolean singleUser = true;
         for( String user : users.keySet() ) {
             if( user.startsWith(word) ) {
@@ -110,4 +124,5 @@
                     result = user;
                 else {
+                    singleUser = false;
                     int i = word.length();
                     while( i < result.length() && i < user.length() && result.charAt(i) == user.charAt(i) )
@@ -118,5 +133,5 @@
             }
         }
-        return result;
+        return result == null ? null : !singleUser ? result : atStart ? result + ": " : result + " ";
     }
 
@@ -159,8 +174,8 @@
         if( !isDialogInCollapsedView() && alarmLevel > 1 )
             alarmLevel = 1;
-        String name = users.isEmpty() ? tr("GeoChat") :
+        String title = users.isEmpty() ? tr("GeoChat") :
                 trn("GeoChat ({0} user)", "GeoChat ({0} users)", users.size(), users.size());
         String alarm = alarmLevel <= 0 ? "" : alarmLevel == 1 ? "* " : "!!! ";
-        setTitle(alarm + name);
+        setTitle(alarm + title);
     }
 
@@ -218,9 +233,9 @@
         for( String uname : this.users.keySet() ) {
             if( !newUsers.containsKey(uname) )
-                chatPanes.addLineToPublic(tr("User {0} has left", uname));
+                chatPanes.addLineToPublic(tr("User {0} has left", uname), ChatPaneManager.MESSAGE_TYPE_INFORMATION);
         }
         for( String uname : newUsers.keySet() ) {
             if( !this.users.containsKey(uname) )
-                chatPanes.addLineToPublic(tr("User {0} is mapping nearby", uname));
+                chatPanes.addLineToPublic(tr("User {0} is mapping nearby", uname), ChatPaneManager.MESSAGE_TYPE_INFORMATION);
         }
         this.users = newUsers;
@@ -254,5 +269,5 @@
                     sb.setLength(0);
                     formatMessage(sb, msg);
-                    chatPanes.addLineToPublicEm(sb.toString());
+                    chatPanes.addLineToPublic(sb.toString(), ChatPaneManager.MESSAGE_TYPE_ATTENTION);
                     sb.setLength(0);
                 } else
@@ -262,4 +277,18 @@
             if( alarm > 0 )
                 chatPanes.notify(null, alarm);
+        }
+        if( replace )
+            showNearbyUsers();
+    }
+
+    private void showNearbyUsers() {
+        if( !users.isEmpty() ) {
+            StringBuilder sb = new StringBuilder(tr("Users mapping nearby:"));
+            boolean first = true;
+            for( String user : users.keySet() ) {
+                sb.append(first ? " " : ", ");
+                sb.append(user);
+            }
+            chatPanes.addLineToPublic(sb.toString(), ChatPaneManager.MESSAGE_TYPE_INFORMATION);
         }
     }
Index: /applications/editors/josm/plugins/geochat/src/geochat/GeoChatPopupAdapter.java
===================================================================
--- /applications/editors/josm/plugins/geochat/src/geochat/GeoChatPopupAdapter.java	(revision 29575)
+++ /applications/editors/josm/plugins/geochat/src/geochat/GeoChatPopupAdapter.java	(revision 29576)
@@ -43,4 +43,6 @@
 
         JPopupMenu menu = new JPopupMenu();
+        if( panel.chatPanes.hasSelectedText() )
+            menu.add(new CopyTextAction());
         menu.add(new JCheckBoxMenuItem(new ToggleUserLayerAction()));
         if( userMenu.getItemCount() > 0 )
@@ -49,5 +51,5 @@
             menu.add(new CloseTabAction());
 //        menu.add(new ClearPaneAction());
-//        menu.add(new LogoutAction());
+        menu.add(new LogoutAction());
         return menu;
     }
@@ -118,3 +120,14 @@
         }
     }
+
+    private class CopyTextAction extends AbstractAction {
+        public CopyTextAction() {
+            super(tr("Copy"));
+//            putValue(SMALL_ICON, ImageProvider.get("help"));
+        }
+
+        public void actionPerformed( ActionEvent e ) {
+            panel.chatPanes.copySelectedText();
+        }
+    }
 }
Index: /applications/editors/josm/plugins/geochat/src/geochat/JPanelTextField.java
===================================================================
--- /applications/editors/josm/plugins/geochat/src/geochat/JPanelTextField.java	(revision 29575)
+++ /applications/editors/josm/plugins/geochat/src/geochat/JPanelTextField.java	(revision 29576)
@@ -37,8 +37,7 @@
                     start--;
                 start++;
-                System.out.println("Autocomplete! Word " + start + "-" + caret + " (not inclusive)");
                 if( start < caret ) {
                     String word = text.substring(start, caret);
-                    String complete = word == null ? null : autoComplete(word);
+                    String complete = word == null ? null : autoComplete(word, start == 0);
                     if( complete != null && !complete.equals(word) ) {
                         StringBuilder sb = new StringBuilder();
@@ -75,5 +74,5 @@
      * @return The whole word.
      */
-    protected String autoComplete( String word ) {
+    protected String autoComplete( String word, boolean atStart ) {
         return word;
     }
