Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java	(revision 6020)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java	(revision 6021)
@@ -2,19 +2,12 @@
 package org.openstreetmap.josm.gui.preferences.advanced;
 
-import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Color;
-import java.awt.Component;
 import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -22,8 +15,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
+import javax.swing.AbstractAction;
 
 import javax.swing.Box;
-import javax.swing.ButtonGroup;
-import javax.swing.DefaultCellEditor;
 import javax.swing.JButton;
 import javax.swing.JFileChooser;
@@ -31,12 +23,9 @@
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
-import javax.swing.JRadioButton;
+import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
-import javax.swing.JTable;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
 import javax.swing.filechooser.FileFilter;
-import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.DefaultTableModel;
 
 import org.openstreetmap.josm.Main;
@@ -44,10 +33,5 @@
 import org.openstreetmap.josm.data.CustomConfigurator;
 import org.openstreetmap.josm.data.Preferences;
-import org.openstreetmap.josm.data.Preferences.ListListSetting;
-import org.openstreetmap.josm.data.Preferences.ListSetting;
-import org.openstreetmap.josm.data.Preferences.MapListSetting;
 import org.openstreetmap.josm.data.Preferences.Setting;
-import org.openstreetmap.josm.data.Preferences.StringSetting;
-import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.actionsupport.LogShowDialog;
 import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
@@ -55,12 +39,13 @@
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
 import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.Utils;
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 public class AdvancedPreference extends DefaultTabPreferenceSetting {
 
     public static class Factory implements PreferenceSettingFactory {
+        @Override
         public PreferenceSetting createPreferenceSetting() {
             return new AdvancedPreference();
@@ -77,73 +62,10 @@
     }
 
-    public static class PrefEntry implements Comparable<PrefEntry> {
-        private String key;
-        private Setting value;
-        private Setting defaultValue;
-        private boolean isDefault;
-        private boolean changed;
-
-        public PrefEntry(String key, Setting value, Setting defaultValue, boolean isDefault) {
-            CheckParameterUtil.ensureParameterNotNull(key);
-            CheckParameterUtil.ensureParameterNotNull(value);
-            CheckParameterUtil.ensureParameterNotNull(defaultValue);
-            this.key = key;
-            this.value = value;
-            this.defaultValue = defaultValue;
-            this.isDefault = isDefault;
-        }
-
-        public String getKey() {
-            return key;
-        }
-
-        public Setting getValue() {
-            return value;
-        }
-
-        public Setting getDefaultValue() {
-            return defaultValue;
-        }
-
-        public void setValue(Setting value) {
-            this.value = value;
-            changed = true;
-            isDefault = false;
-        }
-
-        public boolean isDefault() {
-            return isDefault;
-        }
-
-        public boolean isChanged() {
-            return changed;
-        }
-    
-        private void markAsChanged() {
-            changed = true;
-        }
-    
-        public void reset() {
-            value = defaultValue;
-            changed = true;
-            isDefault = true;
-        }
-
-        @Override
-        public int compareTo(PrefEntry other) {
-            return key.compareTo(other.key);
-        }
-
-        @Override
-        public String toString() {
-            return value.toString();
-        }
-    }
-
-    private AllSettingsTableModel model;
-    protected List<PrefEntry> data;
-    protected List<PrefEntry> displayData;
+    protected List<PrefEntry> allData;
+    protected List<PrefEntry> displayData = new ArrayList<PrefEntry>();
     protected JosmTextField txtFilter;
-
+    protected PreferencesTable table;
+
+    @Override
     public void addGui(final PreferenceTabbedPane gui) {
         JPanel p = gui.createPreferenceTab(this);
@@ -169,13 +91,8 @@
         });
         readPreferences(Main.pref);
-        model = new AllSettingsTableModel();
+        
         applyFilter();
-
-        final JTable list = new JTable(model);
-        list.putClientProperty("terminateEditOnFocusLost", true);
-        list.getColumnModel().getColumn(1).setCellRenderer(new SettingCellRenderer());
-        list.getColumnModel().getColumn(1).setCellEditor(new SettingCellEditor());
-
-        JScrollPane scroll = new JScrollPane(list);
+        table = new PreferencesTable(displayData);
+        JScrollPane scroll = new JScrollPane(table);
         p.add(scroll, GBC.eol().fill(GBC.BOTH));
         scroll.setPreferredSize(new Dimension(400,200));
@@ -185,6 +102,11 @@
         p.add(add, GBC.std().insets(0,5,0,0));
         add.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                addPreference(gui);
+            @Override public void actionPerformed(ActionEvent e) {
+                PrefEntry pe = table.addPreference(gui);
+                if (pe!=null) {
+                    allData.add(pe);
+                    Collections.sort(allData);
+                    applyFilter();
+                }
             }
         });
@@ -193,6 +115,7 @@
         p.add(edit, GBC.std().insets(5,5,5,0));
         edit.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                editPreference(gui, list);
+            @Override public void actionPerformed(ActionEvent e) {
+                boolean ok = table.editPreference(gui);
+                if (ok) applyFilter();
             }
         });
@@ -201,6 +124,6 @@
         p.add(reset, GBC.std().insets(0,5,0,0));
         reset.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                resetPreference(gui, list);
+            @Override public void actionPerformed(ActionEvent e) {
+                table.resetPreferences(gui);
             }
         });
@@ -209,44 +132,7 @@
         p.add(read, GBC.std().insets(5,5,0,0));
         read.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                File[] files = askUserForCustomSettingsFiles(false, tr("Open JOSM customization file"));
-                if (files.length==0) return;
-                
-                Preferences tmpPrefs = CustomConfigurator.clonePreferences(Main.pref);
-                
-                StringBuilder log = new StringBuilder();
-                log.append("<html>");
-                for (File f: files) {
-                    CustomConfigurator.readXML(f, tmpPrefs);
-                    log.append(CustomConfigurator.getLog());
-                }
-                //try { Main.pref.save();  } catch (IOException ex) { }
-                log.append("</html>");
-                String msg = log.toString().replace("\n", "<br/>");
-                
-                new LogShowDialog(tr("Import log"), tr("<html>Here is file import summary. <br/>"
-                        + "You can reject preferences changes by pressing \"Cancel\" in preferences dialog <br/>"
-                        + "To activate some changes JOSM restart may be needed.</html>"), msg).showDialog();
-                
-                //JOptionPane.showMessageDialog(Main.parent,
-                //   tr("Installed plugins and some changes in preferences will start to work after JOSM restart"), tr("Warning"), JOptionPane.WARNING_MESSAGE);
-
-                readPreferences(tmpPrefs);
-                // sorting after modification - first modified, then non-default, then default entries
-                Collections.sort(data, new Comparator<PrefEntry>() {
-                    @Override
-                    public int compare(PrefEntry o1, PrefEntry o2) {
-                        if (o1.changed && !o2.changed) return -1;
-                        if (o2.changed && !o1.changed) return 1;
-                        if (!(o1.isDefault) && o2.isDefault) return -1;
-                        if (!(o2.isDefault) && o1.isDefault) return 1;
-                        return o1.key.compareTo(o2.key);
-                    }
-                  });
-
-                applyFilter();
-                ((AllSettingsTableModel) list.getModel()).fireTableDataChanged();
-            }
-
+            @Override public void actionPerformed(ActionEvent e) {
+                readPreferencesFromXML();
+            }
         });
         
@@ -254,41 +140,15 @@
         p.add(export, GBC.std().insets(5,5,0,0));
         export.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                ArrayList<String> keys = new ArrayList<String>();
-                boolean hasLists = false;
-                for (int row : list.getSelectedRows()) {
-                    PrefEntry p = (PrefEntry) model.getValueAt(row, -1);
-                    if (!p.isDefault()) {
-                        // preferences with default values are not saved
-                        if (!(p.getValue() instanceof StringSetting)) hasLists=true; // => append and replace differs
-                        keys.add(p.getKey());
-                    }
-                }
-                if (keys.size()==0) {
-                     JOptionPane.showMessageDialog(Main.parent,
-                        tr("Please select some preference keys not marked as default"), tr("Warning"), JOptionPane.WARNING_MESSAGE);
-                     return;
-                }
-
-                File[] files = askUserForCustomSettingsFiles(true, tr("Export preferences keys to JOSM customization file"));
-                if (files.length==0) return;
-                
-                int answer = 0;
-                if (hasLists) {
-                    answer = JOptionPane.showOptionDialog(
-                            Main.parent, tr("What to do with preference lists when this file is to be imported?"), tr("Question"),
-                            JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
-                            new String[]{tr("Append preferences from file to existing values"), tr("Replace existing values")}, 0);
-                }
-                CustomConfigurator.exportPreferencesKeysToFile(files[0].getAbsolutePath(), answer==0, keys);
-            }
-        });
-
-
-        list.addMouseListener(new MouseAdapter(){
-            @Override public void mouseClicked(MouseEvent e) {
-                if (e.getClickCount() == 2) {
-                    editPreference(gui, list);
-                }
+            @Override public void actionPerformed(ActionEvent e) {
+                exportSelectedToXML();
+            }
+        });
+        
+        final JButton more = new JButton(tr("More..."));
+        p.add(more, GBC.std().insets(5,5,0,0));
+        more.addActionListener(new ActionListener() {
+            JPopupMenu menu = buildPopupMenu();
+            @Override public void actionPerformed(ActionEvent ev) {
+                menu.show(more, 0, 0);
             }
         });
@@ -312,5 +172,5 @@
             loaded = orig;
         }
-        prepareData(loaded, orig, defaults);
+        allData = prepareData(loaded, orig, defaults);
     }
     
@@ -334,7 +194,80 @@
         return new File[0];
     }
-            
-    private void prepareData(Map<String, Setting> loaded, Map<String, Setting> orig, Map<String, Setting> defaults) {
-        data = new ArrayList<PrefEntry>();
+ 
+    private void exportSelectedToXML() {
+        ArrayList<String> keys = new ArrayList<String>();
+        boolean hasLists = false;
+        
+        for (PrefEntry p: table.getSelectedItems()) {
+            // preferences with default values are not saved
+            if (!(p.getValue() instanceof Preferences.StringSetting)) {
+                hasLists = true; // => append and replace differs
+            }
+            if (!p.isDefault()) {
+                keys.add(p.getKey());
+            }
+        }
+        
+        if (keys.isEmpty()) {
+            JOptionPane.showMessageDialog(Main.parent,
+                    tr("Please select some preference keys not marked as default"), tr("Warning"), JOptionPane.WARNING_MESSAGE);
+            return;
+        }
+
+        File[] files = askUserForCustomSettingsFiles(true, tr("Export preferences keys to JOSM customization file"));
+        if (files.length == 0) {
+            return;
+        }
+
+        int answer = 0;
+        if (hasLists) {
+            answer = JOptionPane.showOptionDialog(
+                    Main.parent, tr("What to do with preference lists when this file is to be imported?"), tr("Question"),
+                    JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
+                    new String[]{tr("Append preferences from file to existing values"), tr("Replace existing values")}, 0);
+        }
+        CustomConfigurator.exportPreferencesKeysToFile(files[0].getAbsolutePath(), answer == 0, keys);
+    }
+    
+    private void readPreferencesFromXML() {
+        File[] files = askUserForCustomSettingsFiles(false, tr("Open JOSM customization file"));
+        if (files.length == 0) return;
+
+        Preferences tmpPrefs = CustomConfigurator.clonePreferences(Main.pref);
+
+        StringBuilder log = new StringBuilder();
+        log.append("<html>");
+        for (File f : files) {
+            CustomConfigurator.readXML(f, tmpPrefs);
+            log.append(CustomConfigurator.getLog());
+        }
+        //try { Main.pref.save();  } catch (IOException ex) { }
+        log.append("</html>");
+        String msg = log.toString().replace("\n", "<br/>");
+
+        new LogShowDialog(tr("Import log"), tr("<html>Here is file import summary. <br/>"
+                + "You can reject preferences changes by pressing \"Cancel\" in preferences dialog <br/>"
+                + "To activate some changes JOSM restart may be needed.</html>"), msg).showDialog();
+
+        //JOptionPane.showMessageDialog(Main.parent,
+        //   tr("Installed plugins and some changes in preferences will start to work after JOSM restart"), tr("Warning"), JOptionPane.WARNING_MESSAGE);
+
+        readPreferences(tmpPrefs);
+        // sorting after modification - first modified, then non-default, then default entries
+        Collections.sort(allData, new Comparator<PrefEntry>() {
+            @Override
+            public int compare(PrefEntry o1, PrefEntry o2) {
+                if (o1.isChanged() && !o2.isChanged()) return -1;
+                if (o2.isChanged() && !o1.isChanged()) return 1;
+                if (!(o1.isDefault()) && o2.isDefault()) return -1;
+                if (!(o2.isDefault()) && o1.isDefault()) return 1;
+                return o1.compareTo(o2);
+            }
+        });
+        applyFilter();
+    }
+                
+    private List<PrefEntry> prepareData(Map<String, Setting> loaded, Map<String, Setting> orig, Map<String, Setting> defaults) {
+        List<PrefEntry> data = new ArrayList<PrefEntry>();
         for (Entry<String, Setting> e : loaded.entrySet()) {
             Setting value = e.getValue();
@@ -363,110 +296,32 @@
         }
         Collections.sort(data);
-        displayData = new ArrayList<PrefEntry>(data);
-    }
-
-    class AllSettingsTableModel extends DefaultTableModel {
-
-        public AllSettingsTableModel() {
-            setColumnIdentifiers(new String[]{tr("Key"), tr("Value")});
-        }
-
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            return column == 1 && (displayData.get(row).getValue() instanceof StringSetting);
-        }
-
-        @Override
-        public int getRowCount() {
-            return displayData.size();
-        }
-
-        @Override
-        public Object getValueAt(int row, int column) {
-            if (column == 0)
-                return displayData.get(row).getKey();
-            else
-                return displayData.get(row);
-        }
-
-        @Override
-        public void setValueAt(Object o, int row, int column) {
-            PrefEntry pe = displayData.get(row);
-            String s = (String) o;
-            if (!s.equals(pe.getValue().getValue())) {
-                pe.setValue(new StringSetting(s));
-                fireTableCellUpdated(row, column);
-            }
-        }
-    }
-
-    private static class SettingCellRenderer extends DefaultTableCellRenderer {
-        private Color backgroundColor = Main.pref.getUIColor("Table.background");
-        private Color changedColor = Main.pref.getColor(
-                         marktr("Advanced Background: Changed"),
-                         new Color(200,255,200));
-        private Color foregroundColor = Main.pref.getUIColor("Table.foreground");
-        private Color nonDefaultColor = Main.pref.getColor(
-                            marktr("Advanced Background: NonDefalut"),
-                            new Color(255,255,200));
-        
-        @Override
-        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
-            if (value == null)
-                return this;
-            PrefEntry pe = (PrefEntry) value;
-            Setting setting = pe.getValue();
-            Object val = setting.getValue();
-            String display = val != null ? val.toString() : "<html><i>&lt;"+tr("unset")+"&gt;</i></html>";
-            
-            JLabel label = (JLabel)super.getTableCellRendererComponent(table,
-                    display, isSelected, hasFocus, row, column);
-
-            label.setBackground(backgroundColor);
-            if (isSelected) {
-                label.setForeground(foregroundColor);
-            }
-            if(pe.isChanged()) {
-                label.setBackground(changedColor);
-            } else if(!pe.isDefault()) {
-                label.setBackground(nonDefaultColor);
-            }
-
-            if (!pe.isDefault()) {
-                label.setFont(label.getFont().deriveFont(Font.BOLD));
-            }
-            val = pe.getDefaultValue().getValue();
-            if(val != null)
-            {
-                if(pe.isDefault()) {
-                    label.setToolTipText(tr("Current value is default."));
-                } else {
-                    label.setToolTipText(tr("Default value is ''{0}''.", val));
+        displayData.clear();
+        displayData.addAll(data);
+        return data;
+    }
+    
+    private JPopupMenu buildPopupMenu() {
+        JPopupMenu menu = new JPopupMenu();
+        menu.add(new AbstractAction(tr("Reset preferences")) {
+            @Override public void actionPerformed(ActionEvent ae) {
+                if (!GuiHelper.warnUser(tr("Reset preferences"),
+                        "<html>"+
+                        tr("You are about to clear all preferences to their default values<br />"+
+                        "All your settings will be deleted: plugins, imagery, filters, toolbar buttons, keyboard, etc. <br />"+
+                        "Are you sure you want to continue?")
+                        +"</html>", null, "")) {
+                    Main.pref.resetToDefault();
+                    try { Main.pref.save(); } catch (IOException ex) {}
+                    readPreferences(Main.pref);
+                    applyFilter();
                 }
-            } else {
-                label.setToolTipText(tr("Default value currently unknown (setting has not been used yet)."));
-            }
-            return label;
-        }
-    }
-
-    private static class SettingCellEditor extends DefaultCellEditor {
-        public SettingCellEditor() {
-            super(new JosmTextField());
-        }
-
-        @Override
-        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
-            PrefEntry pe = (PrefEntry) value;
-            StringSetting stg = (StringSetting) pe.getValue();
-            String s = stg.getValue() == null ? "" : stg.getValue();
-            return super.getTableCellEditorComponent(table, s, isSelected, row, column);
-        }
+            }
+        });
+        return menu;
     }
 
     private void applyFilter() {
         displayData.clear();
-        for (PrefEntry e : data) {
-
+        for (PrefEntry e : allData) {
             String prefKey = e.getKey();
             Setting valueSetting = e.getValue();
@@ -490,10 +345,11 @@
             }
         }
-        model.fireTableDataChanged();
+        System.out.println(displayData.size())  ;
+        if (table!=null) table.fireDataChanged();
     }
 
     @Override
     public boolean ok() {
-        for (PrefEntry e : data) {
+        for (PrefEntry e : allData) {
             if (e.isChanged()) {
                 Main.pref.putSetting(e.getKey(), e.getValue());
@@ -502,168 +358,3 @@
         return false;
     }
-
-    private void resetPreference(final PreferenceTabbedPane gui, final JTable list) {
-        if (list.getSelectedRowCount() == 0) {
-            JOptionPane.showMessageDialog(
-                    gui,
-                    tr("Please select the row to delete."),
-                    tr("Warning"),
-                    JOptionPane.WARNING_MESSAGE
-                    );
-            return;
-        }
-        for (int row : list.getSelectedRows()) {
-            PrefEntry e = displayData.get(row);
-            e.reset();
-        }
-        model.fireTableDataChanged();
-    }
-
-    private void addPreference(final PreferenceTabbedPane gui) {
-        JPanel p = new JPanel(new GridBagLayout());
-        p.add(new JLabel(tr("Key")), GBC.std().insets(0,0,5,0));
-        JosmTextField tkey = new JosmTextField("", 50);
-        p.add(tkey, GBC.eop().insets(5,0,0,0).fill(GBC.HORIZONTAL));
-
-        p.add(new JLabel(tr("Select Setting Type:")), GBC.eol().insets(5,15,5,0));
-
-        JRadioButton rbString = new JRadioButton(tr("Simple"));
-        JRadioButton rbList = new JRadioButton(tr("List"));
-        JRadioButton rbListList = new JRadioButton(tr("List of lists"));
-        JRadioButton rbMapList = new JRadioButton(tr("List of maps"));
-
-        ButtonGroup group = new ButtonGroup();
-        group.add(rbString);
-        group.add(rbList);
-        group.add(rbListList);
-        group.add(rbMapList);
-
-        p.add(rbString, GBC.eol());
-        p.add(rbList, GBC.eol());
-        p.add(rbListList, GBC.eol());
-        p.add(rbMapList, GBC.eol());
-
-        rbString.setSelected(true);
-
-        ExtendedDialog dlg = new ExtendedDialog(gui, tr("Add setting"), new String[] {tr("OK"), tr("Cancel")});
-        dlg.setButtonIcons(new String[] {"ok.png", "cancel.png"});
-        dlg.setContent(p);
-        dlg.showDialog();
-
-        PrefEntry pe = null;
-        boolean ok = false;
-        if (dlg.getValue() == 1) {
-            if (rbString.isSelected()) {
-                StringSetting sSetting = new StringSetting(null);
-                pe = new PrefEntry(tkey.getText(), sSetting, sSetting, false);
-                StringEditor sEditor = new StringEditor(gui, pe, sSetting);
-                sEditor.showDialog();
-                if (sEditor.getValue() == 1) {
-                    String data = sEditor.getData();
-                    if (!Utils.equal(sSetting.getValue(), data)) {
-                        pe.setValue(new StringSetting(data));
-                        ok = true;
-                    }
-                }
-            } else if (rbList.isSelected()) {
-                ListSetting lSetting = new ListSetting(null);
-                pe = new PrefEntry(tkey.getText(), lSetting, lSetting, false);
-                ListEditor lEditor = new ListEditor(gui, pe, lSetting);
-                lEditor.showDialog();
-                if (lEditor.getValue() == 1) {
-                    List<String> data = lEditor.getData();
-                    if (!Preferences.equalCollection(lSetting.getValue(), data)) {
-                        pe.setValue(new ListSetting(data));
-                        ok = true;
-                    }
-                }
-            } else if (rbListList.isSelected()) {
-                ListListSetting llSetting = new ListListSetting(null);
-                pe = new PrefEntry(tkey.getText(), llSetting, llSetting, false);
-                ListListEditor llEditor = new ListListEditor(gui, pe, llSetting);
-                llEditor.showDialog();
-                if (llEditor.getValue() == 1) {
-                    List<List<String>> data = llEditor.getData();
-                    @SuppressWarnings("unchecked")
-                    Collection<Collection<String>> llSettingValue = (Collection) llSetting.getValue();
-                    if (!Preferences.equalArray(llSettingValue, data)) {
-                        pe.setValue(new ListListSetting(data));
-                        ok = true;
-                    }
-                }
-            } else if (rbMapList.isSelected()) {
-                MapListSetting mlSetting = new MapListSetting(null);
-                pe = new PrefEntry(tkey.getText(), mlSetting, mlSetting, false);
-                MapListEditor mlEditor = new MapListEditor(gui, pe, mlSetting);
-                mlEditor.showDialog();
-                if (mlEditor.getValue() == 1) {
-                    List<Map<String, String>> data = mlEditor.getData();
-                    if (!Preferences.equalListOfStructs(mlSetting.getValue(), data)) {
-                        pe.setValue(new MapListSetting(data));
-                        ok = true;
-                    }
-                }
-            }
-            if (ok) {
-                data.add(pe);
-                Collections.sort(data);
-                applyFilter();
-            }
-        }
-    }
-
-    private void editPreference(final PreferenceTabbedPane gui, final JTable list) {
-        if (list.getSelectedRowCount() != 1) {
-            JOptionPane.showMessageDialog(
-                    gui,
-                    tr("Please select the row to edit."),
-                    tr("Warning"),
-                    JOptionPane.WARNING_MESSAGE
-                    );
-            return;
-        }
-        final PrefEntry e = (PrefEntry) model.getValueAt(list.getSelectedRow(), 1);
-        Setting stg = e.getValue();
-        if (stg instanceof StringSetting) {
-            list.editCellAt(list.getSelectedRow(), 1);
-            Component editor = list.getEditorComponent();
-            if (editor != null) {
-                editor.requestFocus();
-            }
-        } else if (stg instanceof ListSetting) {
-            ListSetting lSetting = (ListSetting) stg;
-            ListEditor lEditor = new ListEditor(gui, e, lSetting);
-            lEditor.showDialog();
-            if (lEditor.getValue() == 1) {
-                List<String> data = lEditor.getData();
-                if (!Preferences.equalCollection(lSetting.getValue(), data)) {
-                    e.setValue(new ListSetting(data));
-                    applyFilter();
-                }
-            }
-        } else if (stg instanceof ListListSetting) {
-            ListListEditor llEditor = new ListListEditor(gui, e, (ListListSetting) stg);
-            llEditor.showDialog();
-            if (llEditor.getValue() == 1) {
-                List<List<String>> data = llEditor.getData();
-                @SuppressWarnings("unchecked")
-                Collection<Collection<String>> stgValue = (Collection) stg.getValue();
-                if (!Preferences.equalArray(stgValue, data)) {
-                    e.setValue(new ListListSetting(data));
-                    applyFilter();
-                }
-            }
-        } else if (stg instanceof MapListSetting) {
-            MapListSetting mlSetting = (MapListSetting) stg;
-            MapListEditor mlEditor = new MapListEditor(gui, e, mlSetting);
-            mlEditor.showDialog();
-            if (mlEditor.getValue() == 1) {
-                List<Map<String, String>> data = mlEditor.getData();
-                if (!Preferences.equalListOfStructs(mlSetting.getValue(), data)) {
-                    e.setValue(new MapListSetting(data));
-                    applyFilter();
-                }
-            }
-        }
-    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/ListEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/ListEditor.java	(revision 6020)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/ListEditor.java	(revision 6021)
@@ -10,4 +10,5 @@
 
 import javax.swing.DefaultCellEditor;
+import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
@@ -18,6 +19,4 @@
 import org.openstreetmap.josm.data.Preferences.ListSetting;
 import org.openstreetmap.josm.gui.ExtendedDialog;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.gui.preferences.advanced.AdvancedPreference.PrefEntry;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
@@ -29,5 +28,5 @@
     PrefEntry entry;
 
-    public ListEditor(final PreferenceTabbedPane gui, PrefEntry entry, ListSetting setting) {
+    public ListEditor(final JComponent gui, PrefEntry entry, ListSetting setting) {
         super(gui, tr("Change list setting"), new String[] {tr("OK"), tr("Cancel")});
         this.entry = entry;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/ListListEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/ListListEditor.java	(revision 6020)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/ListListEditor.java	(revision 6021)
@@ -14,4 +14,5 @@
 import javax.swing.AbstractListModel;
 import javax.swing.DefaultCellEditor;
+import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JList;
@@ -27,6 +28,4 @@
 import org.openstreetmap.josm.data.Preferences.ListListSetting;
 import org.openstreetmap.josm.gui.ExtendedDialog;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.gui.preferences.advanced.AdvancedPreference.PrefEntry;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
@@ -46,5 +45,5 @@
     ListTableModel tableModel;
 
-    public ListListEditor(final PreferenceTabbedPane gui, PrefEntry entry, ListListSetting setting) {
+    public ListListEditor(final JComponent gui, PrefEntry entry, ListListSetting setting) {
         super(gui, tr("Change list of lists setting"), new String[] {tr("OK"), tr("Cancel")});
         this.entry = entry;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/MapListEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/MapListEditor.java	(revision 6020)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/MapListEditor.java	(revision 6021)
@@ -18,4 +18,5 @@
 import javax.swing.AbstractListModel;
 import javax.swing.DefaultCellEditor;
+import javax.swing.JComponent;
 import javax.swing.JLabel;
 import javax.swing.JList;
@@ -31,6 +32,4 @@
 import org.openstreetmap.josm.data.Preferences.MapListSetting;
 import org.openstreetmap.josm.gui.ExtendedDialog;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.gui.preferences.advanced.AdvancedPreference.PrefEntry;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
@@ -51,5 +50,5 @@
     Integer entryIdx;
 
-    public MapListEditor(PreferenceTabbedPane gui, PrefEntry entry, MapListSetting setting) {
+    public MapListEditor(JComponent gui, PrefEntry entry, MapListSetting setting) {
         super(gui, tr("Change list of maps setting"), new String[] {tr("OK"), tr("Cancel")});
         this.entry = entry;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PrefEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PrefEntry.java	(revision 6021)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PrefEntry.java	(revision 6021)
@@ -0,0 +1,72 @@
+package org.openstreetmap.josm.gui.preferences.advanced;
+
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
+
+/**
+ * Class to store single preference line for the table
+ * @since 6021 : extracted from AdvancedPreference class 
+ */
+public class PrefEntry implements Comparable<PrefEntry> {
+    private String key;
+    private Preferences.Setting value;
+    private Preferences.Setting defaultValue;
+    private boolean isDefault;
+    private boolean changed;
+
+    public PrefEntry(String key, Preferences.Setting value, Preferences.Setting defaultValue, boolean isDefault) {
+        CheckParameterUtil.ensureParameterNotNull(key);
+        CheckParameterUtil.ensureParameterNotNull(value);
+        CheckParameterUtil.ensureParameterNotNull(defaultValue);
+        this.key = key;
+        this.value = value;
+        this.defaultValue = defaultValue;
+        this.isDefault = isDefault;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public Preferences.Setting getValue() {
+        return value;
+    }
+
+    public Preferences.Setting getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setValue(Preferences.Setting value) {
+        this.value = value;
+        changed = true;
+        isDefault = false;
+    }
+
+    public boolean isDefault() {
+        return isDefault;
+    }
+
+    public boolean isChanged() {
+        return changed;
+    }
+
+    public void markAsChanged() {
+        changed = true;
+    }
+
+    public void reset() {
+        value = defaultValue;
+        changed = true;
+        isDefault = true;
+    }
+
+    @Override
+    public int compareTo(PrefEntry other) {
+        return key.compareTo(other.key);
+    }
+
+    @Override
+    public String toString() {
+        return value.toString();
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PreferencesTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PreferencesTable.java	(revision 6021)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/PreferencesTable.java	(revision 6021)
@@ -0,0 +1,355 @@
+package org.openstreetmap.josm.gui.preferences.advanced;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.GridBagLayout;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import javax.swing.ButtonGroup;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.widgets.JosmTextField;
+import org.openstreetmap.josm.tools.GBC;
+import static org.openstreetmap.josm.tools.I18n.marktr;
+import static org.openstreetmap.josm.tools.I18n.tr;
+import org.openstreetmap.josm.tools.Utils;
+
+/**
+ * Component for editing list of preferences as a table
+ * @since 6021 : extracted from AdvancedPreference class 
+ */
+public class PreferencesTable extends JTable {
+    private AllSettingsTableModel model;
+    private final List<PrefEntry> displayData;
+
+    public PreferencesTable(List<PrefEntry> displayData) {
+        this.displayData = displayData;
+        model = new AllSettingsTableModel();
+        setModel(model);
+        putClientProperty("terminateEditOnFocusLost", true);
+        getColumnModel().getColumn(1).setCellRenderer(new SettingCellRenderer());
+        getColumnModel().getColumn(1).setCellEditor(new SettingCellEditor());
+        
+        addMouseListener(new MouseAdapter(){
+            @Override public void mouseClicked(MouseEvent e) {
+                if (e.getClickCount() == 2) {
+                    editPreference(PreferencesTable.this);
+                }
+            }
+        });
+    }
+    
+    /**
+     * This method should be called when displayed data was changed form external code
+     */
+    public void fireDataChanged() {
+        model.fireTableDataChanged();
+    }
+    
+    
+    /**
+     * The list of currently selected rows
+     * @return newly created list of PrefEntry
+     */
+    public List<PrefEntry> getSelectedItems() {
+        List<PrefEntry> entries = new ArrayList<PrefEntry>();
+        for (int row : getSelectedRows()) {
+            PrefEntry p = (PrefEntry) model.getValueAt(row, -1);
+            entries.add(p);
+        }
+        return entries;
+    }
+    
+    /**
+     * Call this to edit selected row in preferences table
+     * @param gui - parent component for messagebox
+     * @return true if editing was actually performed during this call
+     */
+    public boolean editPreference(final JComponent gui) {
+        if (getSelectedRowCount() != 1) {
+            JOptionPane.showMessageDialog(
+                    gui,
+                    tr("Please select the row to edit."),
+                    tr("Warning"),
+                    JOptionPane.WARNING_MESSAGE
+                    );
+            return false;
+        }
+        final PrefEntry e = (PrefEntry) model.getValueAt(getSelectedRow(), 1);
+        Preferences.Setting stg = e.getValue();
+        if (stg instanceof Preferences.StringSetting) {
+            editCellAt(getSelectedRow(), 1);
+            Component editor = getEditorComponent();
+            if (editor != null) {
+                editor.requestFocus();
+            }
+        } else if (stg instanceof Preferences.ListSetting) {
+            Preferences.ListSetting lSetting = (Preferences.ListSetting) stg;
+            ListEditor lEditor = new ListEditor(gui, e, lSetting);
+            lEditor.showDialog();
+            if (lEditor.getValue() == 1) {
+                List<String> data = lEditor.getData();
+                if (!Preferences.equalCollection(lSetting.getValue(), data)) {
+                    e.setValue(new Preferences.ListSetting(data));
+                    return true;
+                }
+            }
+        } else if (stg instanceof Preferences.ListListSetting) {
+            ListListEditor llEditor = new ListListEditor(gui, e, (Preferences.ListListSetting) stg);
+            llEditor.showDialog();
+            if (llEditor.getValue() == 1) {
+                List<List<String>> data = llEditor.getData();
+                @SuppressWarnings("unchecked")
+                Collection<Collection<String>> stgValue = (Collection) stg.getValue();
+                if (!Preferences.equalArray(stgValue, data)) {
+                    e.setValue(new Preferences.ListListSetting(data));
+                    return true;
+                }
+            }
+        } else if (stg instanceof Preferences.MapListSetting) {
+            Preferences.MapListSetting mlSetting = (Preferences.MapListSetting) stg;
+            MapListEditor mlEditor = new MapListEditor(gui, e, mlSetting);
+            mlEditor.showDialog();
+            if (mlEditor.getValue() == 1) {
+                List<Map<String, String>> data = mlEditor.getData();
+                if (!Preferences.equalListOfStructs(mlSetting.getValue(), data)) {
+                    e.setValue(new Preferences.MapListSetting(data));
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Add new preference to the table
+     * @param gui - parent component for asking dialogs
+     * @return newly created entry or null if adding was cancelled
+     */
+    public PrefEntry addPreference(final JComponent gui) {
+        JPanel p = new JPanel(new GridBagLayout());
+        p.add(new JLabel(tr("Key")), GBC.std().insets(0,0,5,0));
+        JosmTextField tkey = new JosmTextField("", 50);
+        p.add(tkey, GBC.eop().insets(5,0,0,0).fill(GBC.HORIZONTAL));
+
+        p.add(new JLabel(tr("Select Setting Type:")), GBC.eol().insets(5,15,5,0));
+
+        JRadioButton rbString = new JRadioButton(tr("Simple"));
+        JRadioButton rbList = new JRadioButton(tr("List"));
+        JRadioButton rbListList = new JRadioButton(tr("List of lists"));
+        JRadioButton rbMapList = new JRadioButton(tr("List of maps"));
+
+        ButtonGroup group = new ButtonGroup();
+        group.add(rbString);
+        group.add(rbList);
+        group.add(rbListList);
+        group.add(rbMapList);
+
+        p.add(rbString, GBC.eol());
+        p.add(rbList, GBC.eol());
+        p.add(rbListList, GBC.eol());
+        p.add(rbMapList, GBC.eol());
+
+        rbString.setSelected(true);
+
+        ExtendedDialog dlg = new ExtendedDialog(gui, tr("Add setting"), new String[] {tr("OK"), tr("Cancel")});
+        dlg.setButtonIcons(new String[] {"ok.png", "cancel.png"});
+        dlg.setContent(p);
+        dlg.showDialog();
+
+        PrefEntry pe = null;
+        boolean ok = false;
+        if (dlg.getValue() == 1) {
+            if (rbString.isSelected()) {
+                Preferences.StringSetting sSetting = new Preferences.StringSetting(null);
+                pe = new PrefEntry(tkey.getText(), sSetting, sSetting, false);
+                StringEditor sEditor = new StringEditor(gui, pe, sSetting);
+                sEditor.showDialog();
+                if (sEditor.getValue() == 1) {
+                    String data = sEditor.getData();
+                    if (!Utils.equal(sSetting.getValue(), data)) {
+                        pe.setValue(new Preferences.StringSetting(data));
+                        ok = true;
+                    }
+                }
+            } else if (rbList.isSelected()) {
+                Preferences.ListSetting lSetting = new Preferences.ListSetting(null);
+                pe = new PrefEntry(tkey.getText(), lSetting, lSetting, false);
+                ListEditor lEditor = new ListEditor(gui, pe, lSetting);
+                lEditor.showDialog();
+                if (lEditor.getValue() == 1) {
+                    List<String> data = lEditor.getData();
+                    if (!Preferences.equalCollection(lSetting.getValue(), data)) {
+                        pe.setValue(new Preferences.ListSetting(data));
+                        ok = true;
+                    }
+                }
+            } else if (rbListList.isSelected()) {
+                Preferences.ListListSetting llSetting = new Preferences.ListListSetting(null);
+                pe = new PrefEntry(tkey.getText(), llSetting, llSetting, false);
+                ListListEditor llEditor = new ListListEditor(gui, pe, llSetting);
+                llEditor.showDialog();
+                if (llEditor.getValue() == 1) {
+                    List<List<String>> data = llEditor.getData();
+                    @SuppressWarnings("unchecked")
+                    Collection<Collection<String>> llSettingValue = (Collection) llSetting.getValue();
+                    if (!Preferences.equalArray(llSettingValue, data)) {
+                        pe.setValue(new Preferences.ListListSetting(data));
+                        ok = true;
+                    }
+                }
+            } else if (rbMapList.isSelected()) {
+                Preferences.MapListSetting mlSetting = new Preferences.MapListSetting(null);
+                pe = new PrefEntry(tkey.getText(), mlSetting, mlSetting, false);
+                MapListEditor mlEditor = new MapListEditor(gui, pe, mlSetting);
+                mlEditor.showDialog();
+                if (mlEditor.getValue() == 1) {
+                    List<Map<String, String>> data = mlEditor.getData();
+                    if (!Preferences.equalListOfStructs(mlSetting.getValue(), data)) {
+                        pe.setValue(new Preferences.MapListSetting(data));
+                        ok = true;
+                    }
+                }
+            }
+        }
+        if (ok) 
+            return pe; 
+        else 
+            return null;
+    }
+
+    /**
+     * Reset selected preferences to their default values
+     * @param gui - parent component to display warning messages
+     */
+    public void resetPreferences(final JComponent gui) {
+        if (getSelectedRowCount() == 0) {
+            JOptionPane.showMessageDialog(
+                    gui,
+                    tr("Please select the row to delete."),
+                    tr("Warning"),
+                    JOptionPane.WARNING_MESSAGE
+                    );
+            return;
+        }
+        for (int row : getSelectedRows()) {
+            PrefEntry e = displayData.get(row);
+            e.reset();
+        }
+        fireDataChanged();
+    }
+    
+    private class AllSettingsTableModel extends DefaultTableModel {
+
+        public AllSettingsTableModel() {
+            setColumnIdentifiers(new String[]{tr("Key"), tr("Value")});
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return column == 1 && (displayData.get(row).getValue() instanceof Preferences.StringSetting);
+        }
+
+        @Override
+        public int getRowCount() {
+            return displayData.size();
+        }
+
+        @Override
+        public Object getValueAt(int row, int column) {
+            if (column == 0)
+                return displayData.get(row).getKey();
+            else
+                return displayData.get(row);
+        }
+
+        @Override
+        public void setValueAt(Object o, int row, int column) {
+            PrefEntry pe = displayData.get(row);
+            String s = (String) o;
+            if (!s.equals(pe.getValue().getValue())) {
+                pe.setValue(new Preferences.StringSetting(s));
+                fireTableCellUpdated(row, column);
+            }
+        }
+    }
+
+    private static class SettingCellRenderer extends DefaultTableCellRenderer {
+        private Color backgroundColor = Main.pref.getUIColor("Table.background");
+        private Color changedColor = Main.pref.getColor(
+                         marktr("Advanced Background: Changed"),
+                         new Color(200,255,200));
+        private Color foregroundColor = Main.pref.getUIColor("Table.foreground");
+        private Color nonDefaultColor = Main.pref.getColor(
+                            marktr("Advanced Background: NonDefalut"),
+                            new Color(255,255,200));
+        
+        @Override
+        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+            if (value == null)
+                return this;
+            PrefEntry pe = (PrefEntry) value;
+            Preferences.Setting setting = pe.getValue();
+            Object val = setting.getValue();
+            String display = val != null ? val.toString() : "<html><i>&lt;"+tr("unset")+"&gt;</i></html>";
+            
+            JLabel label = (JLabel)super.getTableCellRendererComponent(table,
+                    display, isSelected, hasFocus, row, column);
+
+            label.setBackground(backgroundColor);
+            if (isSelected) {
+                label.setForeground(foregroundColor);
+            }
+            if(pe.isChanged()) {
+                label.setBackground(changedColor);
+            } else if(!pe.isDefault()) {
+                label.setBackground(nonDefaultColor);
+            }
+
+            if (!pe.isDefault()) {
+                label.setFont(label.getFont().deriveFont(Font.BOLD));
+            }
+            val = pe.getDefaultValue().getValue();
+            if(val != null)
+            {
+                if(pe.isDefault()) {
+                    label.setToolTipText(tr("Current value is default."));
+                } else {
+                    label.setToolTipText(tr("Default value is ''{0}''.", val));
+                }
+            } else {
+                label.setToolTipText(tr("Default value currently unknown (setting has not been used yet)."));
+            }
+            return label;
+        }
+    }
+
+    private static class SettingCellEditor extends DefaultCellEditor {
+        public SettingCellEditor() {
+            super(new JosmTextField());
+        }
+
+        @Override
+        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+            PrefEntry pe = (PrefEntry) value;
+            Preferences.StringSetting stg = (Preferences.StringSetting) pe.getValue();
+            String s = stg.getValue() == null ? "" : stg.getValue();
+            return super.getTableCellEditorComponent(table, s, isSelected, row, column);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/StringEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/StringEditor.java	(revision 6020)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/StringEditor.java	(revision 6021)
@@ -5,4 +5,5 @@
 
 import java.awt.GridBagLayout;
+import javax.swing.JComponent;
 
 import javax.swing.JLabel;
@@ -11,6 +12,4 @@
 import org.openstreetmap.josm.data.Preferences.StringSetting;
 import org.openstreetmap.josm.gui.ExtendedDialog;
-import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
-import org.openstreetmap.josm.gui.preferences.advanced.AdvancedPreference.PrefEntry;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
@@ -21,5 +20,5 @@
     JosmTextField tvalue;
 
-    public StringEditor(final PreferenceTabbedPane gui, PrefEntry entry, StringSetting setting) {
+    public StringEditor(final JComponent gui, PrefEntry entry, StringSetting setting) {
         super(gui, tr("Change string setting"), new String[] {tr("OK"), tr("Cancel")});
         this.entry = entry;
