Index: /applications/editors/josm/plugins/tageditor/build.xml
===================================================================
--- /applications/editors/josm/plugins/tageditor/build.xml	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/build.xml	(revision 20058)
@@ -28,6 +28,6 @@
 
 
-	<property name="commit.message" value="Fixed NPE when icon is missing" />
-	<property name="plugin.main.version" value="2830" />
+	<property name="commit.message" value="Tageditor plugin cleaned up" />
+	<property name="plugin.main.version" value="3015" />
 
 	<!--
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/LaunchAction.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/LaunchAction.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/LaunchAction.java	(revision 20058)
@@ -3,10 +3,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GraphicsConfiguration;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
@@ -25,5 +19,4 @@
 import org.openstreetmap.josm.tools.Shortcut;
 
-@SuppressWarnings("serial")
 public class LaunchAction extends JosmAction implements SelectionChangedListener {
 
@@ -68,67 +61,7 @@
 		);
 
-
-		// register as dataset selection listener
-		//
 		DataSet.selListeners.add(this);
-
-		// insert a menu item
-		//
 		registerAsMenuItem();
-
-		// initially not enabled; becomes enabled when the selection becomes non-empty
-		//
 		setEnabled(false);
-
-	}
-
-	/**
-	 * 
-	 * @return  the top window of the JOSM GUI; can be null
-	 */
-	protected Window getTopWindow() {
-		if (Main.contentPane == null)
-			return null;
-		Component c = Main.contentPane;
-		while(c.getParent() != null) {
-			c = c.getParent();
-		}
-		if (c instanceof Window)
-			return (Window)c;
-		else
-			return null;
-	}
-
-	/**
-	 * tries to center the tag editor dialog on the top window or, alternatively,
-	 * on the screen
-	 * 
-	 * @param dialog the dialog to be placed on the screen
-	 */
-	protected void placeDialogOnScreen(TagEditorDialog dialog) {
-		Window w = getTopWindow();
-		if (w == null)
-			// don't center
-			return;
-
-		GraphicsConfiguration gc = w.getGraphicsConfiguration();
-		Rectangle screenBounds = null;
-		if (gc != null) {
-			screenBounds = gc.getBounds();
-		}
-		Rectangle winBounds = w.getBounds();
-		Dimension d = dialog.getPreferredSize();
-
-		Point p = new Point();
-		if (d.width <= winBounds.width && d.height <= winBounds.height) {
-			p.x = winBounds.x + ((winBounds.width - d.width)/2 );
-			p.y = winBounds.y + ((winBounds.height - d.height)/2 );
-		} else  {
-			p.x = screenBounds.x + ((screenBounds.width - d.width)/2 );
-			p.y = screenBounds.y + ((screenBounds.height - d.height)/2 );
-		}
-
-		dialog.setLocation(p);
-
 	}
 
@@ -140,5 +73,4 @@
 			return;
 		TagEditorDialog dialog = TagEditorDialog.getInstance();
-		placeDialogOnScreen(dialog);
 		dialog.startEditSession();
 		dialog.setVisible(true);
@@ -152,7 +84,3 @@
 		setEnabled(newSelection != null && newSelection.size() >0);
 	}
-
-
-
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorDialog.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorDialog.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorDialog.java	(revision 20058)
@@ -14,5 +14,4 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.util.Collection;
 import java.util.logging.Logger;
 
@@ -43,16 +42,16 @@
 import org.openstreetmap.josm.plugins.tageditor.tagspec.ui.ITagSelectorListener;
 import org.openstreetmap.josm.plugins.tageditor.tagspec.ui.TabularTagSelector;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.WindowGeometry;
 /**
  * The dialog for editing name/value-pairs (aka <em>tags</em>) associated with {@link OsmPrimitive}s.
  * 
- *
  */
 @SuppressWarnings("serial")
 public class TagEditorDialog extends JDialog {
-
-	static private Logger logger = Logger.getLogger(TagEditorDialog.class.getName());
+	static private final Logger logger = Logger.getLogger(TagEditorDialog.class.getName());
 
 	/** the unique instance */
-	static protected  TagEditorDialog instance = null;
+	static private  TagEditorDialog instance = null;
 
 	/**
@@ -68,14 +67,9 @@
 	}
 
-
-	/**
-	 * default preferred size
-	 */
+	/** default preferred size */
 	static public final Dimension PREFERRED_SIZE = new Dimension(700, 500);
-
 
 	/** the properties table */
 	private TagEditor tagEditor = null;
-	private TagEditorModel model = null;
 
 	/**  the auto completion list viewer */
@@ -85,85 +79,34 @@
 	private AutoCompletionCache acCache = null;
 
-	/** widgets */
-	private JButton btnOK = null;
-	private JButton btnCancel = null;
-	private JButton btnAdd = null;
-	private JButton btnDelete = null;
 	private OKAction okAction = null;
 	private CancelAction cancelAction = null;
 
-
-	public OKAction getOKAction() {
-		return okAction;
-	}
-
 	/**
 	 * @return the tag editor model
 	 */
 	public TagEditorModel getModel() {
-		return model;
-	}
-
-
+		return tagEditor.getModel();
+	}
 
 	protected JPanel buildButtonRow() {
-		// create the rows of action buttons at the bottom
-		// of the dialog
-		//
-		JPanel pnl = new JPanel();
-		pnl.setLayout(new FlowLayout(FlowLayout.RIGHT));
-
+		JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
+		
 		// the ok button
 		//
-		okAction = new OKAction();
-		btnOK = new JButton(okAction);
+		pnl.add(new JButton(okAction = new OKAction()));
 		getModel().addPropertyChangeListener(okAction);
 
 		// the cancel button
 		//
-		cancelAction = new CancelAction();
-		btnCancel = new JButton(cancelAction);
-		pnl.add(btnOK);
-		pnl.add(btnCancel);
-
-		JPanel pnl1 = new JPanel();
-		pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
-
-		// the add button
-		//
-		btnAdd = new JButton(tagEditor.getAddAction());
-		btnDelete = new JButton(tagEditor.getDeleteAction());
-
-		pnl1.add(btnAdd);
-		pnl1.add(btnDelete);
-
-		JPanel pnl2 = new JPanel();
-		pnl2.setLayout(new BorderLayout());
-		pnl2.add(pnl1, BorderLayout.WEST);
-		pnl2.add(pnl, BorderLayout.EAST);
-
-		return pnl2;
-	}
-
-	/**
-	 * build the GUI
-	 */
-	protected void build() {
-		getContentPane().setLayout(new BorderLayout());
-
-		// basic UI prpoperties
-		//
-		setModal(true);
-		setSize(PREFERRED_SIZE);
-		setTitle(tr("JOSM Tag Editor Plugin"));
-
-
+		pnl.add(new JButton(cancelAction  = new CancelAction()));
+		return pnl;
+	}
+
+	protected JPanel buildTagGridPanel() {
 		// create tag editor and inject an instance of the tag
 		// editor model
 		//
 		tagEditor = new TagEditor();
-		tagEditor.setTagEditorModel(model);
-
-
+		
 		// create the auto completion list viewer and connect it
 		// to the tag editor
@@ -174,11 +117,38 @@
 		tagEditor.setAutoCompletionCache(acCache);
 		aclViewer.addAutoCompletionListListener(tagEditor);
+		tagEditor.addComponentNotStoppingCellEditing(aclViewer);
 
 		JPanel pnlTagGrid = new JPanel();
 		pnlTagGrid.setLayout(new BorderLayout());
+		
+		
 		pnlTagGrid.add(tagEditor, BorderLayout.CENTER);
 		pnlTagGrid.add(aclViewer, BorderLayout.EAST);
 		pnlTagGrid.setBorder(BorderFactory.createEmptyBorder(5, 0,0,0));
-
+		
+		JSplitPane splitPane = new JSplitPane(
+				JSplitPane.HORIZONTAL_SPLIT,
+				tagEditor, 
+				aclViewer
+		);
+		splitPane.setOneTouchExpandable(false);
+		splitPane.setDividerLocation(600);		
+		pnlTagGrid.add(splitPane, BorderLayout.CENTER);
+		return pnlTagGrid;
+	}
+		
+	/**
+	 * build the GUI
+	 */
+	protected void build() {
+		getContentPane().setLayout(new BorderLayout());
+
+		// basic UI prpoperties
+		//
+		setModal(true);
+		setSize(PREFERRED_SIZE);
+		setTitle(tr("JOSM Tag Editor Plugin"));
+		
+		JPanel pnlTagGrid = buildTagGridPanel();
 
 		// create the preset selector
@@ -189,10 +159,9 @@
 					public void itemSelected(Item item) {
 						tagEditor.stopEditing();
-						model.applyPreset(item);
+						tagEditor.getModel().applyPreset(item);
 						tagEditor.requestFocusInTopLeftCell();
 					}
 				}
 		);
-
 
 		JPanel pnlPresetSelector = new JPanel();
@@ -208,5 +177,5 @@
 					public void itemSelected(KeyValuePair pair) {
 						tagEditor.stopEditing();
-						model.applyKeyValuePair(pair);
+						tagEditor.getModel().applyKeyValuePair(pair);
 						tagEditor.requestFocusInTopLeftCell();
 					}
@@ -218,7 +187,4 @@
 		pnlTagSelector.setBorder(BorderFactory.createEmptyBorder(0,0,5,0	));
 
-
-
-
 		// create the tabbed pane
 		//
@@ -227,8 +193,12 @@
 		tabbedPane.add(pnlTagSelector, tr("Tags"));
 
+		
 		// create split pane
 		//
-		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
-				tabbedPane, pnlTagGrid);
+		JSplitPane splitPane = new JSplitPane(
+				JSplitPane.VERTICAL_SPLIT,
+				tabbedPane, 
+				pnlTagGrid
+		);
 		splitPane.setOneTouchExpandable(true);
 		splitPane.setDividerLocation(200);
@@ -258,5 +228,4 @@
 		);
 
-
 		// makes sure that 'Ctrl-Enter' in the properties table
 		// and in the aclViewer is handled by okAction
@@ -279,22 +248,27 @@
 	}
 
-
-
 	/**
 	 * constructor
 	 */
 	protected TagEditorDialog() {
-		acCache = new AutoCompletionCache();
-		model = new TagEditorModel();
+		acCache = new AutoCompletionCache();	
 		build();
 	}
 
-
-	@Override
-	public Dimension getPreferredSize() {
-		return PREFERRED_SIZE;
-	}
-
-
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            new WindowGeometry(
+                    getClass().getName() + ".geometry",
+                    WindowGeometry.centerInWindow(
+                            Main.parent,
+                            PREFERRED_SIZE
+                    )
+            ).applySafe(this);
+        } else if (!visible && isShowing()){
+            new WindowGeometry(this).remember(getClass().getName() + ".geometry");
+        }
+        super.setVisible(visible);
+    }
 
 	/**
@@ -304,18 +278,16 @@
 	 */
 	public void startEditSession() {
-		model.clearAppliedPresets();
-		model.initFromJOSMSelection();
+		tagEditor.getModel().clearAppliedPresets();
+		tagEditor.getModel().initFromJOSMSelection();
 		//acCache.initFromJOSMDataset();
 		getModel().ensureOneTag();
 	}
 
-
-
-	@SuppressWarnings("serial")
 	class CancelAction extends AbstractAction {
-
 		public CancelAction() {
-			putValue(Action.NAME, tr("Cancel"));
-			putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
+			putValue(NAME, tr("Cancel"));
+			putValue(SMALL_ICON, ImageProvider.get("cancel"));
+			putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
+			putValue(SHORT_DESCRIPTION, tr("Abort tag editing and close dialog"));
 		}
 
@@ -325,12 +297,11 @@
 	}
 
-
-
-	@SuppressWarnings("serial")
 	class OKAction extends AbstractAction implements PropertyChangeListener {
 
 		public OKAction() {
-			putValue(Action.NAME, tr("OK"));
-			putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl ENTER"));
+			putValue(NAME, tr("OK"));
+			putValue(SMALL_ICON, ImageProvider.get("ok"));
+			putValue(SHORT_DESCRIPTION, tr("Apply edited tags and close dialog"));
+			putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl ENTER"));
 		}
 
@@ -342,5 +313,5 @@
 			tagEditor.stopEditing();
 			setVisible(false);
-			model.updateJOSMSelection();
+			tagEditor.getModel().updateJOSMSelection();
 			DataSet ds = Main.main.getCurrentDataSet();
 			ds.fireSelectionChanged();
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionCache.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionCache.java	(revision 20057)
+++ 	(revision )
@@ -1,114 +1,0 @@
-package org.openstreetmap.josm.plugins.tageditor.ac;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
-/**
- * AutoCompletionCache temporarily holds a cache of keys with a list of
- * possible auto completion values for each key.
- * 
- * The cache can initialize itself from the current JOSM data set such that
- * <ol>
- *   <li>any key used in a tag in the data set is part of the key list in the cache</li>
- *   <li>any value used in a tag for a specific key is part of the autocompletion list of
- *     this key</li>
- * </ol>
- * 
- * Building up auto completion lists should not
- * slow down tabbing from input field to input field. Looping through the complete
- * data set in order to build up the auto completion list for a specific input
- * field is not efficient enough, hence this cache.
- *
- */
-public class AutoCompletionCache {
-
-	/** the cache */
-	private HashMap<String, ArrayList<String>> cache;
-
-	/**
-	 * constructor
-	 */
-	public AutoCompletionCache() {
-		cache = new HashMap<String, ArrayList<String>>();
-	}
-
-	/**
-	 * make sure, <code>key</code> is in the cache
-	 * 
-	 * @param key  the key
-	 */
-	protected void cacheKey(String key) {
-		if (cache.containsKey(key))
-			return;
-		else {
-			cache.put(key, new ArrayList<String>());
-		}
-	}
-
-	/**
-	 * make sure, value is one of the auto completion values allowed for key
-	 * 
-	 * @param key the key
-	 * @param value the value
-	 */
-	protected void cacheValue(String key, String value) {
-		cacheKey(key);
-		ArrayList<String> values = cache.get(key);
-		if (!values.contains(value)) {
-			values.add(value);
-		}
-	}
-
-	/**
-	 * make sure, the keys and values of all tags held by primitive are
-	 * in the auto completion cache
-	 * 
-	 * @param primitive an OSM primitive
-	 */
-	protected void cachePrimitive(OsmPrimitive primitive) {
-		for (String key: primitive.keySet()) {
-			String value = primitive.get(key);
-			cacheValue(key, value);
-		}
-	}
-
-	/**
-	 * initializes the cache from the current JOSM dataset {@link OsmPrimitive}s.
-	 * 
-	 */
-	public void initFromJOSMDataset() {
-		cache = new HashMap<String, ArrayList<String>>();
-		Collection<OsmPrimitive> ds = Main.main.getCurrentDataSet().allNonDeletedPrimitives();
-		for (OsmPrimitive primitive : ds) {
-			cachePrimitive(primitive);
-		}
-	}
-
-	/**
-	 * replies the keys held by the cache
-	 * 
-	 * @return the list of keys held by the cache
-	 */
-	public List<String> getKeys() {
-		return new ArrayList<String>(cache.keySet());
-	}
-
-
-	/**
-	 * replies the auto completion values allowed for a specific key. Replies
-	 * an empty list if key is null or if key is not in {@link #getKeys()}.
-	 * 
-	 * @param key
-	 * @return the list of auto completion values
-	 */
-	public List<String> getValues(String key) {
-		if (!cache.containsKey(key))
-			return new ArrayList<String>();
-		else
-			return cache.get(key);
-	}
-}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionContext.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionContext.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionContext.java	(revision 20058)
@@ -2,5 +2,4 @@
 
 import org.openstreetmap.josm.Main;
-
 
 public class AutoCompletionContext {
@@ -20,5 +19,4 @@
 		selectionEmpty = (Main.main.getCurrentDataSet().getSelected().size() == 0);
 	}
-
 
 	public boolean isSelectionEmpty() {
@@ -49,7 +47,3 @@
 		this.selectionIncludesRelations = selectionIncludesRelations;
 	}
-
-
-
-
 }
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionItemPritority.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionItemPritority.java	(revision 20057)
+++ 	(revision )
@@ -1,26 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.tageditor.ac;
-
-public enum AutoCompletionItemPritority implements Comparable<AutoCompletionItemPritority> {
-
-	/** indicates that a value is in the current selection */
-	IS_IN_SELECTION,
-
-	/** indicates that this is a standard value, i.e. a standard tag name 
-	 *  or a standard value for a given tag name 
-	 */
-	IS_IN_STANDARD,
-	
-	
-	/**
-	 * indicates that this is an arbitrary value from the data set, i.e. 
-	 * the value of a tag name=xxx
-	 */
-	IS_IN_DATASET,
-	
-	/** unknown priority. This is the lowest priority. */
-	UNKNOWN
-	
-	
-	
-}
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionList.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionList.java	(revision 20057)
+++ 	(revision )
@@ -1,285 +1,0 @@
-package org.openstreetmap.josm.plugins.tageditor.ac;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import javax.swing.JTable;
-import javax.swing.table.AbstractTableModel;
-
-/**
- * AutoCompletionList manages a list of {@see AutoCompletionListItem}s.
- * 
- * The list is sorted, items with higher priority first, then according to lexicographic order
- * on the value of the {@see AutoCompletionListItem}.
- * 
- * AutoCompletionList maintains two views on the list of {@see AutoCompletionListItem}s.
- * <ol>
- *   <li>the bare, unfiltered view which includes all items</li>
- *   <li>a filtered view, which includes only items which match a current filter expression</li>
- * </ol>
- * 
- * AutoCompletionList is an {@link AbstractTableModel} which serves the list of filtered
- * items to a {@link JTable}.
- * 
- * @author gubaer
- */
-public class AutoCompletionList extends AbstractTableModel {
-
-	/** the bare list of AutoCompletionItems */
-	private ArrayList<AutoCompletionListItem> list = null;
-	/**  the filtered list of AutoCompletionItems */
-	private ArrayList<AutoCompletionListItem> filtered = null;
-	/** the filter expression */
-	private String filter = null;
-
-	/**
-	 * constructor
-	 */
-	public AutoCompletionList() {
-		list = new ArrayList<AutoCompletionListItem>();
-		filtered = new ArrayList<AutoCompletionListItem>();
-	}
-
-
-	/**
-	 * applies a filter expression to the list of {@see AutoCompletionListItem}s.
-	 * 
-	 * The matching criterion is a case insensitive substring match.
-	 * 
-	 * @param filter  the filter expression; must not be null
-	 * 
-	 * @exception IllegalArgumentException thrown, if filter is null
-	 */
-	public void applyFilter(String filter) {
-		if (filter == null)
-			throw new IllegalArgumentException("argument 'filter' must not be null");
-		this.filter = filter;
-		filter();
-	}
-
-	/**
-	 * clears the current filter
-	 * 
-	 */
-	public void clearFilter() {
-		filter = null;
-		filter();
-	}
-
-	/**
-	 * @return the current filter expression; null, if no filter expression is set
-	 */
-	public String getFilter() {
-		return filter;
-	}
-
-
-	/**
-	 * adds an AutoCompletionListItem to the list. Only adds the item if it
-	 * is not null and if not in the list yet.
-	 * 
-	 * @param item the item
-	 */
-	public void add(AutoCompletionListItem item) {
-		if (item == null)
-			return;
-		appendOrUpdatePriority(item);
-		sort();
-		filter();
-	}
-
-
-	/**
-	 * adds another AutoCompletionList to this list. An item is only
-	 * added it is not null and if it does not exist in the list yet.
-	 * 
-	 * @param other another auto completion list; must not be null
-	 * @exception IllegalArgumentException thrown, if other is null
-	 */
-	public void add(AutoCompletionList other) {
-		if (other == null)
-			throw new IllegalArgumentException("argument 'other' must not be null");
-		for (AutoCompletionListItem item : other.list) {
-			appendOrUpdatePriority(item);
-		}
-		sort();
-		filter();
-	}
-
-
-	/**
-	 * adds a list of AutoCompletionListItem to this list. Only items which
-	 * are not null and which do not exist yet in the list are added.
-	 * 
-	 * @param other a list of AutoCompletionListItem; must not be null
-	 * @exception IllegalArgumentException thrown, if other is null
-	 */
-	public void add(List<AutoCompletionListItem> other) {
-		if (other == null)
-			throw new IllegalArgumentException("argument 'other' must not be null");
-		for (AutoCompletionListItem toadd : other) {
-			appendOrUpdatePriority(toadd);
-		}
-		sort();
-		filter();
-	}
-
-	protected void appendOrUpdatePriority(AutoCompletionListItem toadd) {
-		AutoCompletionListItem item = lookup(toadd.getValue());
-		if (item == null) {
-			// new item does not exist yet. Add it to the list
-			//
-			list.add(toadd);
-		} else {
-			// new item already exists. Update priority if necessary
-			//
-			if (toadd.getPriority().compareTo(item.getPriority()) < 0) {
-				item.setPriority(toadd.getPriority());
-			}
-		}
-	}
-
-	/**
-	 * checks whether a specific item is already in the list. Matches for the
-	 * the value <strong>and</strong> the priority of the item
-	 * 
-	 * @param item the item to check
-	 * @return true, if item is in the list; false, otherwise
-	 */
-	public boolean contains(AutoCompletionListItem item) {
-		if (item == null)
-			return false;
-		return list.contains(item);
-	}
-
-	/**
-	 * checks whether an item with the given value is already in the list. Ignores
-	 * priority of the items.
-	 * 
-	 * @param value the value of an auto completion item
-	 * @return true, if value is in the list; false, otherwise
-	 */
-	public boolean contains(String value) {
-		if (value == null)
-			return false;
-		for (AutoCompletionListItem item: list) {
-			if (item.getValue().equals(value))
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * 
-	 * @param value a specific value
-	 * @return  the auto completion item for this value; null, if there is no
-	 *   such auto completion item
-	 */
-	public AutoCompletionListItem lookup(String value) {
-		if (value == null)
-			return null;
-		for (AutoCompletionListItem item : list) {
-			if (item.getValue().equals(value))
-				return item;
-		}
-		return null;
-	}
-
-
-	/**
-	 * removes the auto completion item with key <code>key</code>
-	 * @param key  the key;
-	 */
-	public void remove(String key) {
-		if (key == null)
-			return;
-		for (int i=0;i< list.size();i++) {
-			AutoCompletionListItem item = list.get(i);
-			if (item.getValue().equals(key)) {
-				list.remove(i);
-				return;
-			}
-		}
-	}
-
-
-
-	/**
-	 * sorts the list
-	 */
-	protected void sort() {
-		Collections.sort(list);
-	}
-
-	protected void filter() {
-		filtered.clear();
-		if (filter == null) {
-			// Collections.copy throws an exception "Source does not fit in dest"
-			// Collections.copy(filtered, list);
-			filtered.ensureCapacity(list.size());
-			for (AutoCompletionListItem item: list) {
-				filtered.add(item);
-			}
-			return;
-		}
-
-		// apply the pattern to list of possible values. If it matches, add the
-		// value to the list of filtered values
-		//
-		for (AutoCompletionListItem item : list) {
-			if (item.getValue().startsWith(filter)) {
-				filtered.add(item);
-			}
-		}
-
-		fireTableDataChanged();
-	}
-
-	/**
-	 * replies the number of filtered items
-	 * 
-	 * @return the number of filtered items
-	 */
-	public int getFilteredSize() {
-		return this.filtered.size();
-	}
-
-	/**
-	 * replies the idx-th item from the list of filtered items
-	 * @param idx the index; must be in the range 0<= idx < {@see #getFilteredSize()}
-	 * @return the item
-	 * 
-	 * @exception IndexOutOfBoundsException thrown, if idx is out of bounds
-	 */
-	public AutoCompletionListItem getFilteredItem(int idx) {
-		if (idx < 0 || idx >= getFilteredSize())
-			throw new IndexOutOfBoundsException("idx out of bounds. idx=" + idx);
-		return filtered.get(idx);
-	}
-
-
-	/**
-	 * removes all elements from the auto completion list
-	 * 
-	 */
-	public void clear() {
-		list.clear();
-		fireTableDataChanged();
-	}
-
-
-	public int getColumnCount() {
-		return 1;
-	}
-
-	public int getRowCount() {
-
-		return list == null ? 0 : getFilteredSize();
-	}
-
-	public Object getValueAt(int rowIndex, int columnIndex) {
-		return list == null ? null : getFilteredItem(rowIndex);
-	}
-
-}
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListItem.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListItem.java	(revision 20057)
+++ 	(revision )
@@ -1,129 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.tageditor.ac;
-
-/**
- * Represents an entry in the list of auto completion values.
- * 
- *  An AutoCompletionListItem has a <em>priority</em> and a <em>value</em>.
- * 
- *  The priority helps to sort the auto completion items according to their importance. For instance,
- *  in an auto completion list for tag names, standard tag names would be assigned a higher
- *  priority than arbitrary tag names present in the current data set. There are three priority levels,
- *  {@see AutoCompletionItemPritority}.
- *
- * The value is a string which will be displayed in the auto completion list.
- * 
- * @author gubaer
- *
- */
-public class AutoCompletionListItem implements Comparable<AutoCompletionListItem>{
-
-	/** the pritority of this item */
-	private  AutoCompletionItemPritority priority;
-	/** the value of this item */
-	private String value;
-
-	/**
-	 * constructor
-	 */
-	public AutoCompletionListItem() {
-		value = "";
-		priority = AutoCompletionItemPritority.UNKNOWN;
-	}
-
-	public AutoCompletionListItem(String value, AutoCompletionItemPritority priority) {
-		this.value = value;
-		this.priority = priority;
-	}
-
-	/**
-	 * 
-	 * @return the priority
-	 */
-	public AutoCompletionItemPritority getPriority() {
-		return priority;
-	}
-
-	/**
-	 * sets the priority
-	 * @param priority  the priority
-	 */
-	public void setPriority(AutoCompletionItemPritority priority) {
-		this.priority = priority;
-	}
-
-	/**
-	 * 
-	 * @return the value
-	 */
-	public String getValue() {
-		return value;
-	}
-
-	/**
-	 * sets the value
-	 * @param value the value; must not be null
-	 * @exception IllegalArgumentException thrown, if value if null
-	 */
-	public void setValue(String value) {
-		if (value == null)
-			throw new IllegalArgumentException("argument 'value' must not be null");
-		this.value = value;
-	}
-
-	@Override public String toString() {
-		StringBuilder sb = new StringBuilder();
-		sb.append("<AutoCompletionItemPritority: ");
-		sb.append("value='");
-		sb.append(value);
-		sb.append("',");
-		sb.append("priority='");
-		sb.append(priority.toString());
-		sb.append("'>");
-		return sb.toString();
-	}
-
-	@Override public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result
-		+ ((priority == null) ? 0 : priority.hashCode());
-		result = prime * result + ((value == null) ? 0 : value.hashCode());
-		return result;
-	}
-
-	@Override public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		final AutoCompletionListItem other = (AutoCompletionListItem)obj;
-		if (priority == null) {
-			if (other.priority != null)
-				return false;
-		} else if (!priority.equals(other.priority))
-			return false;
-		if (value == null) {
-			if (other.value != null)
-				return false;
-		} else if (!value.equals(other.value))
-			return false;
-		return true;
-	}
-
-
-	public int compareTo(AutoCompletionListItem other) {
-		int ret = this.priority.compareTo(other.priority);
-		if (ret != 0)
-			return ret;
-		else
-			return this.value.compareTo(other.value);
-	}
-
-
-
-
-
-}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListRenderer.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListRenderer.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListRenderer.java	(revision 20058)
@@ -1,6 +1,7 @@
 package org.openstreetmap.josm.plugins.tageditor.ac;
 
-import java.awt.Color;
 import java.awt.Component;
+import java.awt.Font;
+import java.net.URL;
 
 import javax.swing.Icon;
@@ -8,22 +9,18 @@
 import javax.swing.JLabel;
 import javax.swing.JTable;
+import javax.swing.UIManager;
 import javax.swing.table.TableCellRenderer;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 /**
  * This is the table cell renderer for the list of auto completion list items.
  * 
- * It uses an instance of {@Link JLabel} to render an {@link AutoCompletionListItem}.
- * 
- *
  */
-public class AutoCompletionListRenderer implements TableCellRenderer {
-
+public class AutoCompletionListRenderer extends JLabel implements TableCellRenderer {
 
 	static public final String RES_OSM_ICON = "/resources/osm.gif";
 	static public final String RES_SELECTION_ICON = "/resources/selection.gif";
-	public static final Color BG_COLOR_SELECTED = new Color(143,170,255);
-
-	/** the renderer component */
-	private final JLabel renderer;
 
 	/** the icon used to decorate items of priority
@@ -41,7 +38,5 @@
 	 */
 	public AutoCompletionListRenderer() {
-		renderer = new JLabel();
-		renderer.setOpaque(true);
-
+		setOpaque(true);
 		loadIcons();
 	}
@@ -51,5 +46,5 @@
 	 */
 	protected void loadIcons() {
-		java.net.URL imgURL = getClass().getResource(RES_OSM_ICON);
+		URL imgURL = getClass().getResource(RES_OSM_ICON);
 		if (imgURL != null) {
 			iconStandard = new ImageIcon(imgURL);
@@ -68,5 +63,4 @@
 	}
 
-
 	/**
 	 * prepares the renderer for rendering a specific icon
@@ -77,9 +71,9 @@
 		if (item.getPriority().equals(AutoCompletionItemPritority.IS_IN_STANDARD)) {
 			if (iconStandard != null) {
-				renderer.setIcon(iconStandard);
+				setIcon(iconStandard);
 			}
 		} else if (item.getPriority().equals(AutoCompletionItemPritority.IS_IN_SELECTION)) {
 			if (iconSelection != null) {
-				renderer.setIcon(iconSelection);
+				setIcon(iconSelection);
 			}
 		}
@@ -90,9 +84,10 @@
 	 */
 	protected void resetRenderer() {
-		renderer.setIcon(null);
-		renderer.setText("");
-		renderer.setOpaque(true);
-		renderer.setBackground(Color.WHITE);
-		renderer.setForeground(Color.BLACK);
+		setIcon(null);
+		setText("");
+		setFont(UIManager.getFont("Table.font"));
+		setOpaque(true);
+		setBackground(UIManager.getColor("Table.background"));
+		setForeground(UIManager.getColor("Table.foreground"));
 	}
 
@@ -101,6 +96,6 @@
 	 */
 	protected void renderSelected() {
-		renderer.setBackground(BG_COLOR_SELECTED);
-		renderer.setForeground(Color.WHITE);
+		setBackground(UIManager.getColor("Table.selectionBackground"));
+		setForeground(UIManager.getColor("Table.selectionForeground"));
 	}
 
@@ -114,9 +109,12 @@
 			AutoCompletionListItem item = (AutoCompletionListItem)value;
 			prepareRendererIcon(item);
-			renderer.setText(item.getValue());
+			setText(item.getValue());
+			setToolTipText(item.getValue());
 		} else if (value != null) {
-			renderer.setText(value.toString());
+			setText(value.toString());
+			setToolTipText(value.toString());
 		} else {
-			renderer.setText("<null>");
+			setText(tr("unknown"));
+			setFont(getFont().deriveFont(Font.ITALIC));
 		}
 
@@ -126,11 +124,5 @@
 			renderSelected();
 		}
-
-
-		return renderer;
-
+		return this;
 	}
-
-
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListViewer.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListViewer.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListViewer.java	(revision 20058)
@@ -41,5 +41,4 @@
 		setLayout(new BorderLayout());
 	
-		
 		table = new JTable();
 		
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetItemListCellRenderer.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetItemListCellRenderer.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetItemListCellRenderer.java	(revision 20058)
@@ -3,7 +3,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Color;
 import java.awt.Component;
-import java.awt.Font;
 import java.util.logging.Logger;
 
@@ -11,13 +9,10 @@
 import javax.swing.JList;
 import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
 
 import org.openstreetmap.josm.plugins.tageditor.preset.Item;
 
-public class PresetItemListCellRenderer extends JLabel implements
-ListCellRenderer {
-
+public class PresetItemListCellRenderer extends JLabel implements ListCellRenderer {
 	private static final Logger logger = Logger.getLogger(PresetItemListCellRenderer.class.getName());
-	private static final Font DEFAULT_FONT =  new Font("SansSerif",Font.PLAIN,10);
-	public static final Color BG_COLOR_SELECTED = new Color(143,170,255);
 
 	public Component getListCellRendererComponent(JList list, Object value,
@@ -30,7 +25,9 @@
 		} else {
 			if (isSelected) {
-				setBackground(BG_COLOR_SELECTED);
+				setBackground(UIManager.getColor("Table.selectionBackground"));
+				setForeground(UIManager.getColor("Table.selectionForeground"));
 			} else {
-				setBackground(Color.WHITE);
+				setBackground(UIManager.getColor("Table.background"));
+				setForeground(UIManager.getColor("Table.foreground"));
 			}
 			setIcon(item.getIcon());
@@ -41,8 +38,7 @@
 			setText(sb.toString());
 			setOpaque(true);
-			setFont(DEFAULT_FONT);
+			setFont(UIManager.getFont("Table.font"));
 		}
 		return this;
 	}
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetManager.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetManager.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetManager.java	(revision 20058)
@@ -19,5 +19,5 @@
 public class PresetManager extends JPanel {
 
-	static private Logger logger = Logger.getLogger(PresetManager.class.getName());
+	static private final Logger logger = Logger.getLogger(PresetManager.class.getName());
 
 	private JComboBox presets;
@@ -99,6 +99,3 @@
 		this.model = model;
 	}
-
-
-
 }
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/RunnableAction.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/RunnableAction.java	(revision 20057)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package org.openstreetmap.josm.plugins.tageditor.editor;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.AbstractAction;
-
-public abstract class RunnableAction extends AbstractAction implements Runnable {
-
-	public RunnableAction() {
-	}
-
-	public abstract void run();
-
-	public void actionPerformed(ActionEvent arg0) {
-		run();
-	}
-}
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellEditor.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellEditor.java	(revision 20057)
+++ 	(revision )
@@ -1,245 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.tageditor.editor;
-
-import java.awt.Component;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.AbstractCellEditor;
-import javax.swing.JTable;
-
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionCache;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionContext;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionItemPritority;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionList;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionListItem;
-import org.openstreetmap.josm.plugins.tageditor.ac.IAutoCompletionListListener;
-import org.openstreetmap.josm.plugins.tageditor.tagspec.TagSpecifications;
-
-
-/**
- * This is the table cell editor for the tag editor dialog.
- * 
- *
- */
-@SuppressWarnings("serial")
-public class TableCellEditor extends AbstractCellEditor implements javax.swing.table.TableCellEditor, IAutoCompletionListListener{
-
-	/** the logger object */
-	static private Logger logger = Logger.getLogger(TableCellEditor.class.getName());
-
-	private TagFieldEditor editor = null;
-	private TagModel currentTag = null;
-	private TagEditorModel tagEditorModel = null;
-	private int currentColumn = 0;
-
-	/** the cache of auto completion items derived from the current JOSM data set */
-	private AutoCompletionCache acCache = null;
-
-	/** user input is matched against this list of auto completion items */
-	private AutoCompletionList autoCompletionList = null;
-
-	/**
-	 * constructor
-	 */
-	public TableCellEditor() {
-		editor = new TagFieldEditor();
-		acCache = new AutoCompletionCache();
-	}
-
-	/**
-	 * initializes  the auto completion list when the table cell editor starts
-	 * to edit the key of a tag. In this case the auto completion list is
-	 * initialized with the set of standard key values and the set of current key
-	 * values from the the current JOSM data set. Keys already present in the
-	 * current tag model are removed from the auto completion list.
-	 * 
-	 * @param model  the tag editor model
-	 * @param currentTag  the current tag
-	 */
-	protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) {
-		AutoCompletionContext context = new AutoCompletionContext();
-		context.initFromJOSMSelection();
-
-		if (autoCompletionList == null) {
-			logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
-			return;
-		}
-
-		autoCompletionList.clear();
-
-		// add the list of standard keys
-		//
-		try {
-			autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
-		} catch(Exception e) {
-			logger.log(Level.WARNING, "failed to initialize auto completion list with standard keys.", e);
-		}
-
-		// add the list of keys in the current data set
-		//
-		for (String key : acCache.getKeys()) {
-			autoCompletionList.add(
-					new AutoCompletionListItem(key, AutoCompletionItemPritority.IS_IN_DATASET)
-			);
-		}
-
-		// remove the keys already present in the current tag model
-		//
-		for (String key : model.getKeys()) {
-			if (! key.equals(currentTag.getName())) {
-				autoCompletionList.remove(key);
-			}
-		}
-		autoCompletionList.fireTableDataChanged();
-	}
-
-
-	/**
-	 * initializes the auto completion list when the cell editor starts to edit
-	 * a tag value. In this case the auto completion list is initialized with the
-	 * set of standard values for a given key and the set of values present in the
-	 * current data set for the given key.
-	 * 
-	 * @param forKey the key
-	 */
-	protected void initAutoCompletionListForValues(String forKey) {
-
-		if (autoCompletionList == null) {
-			logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
-			return;
-		}
-		autoCompletionList.clear();
-		AutoCompletionContext context = new AutoCompletionContext();
-		context.initFromJOSMSelection();
-
-		// add the list of standard values for the given key
-		//
-		try {
-			autoCompletionList.add(
-					TagSpecifications.getInstance().getLabelsForAutoCompletion(forKey, context)
-			);
-		} catch(Exception e){
-			logger.log(Level.WARNING, "failed to initialize auto completion list with standard values", e);
-		}
-
-		for (String value : acCache.getValues(forKey)) {
-			autoCompletionList.add(
-					new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_DATASET)
-			);
-		}
-
-		//  add the list of possible values for a key from the current selection
-		//
-		if (currentTag.getValueCount() > 1) {
-			for (String value : currentTag.getValues()) {
-				//logger.info("adding ac item " + value + " with priority IN_SELECTION");;
-				autoCompletionList.add(
-						new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION)
-				);
-			}
-		}
-	}
-
-
-	/**
-	 * replies the table cell editor
-	 */
-	public Component getTableCellEditorComponent(JTable table,
-			Object value, boolean isSelected, int row, int column) {
-		currentTag = (TagModel) value;
-
-		if (column == 0) {
-			editor.setText(currentTag.getName());
-			currentColumn = 0;
-			TagEditorModel model = (TagEditorModel)table.getModel();
-			initAutoCompletionListForKeys(model, currentTag);
-			return editor;
-		} else if (column == 1) {
-
-			if (currentTag.getValueCount() == 0) {
-				editor.setText("");
-			} else if (currentTag.getValueCount() == 1) {
-				editor.setText(currentTag.getValues().get(0));
-			} else {
-				editor.setText("");
-			}
-			currentColumn = 1;
-			initAutoCompletionListForValues(currentTag.getName());
-			return editor;
-		} else {
-			logger.warning("column this table cell editor is requested for is out of range. column=" + column);
-			return null;
-		}
-	}
-
-	public Object getCellEditorValue() {
-		return editor.getText();
-	}
-
-	@Override
-	public void cancelCellEditing() {
-		super.cancelCellEditing();
-	}
-
-	@Override
-	public boolean stopCellEditing() {
-		if (tagEditorModel == null) {
-			logger.warning("no tag editor model set. Can't update edited values. Please set tag editor model first");
-			return super.stopCellEditing();
-		}
-
-		if (currentColumn == 0) {
-			tagEditorModel.updateTagName(currentTag, editor.getText());
-		} else if (currentColumn == 1){
-			if (currentTag.getValueCount() > 1 && ! editor.getText().equals("")) {
-				tagEditorModel.updateTagValue(currentTag, editor.getText());
-			} else if (currentTag.getValueCount() <= 1) {
-				tagEditorModel.updateTagValue(currentTag, editor.getText());
-			}
-		}
-
-		return super.stopCellEditing();
-	}
-
-	/**
-	 * replies the {@link AutoCompletionList} this table cell editor synchronizes with
-	 * 
-	 * @return the auto completion list
-	 */
-	public AutoCompletionList getAutoCompletionList() {
-		return autoCompletionList;
-	}
-
-	/**
-	 * sets the {@link AutoCompletionList} this table cell editor synchronizes with
-	 * @param autoCompletionList the auto completion list
-	 */
-	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
-		this.autoCompletionList = autoCompletionList;
-		editor.setAutoCompletionList(autoCompletionList);
-	}
-
-	public void setAutoCompletionCache(AutoCompletionCache acCache) {
-		this.acCache = acCache;
-	}
-
-	public void autoCompletionItemSelected(String item) {
-		editor.setText(item);
-		editor.selectAll();
-		editor.requestFocus();
-	}
-
-	public TagFieldEditor getEditor() {
-		return editor;
-	}
-
-	/**
-	 * sets the tag editor model
-	 * 
-	 * @param tagEditorModel  the tag editor model
-	 */
-	public void setTagEditorModel(TagEditorModel tagEditorModel) {
-		this.tagEditorModel = tagEditorModel;
-	}
-}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellRenderer.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellRenderer.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellRenderer.java	(revision 20058)
@@ -9,11 +9,10 @@
 import java.util.logging.Logger;
 
-import javax.swing.BorderFactory;
-import javax.swing.ImageIcon;
 import javax.swing.JLabel;
 import javax.swing.JTable;
-import javax.swing.border.Border;
+import javax.swing.UIManager;
 import javax.swing.border.EmptyBorder;
 
+import org.openstreetmap.josm.gui.tagging.TagModel;
 import org.openstreetmap.josm.plugins.tageditor.preset.Item;
 import org.openstreetmap.josm.plugins.tageditor.preset.Tag;
@@ -29,13 +28,6 @@
 	
 	private static Logger logger = Logger.getLogger(TableCellRenderer.class.getName());
-	
-	public static final Color BG_COLOR_SELECTED = new Color(143,170,255);
 	public static final Color BG_COLOR_HIGHLIGHTED = new Color(255,255,204);
-	
-	public static final Border BORDER_EMPHASIZED = BorderFactory.createLineBorder(new Color(253,75,45));
-	
-	/** the icon displayed for deleting a tag */
-	private ImageIcon deleteIcon = null;
-	
+		
 	private Font fontStandard = null;
 	private Font fontItalic = null;
@@ -70,10 +62,8 @@
 			setText(tag.getValues().get(0));
 		} else if (tag.getValueCount() >  1) {
-			setText(tr("<multiple>"));
+			setText(tr("multiple"));
 			setFont(fontItalic);
 		}
 	}
-	
-	
 	
 	/**
@@ -121,5 +111,4 @@
 	}
 	
-	
 	/**
 	 * renders the background color. The default color is white. It is
@@ -132,11 +121,9 @@
 	 */
 	protected void renderBackgroundColor(TagModel tagModel, TagEditorModel model) {
-		setBackground(Color.WHITE); // standard color
+		setBackground(UIManager.getColor("Table.background")); 
 		if (belongsToSelectedPreset(tagModel, model)) {
 			setBackground(BG_COLOR_HIGHLIGHTED);
 		}
 	}
-	
-
 	
 	/**
@@ -154,4 +141,5 @@
 	public Component getTableCellRendererComponent(JTable table, Object value,
             boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
+		
 		resetRenderer();
 		
@@ -159,20 +147,19 @@
 		//
 		if (isSelected){
-			setBackground(BG_COLOR_SELECTED);
+			setBackground(UIManager.getColor("Table.selectionBackground"));
+			setForeground(UIManager.getColor("Table.selectionForeground"));
 		} else {
-			renderBackgroundColor(getModel(table).get(rowIndex), getModel(table));
+			setBackground(UIManager.getColor("Table.background"));
+			setForeground(UIManager.getColor("Table.foreground"));
 		}
-		
 
+		TagModel tagModel  = (TagModel)value;
 		switch(vColIndex) { 
-			case 0: renderTagName((TagModel)value); break;
-			case 1: renderTagValue((TagModel)value); break;
-			
-			default: throw new RuntimeException("unexpected index in switch statement");	
+			case 0: renderTagName(tagModel); break;
+			case 1: renderTagValue(tagModel); break;
 		}
+		renderBackgroundColor(tagModel, (TagEditorModel)table.getModel());
 		if (hasFocus && isSelected) {
 			if (table.getSelectedColumnCount() == 1 && table.getSelectedRowCount() == 1) {
-				boolean success = table.editCellAt(rowIndex, vColIndex);
-
 				if (table.getEditorComponent() != null) {
 					table.getEditorComponent().requestFocusInWindow();
@@ -182,5 +169,3 @@
 		return this;
 	}
-
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditor.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditor.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditor.java	(revision 20058)
@@ -2,11 +2,17 @@
 
 import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
 import java.util.logging.Logger;
 
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.JButton;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
-import javax.swing.ScrollPaneConstants;
-
-import org.openstreetmap.josm.gui.dialogs.relation.RunnableAction;
+import javax.swing.table.TableCellEditor;
+
 import org.openstreetmap.josm.gui.tagging.TagTable;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionCache;
@@ -52,10 +58,79 @@
 	private static final Logger logger = Logger.getLogger(TagEditor.class.getName());
 
-	private final TagEditorModel tagEditorModel;
+	private TagEditorModel tagEditorModel;
 	private TagTable tblTagEditor;
 	private PresetManager presetManager;
-	private AutoCompletionList autoCompletionList;
-
-
+	
+	 /**
+     * builds the panel with the button row
+     *
+     * @return the panel
+     */
+    protected JPanel buildButtonsPanel() {
+        JPanel pnl = new JPanel();
+        pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));
+
+        // add action
+        JButton btn;
+        pnl.add(btn = new JButton(tblTagEditor.getAddAction()));
+        btn.setMargin(new Insets(0,0,0,0));
+        tblTagEditor.addComponentNotStoppingCellEditing(btn);
+
+        // delete action
+        pnl.add(btn = new JButton(tblTagEditor.getDeleteAction()));
+        btn.setMargin(new Insets(0,0,0,0));
+        tblTagEditor.addComponentNotStoppingCellEditing(btn);
+        return pnl;
+    }
+    
+    public void addComponentNotStoppingCellEditing(Component c) {
+    	tblTagEditor.addComponentNotStoppingCellEditing(c);
+    }
+    
+    /**
+     * builds the GUI
+     */
+    protected JPanel buildTagEditorPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout());
+
+		DefaultListSelectionModel rowSelectionModel = new DefaultListSelectionModel();
+		DefaultListSelectionModel colSelectionModel = new DefaultListSelectionModel();
+		
+		tagEditorModel = new TagEditorModel(rowSelectionModel,colSelectionModel);
+		
+		// build the scrollable table for editing tag names and tag values
+		//
+		tblTagEditor = new TagTable(tagEditorModel, rowSelectionModel, colSelectionModel);
+		tblTagEditor.setTagCellEditor(new TagSpecificationAwareTagCellEditor());
+		TableCellRenderer renderer = new TableCellRenderer();
+		tblTagEditor.getColumnModel().getColumn(0).setCellRenderer(renderer);
+		tblTagEditor.getColumnModel().getColumn(1).setCellRenderer(renderer);
+
+		final JScrollPane scrollPane = new JScrollPane(tblTagEditor);
+		JPanel pnlTagTable = new JPanel(new BorderLayout());
+		pnlTagTable.add(scrollPane, BorderLayout.CENTER);
+
+        GridBagConstraints gc = new GridBagConstraints();
+
+        // -- buttons panel
+        //
+        gc.fill = GridBagConstraints.VERTICAL;
+        gc.weightx = 0.0;
+        gc.weighty = 1.0;
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        pnl.add(buildButtonsPanel(),gc);
+
+        // -- the panel with the editor table
+        //
+        gc.gridx = 1;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        gc.anchor = GridBagConstraints.CENTER;
+        pnl.add(pnlTagTable,gc);
+        
+        return pnl;
+    }
+    
 	/**
 	 * builds the GUI
@@ -64,26 +139,6 @@
 	protected void build() {
 		setLayout(new BorderLayout());
-
-		// build the scrollable table for editing tag names and tag values
-		//
-		tblTagEditor = new TagTable(tagEditorModel);
-		final JScrollPane scrollPane = new JScrollPane(tblTagEditor);
-		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
-		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
-		add(scrollPane, BorderLayout.CENTER);
-
-		// this adapters ensures that the width of the tag table columns is adjusted
-		// to the width of the scroll pane viewport. Also tried to overwrite
-		// getPreferredViewportSize() in JTable, but did not work.
-		//
-//		scrollPane.addComponentListener(
-//				new ComponentAdapter() {
-//					@Override public void componentResized(ComponentEvent e) {
-//						super.componentResized(e);
-//						Dimension d = scrollPane.getViewport().getExtentSize();
-//						tblTagEditor.adjustColumnWidth(d.width);
-//					}
-//				}
-//		);
+		
+		add(buildTagEditorPanel(), BorderLayout.CENTER);
 
 		// build the preset manager which shows a list of applied presets
@@ -94,16 +149,10 @@
 	}
 
-
 	/**
 	 * constructor
 	 */
 	public TagEditor() {
-		// creates a default model and a default cache
-		//
-		tagEditorModel = new TagEditorModel();
-
 		build();
 	}
-
 
 	/**
@@ -114,29 +163,5 @@
 		return tagEditorModel;
 	}
-
-	/**
-	 * sets the tag editor model
-	 * 
-	 * @param tagEditorModel the tag editor model
-	 */
-	public void setTagEditorModel(TagEditorModel tagEditorModel) {
-		tblTagEditor.setModel(tagEditorModel);
-		for (int i=0; i<=1; i++) {
-			TableCellEditor editor = (TableCellEditor)tblTagEditor.getColumnModel().getColumn(i).getCellEditor();
-			if (editor != null) {
-				editor.setTagEditorModel(tagEditorModel);
-			}
-		}
-		presetManager.setModel(tagEditorModel);
-	}
-
-	public RunnableAction getDeleteAction() {
-		return tblTagEditor.getDeleteAction();
-	}
-
-	public RunnableAction getAddAction() {
-		return tblTagEditor.getAddAction();
-	}
-
+	
 	public void clearSelection() {
 		tblTagEditor.getSelectionModel().clearSelection();
@@ -144,15 +169,10 @@
 
 	public void stopEditing() {
-		TableCellEditor editor = (TableCellEditor) tblTagEditor.getCellEditor();
+		TableCellEditor editor = tblTagEditor.getCellEditor();
 		if (editor != null) {
 			editor.stopCellEditing();
 		}
 	}
-
-	public AutoCompletionList getAutoCompletionList() {
-		return null;
-		//return ((org.openstreetmap.josm.gui.tagging.TagCellEditor)tblTagEditor.getCellEditor()).getAutoCompletionList();
-	}
-
+	
 	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
 		tblTagEditor.setAutoCompletionList(autoCompletionList);
@@ -164,5 +184,6 @@
 
 	public void autoCompletionItemSelected(String item) {
-		org.openstreetmap.josm.plugins.tageditor.editor.TableCellEditor editor = ((org.openstreetmap.josm.plugins.tageditor.editor.TableCellEditor)tblTagEditor.getCellEditor());
+		logger.info("autocompletion item selected ...");
+		TagSpecificationAwareTagCellEditor editor = (TagSpecificationAwareTagCellEditor)tblTagEditor.getCellEditor();
 		if (editor != null) {
 			editor.autoCompletionItemSelected(item);
@@ -173,3 +194,7 @@
 		tblTagEditor.requestFocusInCell(0,0);
 	}
+	
+	public TagEditorModel getModel() {
+		return tagEditorModel;
+	}
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditorModel.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditorModel.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditorModel.java	(revision 20058)
@@ -2,410 +2,38 @@
 package org.openstreetmap.josm.plugins.tageditor.editor;
 
-import static org.openstreetmap.josm.tools.I18n.trn;
+import java.util.ArrayList;
 
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Comparator;
-import java.util.List;
 import java.util.logging.Logger;
 
 import javax.swing.DefaultComboBoxModel;
-import javax.swing.table.AbstractTableModel;
+import javax.swing.DefaultListSelectionModel;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.ChangePropertyCommand;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.tagging.TagModel;
 import org.openstreetmap.josm.plugins.tageditor.preset.Item;
 import org.openstreetmap.josm.plugins.tageditor.preset.Tag;
 import org.openstreetmap.josm.plugins.tageditor.tagspec.KeyValuePair;
+import static org.openstreetmap.josm.tools.I18n.trn;
 
 /**
- * TagEditorModel is a table model.
  * 
- * 
- * @author gubaer
- *
  */
 @SuppressWarnings("serial")
-public class TagEditorModel extends AbstractTableModel {
+public class TagEditorModel extends org.openstreetmap.josm.gui.tagging.TagEditorModel  {
 	static private final Logger logger = Logger.getLogger(TagEditorModel.class.getName());
-
-	static public final String PROP_DIRTY = TagEditorModel.class.getName() + ".dirty";
-
-	/** the list holding the tags */
-	private  ArrayList<TagModel> tags = null;
-	private  ArrayList<Item> items = null;
-
-	/** indicates whether the model is dirty */
-	private boolean dirty =  false;
-	private PropertyChangeSupport propChangeSupport = null;
-
+	
 	private DefaultComboBoxModel appliedPresets = null;
-
 
 	/**
 	 * constructor
 	 */
-	public TagEditorModel(){
-		tags = new ArrayList<TagModel>();
-		items = new ArrayList<Item>();
-		propChangeSupport = new PropertyChangeSupport(this);
+	public TagEditorModel(DefaultListSelectionModel rowSelectionModel, DefaultListSelectionModel colSelectionModel){
+		super(rowSelectionModel, colSelectionModel);
 		appliedPresets = new DefaultComboBoxModel();
 	}
-
-	public void addPropertyChangeListener(PropertyChangeListener listener) {
-		propChangeSupport.addPropertyChangeListener(listener);
-	}
-
-	public void removeProperyChangeListener(PropertyChangeListener listener) {
-		propChangeSupport.removePropertyChangeListener(listener);
-	}
-
-	protected void fireDirtyStateChanged(final boolean oldValue, final boolean newValue) {
-		propChangeSupport.firePropertyChange(PROP_DIRTY, oldValue, newValue);
-	}
-
-	protected void setDirty(boolean newValue) {
-		boolean oldValue = dirty;
-		dirty = newValue;
-		if (oldValue != newValue) {
-			fireDirtyStateChanged(oldValue, newValue);
-		}
-	}
-
-	public int getColumnCount() {
-		return 2;
-	}
-
-	public int getRowCount() {
-		return tags.size();
-	}
-
-	public Object getValueAt(int rowIndex, int columnIndex) {
-		if (rowIndex >= getRowCount())
-			throw new IndexOutOfBoundsException("unexpected rowIndex: rowIndex=" + rowIndex);
-
-		TagModel tag = tags.get(rowIndex);
-		switch(columnIndex) {
-		case 0:
-		case 1: return tag;
-
-		default:
-			throw new IndexOutOfBoundsException("unexpected columnIndex: columnIndex=" + columnIndex);
-		}
-	}
-
-
-	/**
-	 * removes all tags in the model
-	 */
-	public void clear() {
-		tags.clear();
-		items.clear();
-		setDirty(true);
-		fireTableDataChanged();
-	}
-
-	/**
-	 * adds a tag to the model
-	 * 
-	 * @param tag the tag. Must not be null.
-	 * 
-	 * @exception IllegalArgumentException thrown, if tag is null
-	 */
-	public void add(TagModel tag) {
-		if (tag == null)
-			throw new IllegalArgumentException("argument 'tag' must not be null");
-		tags.add(tag);
-		setDirty(true);
-		fireTableDataChanged();
-	}
-
-
-	public void prepend(TagModel tag) {
-		if (tag == null)
-			throw new IllegalArgumentException("argument 'tag' must not be null");
-		tags.add(0, tag);
-		setDirty(true);
-		fireTableDataChanged();
-	}
-
-
-	/**
-	 * adds a tag given by a name/value pair to the tag editor model.
-	 * 
-	 * If there is no tag with name <code>name</name> yet, a new {@link TagModel} is created
-	 * and append to this model.
-	 * 
-	 * If there is a tag with name <code>name</name>, <code>value</code> is merged to the list
-	 * of values for this tag.
-	 * 
-	 * @param name the name; converted to "" if null
-	 * @param value the value; converted to "" if null
-	 */
-	public void add(String name, String value) {
-		name = (name == null) ? "" : name;
-		value = (value == null) ? "" : value;
-
-		TagModel tag = get(name);
-		if (tag == null) {
-			tag = new TagModel(name, value);
-			add(tag);
-		} else {
-			tag.addValue(value);
-		}
-		setDirty(true);
-	}
-
-
-	/**
-	 * replies the tag with name <code>name</code>; null, if no such tag exists
-	 * @param name the tag name
-	 * @return the tag with name <code>name</code>; null, if no such tag exists
-	 */
-	public TagModel get(String name) {
-		name = (name == null) ? "" : name;
-		for (TagModel tag : tags) {
-			if (tag.getName().equals(name))
-				return tag;
-		}
-		return null;
-	}
-
-	public TagModel get(int idx) {
-		TagModel tagModel = tags.get(idx);
-		return tagModel;
-	}
-
-
-
-	@Override public boolean isCellEditable(int row, int col) {
-		// all cells are editable
-		return true;
-	}
-
-
-	/**
-	 * deletes the names of the tags given by tagIndices
-	 * 
-	 * @param tagIndices a list of tag indices
-	 */
-	public void deleteTagNames(int [] tagIndices) {
-		if (tags == null)
-			return;
-		for (int tagIdx : tagIndices) {
-			TagModel tag = tags.get(tagIdx);
-			if (tag != null) {
-				tag.setName("");
-			}
-		}
-		fireTableDataChanged();
-		setDirty(true);
-	}
-
-	/**
-	 * deletes the values of the tags given by tagIndices
-	 * 
-	 * @param tagIndices the lit of tag indices
-	 */
-	public void deleteTagValues(int [] tagIndices) {
-		if (tags == null)
-			return;
-		for (int tagIdx : tagIndices) {
-			TagModel tag = tags.get(tagIdx);
-			if (tag != null) {
-				tag.setValue("");
-			}
-		}
-		fireTableDataChanged();
-		setDirty(true);
-	}
-
-	/**
-	 * deletes the tags given by tagIndices
-	 * 
-	 * @param tagIndices the list of tag indices
-	 */
-	public void deleteTags(int [] tagIndices) {
-		if (tags == null)
-			return;
-		ArrayList<TagModel> toDelete = new ArrayList<TagModel>();
-		for (int tagIdx : tagIndices) {
-			TagModel tag = tags.get(tagIdx);
-			if (tag != null) {
-				toDelete.add(tag);
-			}
-		}
-		for (TagModel tag : toDelete) {
-			tags.remove(tag);
-		}
-		fireTableDataChanged();
-		setDirty(true);
-	}
-
-
-	/**
-	 * creates a new tag and appends it to the model
-	 */
-	public void appendNewTag() {
-		TagModel tag = new TagModel();
-		tags.add(tag);
-		fireTableDataChanged();
-		setDirty(true);
-	}
-
-	/**
-	 * makes sure the model includes at least one (empty) tag
-	 */
-	public void ensureOneTag() {
-		if (tags.size() == 0) {
-			appendNewTag();
-		}
-	}
-
-	/**
-	 * initializes the model with the tags in the current JOSM selection
-	 */
-	public void initFromJOSMSelection() {
-		Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
-		clear();
-		for (OsmPrimitive element : selection) {
-			for (String key : element.keySet()) {
-				String value = element.get(key);
-				add(key,value);
-			}
-		}
-		sort();
-		setDirty(false);
-	}
-
-
-	/**
-	 * checks whether the tag model includes a tag with a given key
-	 * 
-	 * @param key  the key
-	 * @return true, if the tag model includes the tag; false, otherwise
-	 */
-	public boolean includesTag(String key) {
-		if (key == null) return false;
-		for (TagModel tag : tags) {
-			if (tag.getName().equals(key))
-				return true;
-		}
-		return false;
-	}
-
-
-	protected Command createUpdateTagCommand(Collection<OsmPrimitive> primitives, TagModel tag) {
-
-		// tag still holds an unchanged list of different values for the same key.
-		// no property change command required
-		if (tag.getValueCount() > 1)
-			return null;
-
-		// tag name holds an empty key. Don't apply it to the selection.
-		//
-		if (tag.getName().trim().equals(""))
-			return null;
-
-		String newkey = tag.getName();
-		String newvalue = tag.getValue();
-
-		ChangePropertyCommand command = new ChangePropertyCommand(primitives,newkey, newvalue);
-		return command;
-	}
-
-	protected Command createDeleteTagsCommand(Collection<OsmPrimitive> primitives) {
-
-		List<String> currentkeys = getKeys();
-		ArrayList<Command> commands = new ArrayList<Command>();
-
-		for (OsmPrimitive primitive : primitives) {
-			if (primitive.getKeys() == null) {
-				continue;
-			}
-			for (String oldkey : primitive.keySet()) {
-				if (!currentkeys.contains(oldkey)) {
-					ChangePropertyCommand deleteCommand =
-						new ChangePropertyCommand(primitive,oldkey,null);
-					commands.add(deleteCommand);
-				}
-			}
-		}
-
-		SequenceCommand command = new SequenceCommand(
-				trn("Remove old keys from up to {0} object", "Remove old keys from up to {0} objects", primitives.size(), primitives.size()),
-				commands
-		);
-
-		return command;
-	}
-
-	/**
-	 * updates the tags of the primitives in the current selection with the
-	 * values in the current tag model
-	 * 
-	 */
-	public void updateJOSMSelection() {
-		ArrayList<Command> commands = new ArrayList<Command>();
-		Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
-		if (selection == null)
-			return;
-		for (TagModel tag : tags) {
-			Command command = createUpdateTagCommand(selection,tag);
-			if (command != null) {
-				commands.add(command);
-			}
-		}
-		Command deleteCommand = createDeleteTagsCommand(selection);
-		if (deleteCommand != null) {
-			commands.add(deleteCommand);
-		}
-
-		SequenceCommand command = new SequenceCommand(
-				trn("Updating properties of up to {0} object", "Updating properties of up to {0} objects", selection.size(), selection.size()),
-				commands
-		);
-
-		// executes the commands and adds them to the undo/redo chains
-		Main.main.undoRedo.add(command);
-	}
-
-
-	/**
-	 * replies the list of keys of the tags managed by this model
-	 * 
-	 * @return the list of keys managed by this model
-	 */
-	public List<String> getKeys() {
-		ArrayList<String> keys = new ArrayList<String>();
-		for (TagModel tag: tags) {
-			if (!tag.getName().trim().equals("")) {
-				keys.add(tag.getName());
-			}
-		}
-		return keys;
-	}
-
-	/**
-	 * sorts the current tags according alphabetical order of names
-	 */
-	protected void sort() {
-		java.util.Collections.sort(
-				tags,
-				new Comparator<TagModel>() {
-					public int compare(TagModel self, TagModel other) {
-						return self.getName().compareTo(other.getName());
-					}
-				}
-		);
-	}
-
-
-
 
 	/**
@@ -516,34 +144,49 @@
 		fireTableDataChanged();
 	}
+	
+	/**
+	 * updates the tags of the primitives in the current selection with the
+	 * values in the current tag model
+	 * 
+	 */
+	public void updateJOSMSelection() {
+		ArrayList<Command> commands = new ArrayList<Command>();
+		Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
+		if (selection == null)
+			return;
+		for (TagModel tag : tags) {
+			Command command = createUpdateTagCommand(selection,tag);
+			if (command != null) {
+				commands.add(command);
+			}
+		}
+		Command deleteCommand = createDeleteTagsCommand(selection);
+		if (deleteCommand != null) {
+			commands.add(deleteCommand);
+		}
 
+		SequenceCommand command = new SequenceCommand(
+				trn("Updating properties of up to {0} object", "Updating properties of up to {0} objects", selection.size(), selection.size()),
+				commands
+		);
 
+		// executes the commands and adds them to the undo/redo chains
+		Main.main.undoRedo.add(command);
+	}
+	
 	/**
-	 * updates the name of a tag and sets the dirty state to  true if
-	 * the new name is different from the old name.
-	 * 
-	 * @param tag   the tag
-	 * @param newName  the new name
+	 * initializes the model with the tags in the current JOSM selection
 	 */
-	public void updateTagName(TagModel tag, String newName) {
-		String oldName = tag.getName();
-		tag.setName(newName);
-		if (! newName.equals(oldName)) {
-			setDirty(true);
+	public void initFromJOSMSelection() {
+		Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
+		clear();
+		for (OsmPrimitive element : selection) {
+			for (String key : element.keySet()) {
+				String value = element.get(key);
+				add(key,value);
+			}
 		}
-	}
-
-	/**
-	 * updates the value value of a tag and sets the dirty state to true if the
-	 * new name is different from the old name
-	 * 
-	 * @param tag  the tag
-	 * @param newValue  the new value
-	 */
-	public void updateTagValue(TagModel tag, String newValue) {
-		String oldValue = tag.getValue();
-		tag.setValue(newValue);
-		if (! newValue.equals(oldValue)) {
-			setDirty(true);
-		}
+		sort();
+		setDirty(false);
 	}
 }
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagFieldEditor.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagFieldEditor.java	(revision 20057)
+++ 	(revision )
@@ -1,146 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.tageditor.editor;
-
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.util.logging.Logger;
-
-import javax.swing.JTextField;
-import javax.swing.text.AttributeSet;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-import javax.swing.text.PlainDocument;
-
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionList;
-
-
-
-/**
- * TagFieldEditor is an editor for tag names or tag values. It supports auto completion
- * from a list of auto completion items.
- *
- */
-public class TagFieldEditor extends JTextField  {
-
-	static private Logger logger = Logger.getLogger(TagFieldEditor.class.getName());
-
-
-	/**
-	 * The document model for the editor
-	 */
-	class AutoCompletionDocument extends PlainDocument {
-
-		/**
-		 * inserts a string at a specific position
-		 * 
-		 */
-		@Override
-		public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
-			if (autoCompletionList == null) {
-				super.insertString(offs, str, a);
-				return;
-			}
-			// if the current offset isn't at the end of the document we don't autocomplete.
-			// If a highlighted autocompleted suffix was present and we get here Swing has
-			// already removed it from the document. getLength() therefore doesn't include the
-			// autocompleted suffix.
-			//
-			if (offs < getLength()) {
-				super.insertString(offs, str, a);
-				return;
-			}
-
-			String currentText = getText(0, getLength());
-			String prefix = currentText.substring(0, offs);
-			autoCompletionList.applyFilter(prefix+str);
-			if (autoCompletionList.getFilteredSize()>0) {
-				// there are matches. Insert the new text and highlight the
-				// auto completed suffix
-				//
-				String matchingString = autoCompletionList.getFilteredItem(0).getValue();
-				remove(0,getLength());
-				super.insertString(0,matchingString,a);
-
-				// highlight from end to insert position
-				//
-				setCaretPosition(getLength());
-				moveCaretPosition(offs + str.length());
-			} else {
-				// there are no matches. Insert the new text, do not highlight
-				//
-				String newText = prefix + str;
-				remove(0,getLength());
-				super.insertString(0,newText,a);
-				setCaretPosition(getLength());
-			}
-		}
-
-
-	}
-
-
-	/** the auto completion list user input is matched against */
-	protected AutoCompletionList autoCompletionList = null;
-
-	/**
-	 * creates the default document model for this editor
-	 * 
-	 */
-	@Override
-	protected Document createDefaultModel() {
-		return new AutoCompletionDocument();
-	}
-
-	/**
-	 * constructor
-	 */
-	public TagFieldEditor() {
-
-		addFocusListener(
-				new FocusAdapter() {
-					@Override public void focusGained(FocusEvent e) {
-						selectAll();
-						applyFilter(getText());
-					}
-				}
-		);
-
-		addKeyListener(
-				new KeyAdapter() {
-
-					@Override
-					public void keyReleased(KeyEvent e) {
-						if (getText().equals("")) {
-							applyFilter("");
-						}
-					}
-				}
-		);
-	}
-
-	protected void applyFilter(String filter) {
-		if (autoCompletionList != null) {
-			autoCompletionList.applyFilter(filter);
-		}
-	}
-
-	/**
-	 * 
-	 * @return the auto completion list; may be null, if no auto completion list is set
-	 */
-	public AutoCompletionList getAutoCompletionList() {
-		return autoCompletionList;
-	}
-
-	/**
-	 * sets the auto completion list
-	 * @param autoCompletionList the auto completion list; if null, auto completion is
-	 *   disabled
-	 */
-	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
-		this.autoCompletionList = autoCompletionList;
-	}
-
-}
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagModel.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagModel.java	(revision 20057)
+++ 	(revision )
@@ -1,130 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.tageditor.editor;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TagModel {
-	
-	/** the name of the tag */
-	private String name = null;
-	
-	/** the list of values */
-	private ArrayList<String> values = null;
-	
-	/**
-	 * constructor
-	 */
-	public TagModel() {
-		values = new ArrayList<String>();
-		setName("");
-		setValue("");
-	}
-	
-	/**
-	 * constructor 
-	 * @param name the tag name 
-	 */
-	public TagModel(String name) {
-		this();
-		setName(name);
-	}
-	
-	/**
-	 * constructor 
-	 * 
-	 * @param name the tag name 
-	 * @param value the tag value 
-	 */
-	public TagModel(String name, String value) {
-		this();
-		setName(name);
-		setValue(value);
-	}
-	
-	/**
-	 * sets the name. Converts name to "" if null.
-	 * @param name the tag name 
-	 */
-	public void setName(String name) {
-		name = (name == null) ? "" : name;
-		this.name = name; 
-	}
-	
-	/** 
-	 * @return the tag name 
-	 */
-	public String getName(){
-		return name;
-	}
-	
-	/**
-	 * removes all values from the list of values 
-	 */
-	public void clearValues() {
-		this.values.clear();
-	}
-	
-	/**
-	 * sets a unique value for this tag. Converts value to "", if null.
-	 * @param value the value. 
-	 */
-	public void setValue(String value) {
-		value = (value == null) ? "" : value;
-		clearValues();
-		this.values.add(value);
-	}
-	
-	/**
-	 * 
-	 * @param value the value to be checked; converted to "" if null 
-	 * @return true, if the values of this tag include <code>value</code>; false otherwise 
-	 */
-	public boolean hasValue(String value) {
-		value = (value == null) ? "" : value;
-		return values.contains(value);
-	}
-	
-	public void addValue(String value) {
-		value = (value == null) ? "" : value;
-		if (hasValue(value)) {
-			return; 
-		}
-		values.add(value);
-	}
-	
-	
-	/**
-	 * removes a value from the list of values. Converts value to "" if null
-	 * @param value the value 
-	 */
-	public void removeValue(String value){
-		value = (value == null) ? "" : value; 
-		values.remove(value);
-	}	
-	
-	public List<String> getValues() {
-		return values;
-	}
-	
-	public String getValue() {
-		if (getValueCount() == 0) {
-			return "";
-		} else if (getValueCount() == 1) {
-			return values.get(0);
-		} else {
-			StringBuilder sb = new StringBuilder();			
-			for (int i =0; i < values.size(); i++) {
-				sb.append(values.get(i));
-				if (i + 1 < values.size()) {
-					sb.append(";");
-				}
-			}
-			return sb.toString();
-		}
-	}
-	
-	public int getValueCount() {
-		return values.size();
-	}
-}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagSpecificationAwareTagCellEditor.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagSpecificationAwareTagCellEditor.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagSpecificationAwareTagCellEditor.java	(revision 20058)
@@ -0,0 +1,101 @@
+package org.openstreetmap.josm.plugins.tageditor.editor;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.openstreetmap.josm.gui.tagging.TagCellEditor;
+import org.openstreetmap.josm.gui.tagging.TagModel;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
+import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionContext;
+import org.openstreetmap.josm.plugins.tageditor.tagspec.TagSpecifications;
+
+public class TagSpecificationAwareTagCellEditor extends TagCellEditor{
+	private static final Logger logger = Logger.getLogger(TagCellEditor.class.getName());
+
+	/**
+	 * initializes  the auto completion list when the table cell editor starts
+	 * to edit the key of a tag. In this case the auto completion list is
+	 * initialized with the set of standard key values and the set of current key
+	 * values from the the current JOSM data set. Keys already present in the
+	 * current tag model are removed from the auto completion list.
+	 * 
+	 * @param model  the tag editor model
+	 * @param currentTag  the current tag
+	 */
+	protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) {		
+		if (getAutoCompletionList() == null) {
+			logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
+			return;
+		}
+
+		autoCompletionList.clear();
+
+		// add the list of standard keys
+		//
+		try {
+			//autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
+		} catch(Exception e) {
+			logger.log(Level.WARNING, "failed to initialize auto completion list with standard keys.", e);
+		}
+
+		// add the list of keys in the current data set
+		//
+		acCache.populateWithKeys(autoCompletionList, false /* don't append */);
+		AutoCompletionContext context = new AutoCompletionContext();
+		try {
+			context.initFromJOSMSelection();
+			autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
+		} catch(Exception e) {
+			System.out.println("Warning: failed to initialize auto completion list with tag specification keys. Exception was: " + e.toString());
+			e.printStackTrace();
+		}
+
+		// remove the keys already present in the current tag model
+		//
+		for (String key : model.getKeys()) {
+			if (! key.equals(currentTag.getName())) {
+				autoCompletionList.remove(key);
+			}
+		}
+		autoCompletionList.fireTableDataChanged();
+	}
+
+	/**
+	 * initializes the auto completion list when the cell editor starts to edit
+	 * a tag value. In this case the auto completion list is initialized with the
+	 * set of standard values for a given key and the set of values present in the
+	 * current data set for the given key.
+	 * 
+	 * @param forKey the key
+	 */
+	protected void initAutoCompletionListForValues(String forKey) {
+
+		if (autoCompletionList == null) {
+			logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
+			return;
+		}
+		autoCompletionList.clear();
+		acCache.populateWithTagValues(autoCompletionList, forKey, false /* don't append */);
+		
+		AutoCompletionContext context = new AutoCompletionContext();
+		try {
+			context.initFromJOSMSelection();
+			autoCompletionList.add(TagSpecifications.getInstance().getLabelsForAutoCompletion(forKey, context));
+		} catch(Exception e) {
+			System.out.println("Warning: failed to initialize auto completion list with tag specification values. Exception was: " + e.toString());
+			e.printStackTrace();
+		}
+
+		//  add the list of possible values for a key from the current selection
+		//
+		if (currentTag.getValueCount() > 1) {
+			for (String value : currentTag.getValues()) {
+				//logger.info("adding ac item " + value + " with priority IN_SELECTION");;
+				autoCompletionList.add(
+						new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION)
+				);
+			}
+		}
+	}
+}
Index: plications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagTable.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagTable.java	(revision 20057)
+++ 	(revision )
@@ -1,444 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.plugins.tageditor.editor;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.AWTException;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.event.ActionEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.JComponent;
-import javax.swing.JTable;
-import javax.swing.KeyStroke;
-import javax.swing.ListSelectionModel;
-import javax.swing.SwingUtilities;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.table.DefaultTableColumnModel;
-import javax.swing.table.TableColumn;
-import javax.swing.table.TableColumnModel;
-import javax.swing.table.TableModel;
-
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionCache;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionList;
-
-/**
- * This is the tabular editor component for OSM tags.
- * 
- */
-@SuppressWarnings("serial")
-public class TagTable extends JTable  {
-	private static Logger logger = Logger.getLogger(TagTable.class.getName());
-
-	/** the table cell editor used by this table */
-	private TableCellEditor editor = null;
-
-	/**
-	 * The table has three columns. In the first column, we display error and
-	 * warning indications. The second column is used for editing rendering and
-	 * editing tag keys, the third for rendering and editing tag values.
-	 * 
-	 * @author gubaer
-	 *
-	 */
-	static class TagTableColumnModel extends DefaultTableColumnModel {
-
-		public TagTableColumnModel() {
-			TableColumn col = null;
-			TableCellRenderer renderer = new TableCellRenderer();
-
-			// column 0 - tag key
-			col = new TableColumn(0);
-			col.setHeaderValue(tr("Key"));
-			col.setResizable(true);
-			col.setCellRenderer(renderer);
-			addColumn(col);
-
-			// column 1 - tag value
-			col = new TableColumn(1);
-			col.setHeaderValue(tr("Value"));
-			col.setResizable(true);
-			col.setCellRenderer(renderer);
-			addColumn(col);
-
-		}
-	}
-
-	/**
-	 * Action to be run when the user navigates to the next cell in the table,
-	 * for instance by pressing TAB or ENTER. The action alters the standard
-	 * navigation path from cell to cell:
-	 * <ul>
-	 *   <li>it jumps over cells in the first column</li>
-	 *   <li>it automatically add a new empty row when the user leaves the
-	 *   last cell in the table</li>
-	 * <ul>
-	 * 
-	 * @author gubaer
-	 *
-	 */
-	class SelectNextColumnCellAction extends AbstractAction  {
-		public void actionPerformed(ActionEvent e) {
-			run();
-		}
-
-		public void run() {
-			int col = getSelectedColumn();
-			int row = getSelectedRow();
-			if (getCellEditor() != null) {
-				getCellEditor().stopCellEditing();
-			}
-
-			if (col == 0) {
-				col++;
-			} else if (col == 1 && row < getRowCount()-1) {
-				col=0;
-				row++;
-			} else if (col == 1 && row == getRowCount()-1){
-				// we are at the end. Append an empty row and move the focus
-				// to its second column
-				TagEditorModel model = (TagEditorModel)getModel();
-				model.appendNewTag();
-				col=0;
-				row++;
-			}
-			changeSelection(row, col, false, false);
-
-		}
-	}
-
-
-	/**
-	 * Action to be run when the user navigates to the previous cell in the table,
-	 * for instance by pressing Shift-TAB
-	 * 
-	 * @author gubaer
-	 *
-	 */
-	class SelectPreviousColumnCellAction extends AbstractAction  {
-
-		public void actionPerformed(ActionEvent e) {
-
-			int col = getSelectedColumn();
-			int row = getSelectedRow();
-			if (getCellEditor() != null) {
-				getCellEditor().stopCellEditing();
-			}
-
-
-			if (col == 0 && row == 0) {
-				// change nothing
-			} else if (col == 1) {
-				col--;
-			} else {
-				col = 1;
-				row--;
-			}
-			changeSelection(row, col, false, false);
-		}
-	}
-
-	/**
-	 * Action to be run when the user invokes a delete action on the table, for
-	 * instance by pressing DEL.
-	 * 
-	 * Depending on the shape on the current selection the action deletes individual
-	 * values or entire tags from the model.
-	 * 
-	 * If the current selection consists of cells in the second column only, the keys of
-	 * the selected tags are set to the empty string.
-	 * 
-	 * If the current selection consists of cell in the third column only, the values of the
-	 * selected tags are set to the empty string.
-	 * 
-	 *  If the current selection consists of cells in the second and the third column,
-	 *  the selected tags are removed from the model.
-	 * 
-	 *  This action listens to the table selection. It becomes enabled when the selection
-	 *  is non-empty, otherwise it is disabled.
-	 * 
-	 *
-	 */
-	class DeleteAction extends RunnableAction implements ListSelectionListener {
-
-		/**
-		 * delete a selection of tag names
-		 */
-		protected void deleteTagNames() {
-			int[] rows = getSelectedRows();
-			TagEditorModel model = (TagEditorModel)getModel();
-			model.deleteTagNames(rows);
-		}
-
-		/**
-		 * delete a selection of tag values
-		 */
-		protected void deleteTagValues() {
-			int[] rows = getSelectedRows();
-			TagEditorModel model = (TagEditorModel)getModel();
-			model.deleteTagValues(rows);
-		}
-
-		/**
-		 * delete a selection of tags
-		 */
-		protected void deleteTags() {
-			int[] rows = getSelectedRows();
-			TagEditorModel model = (TagEditorModel)getModel();
-			model.deleteTags(rows);
-		}
-
-		/**
-		 * constructor
-		 */
-		public DeleteAction() {
-			putValue(Action.NAME, tr("Delete"));
-			getSelectionModel().addListSelectionListener(this);
-			getColumnModel().getSelectionModel().addListSelectionListener(this);
-		}
-
-		@Override
-		public void run() {
-			if (!isEnabled())
-				return;
-			getCellEditor().stopCellEditing();
-			if (getSelectedColumnCount() == 1) {
-				if (getSelectedColumn() == 0) {
-					deleteTagNames();
-				} else if (getSelectedColumn() == 1) {
-					deleteTagValues();
-				} else
-					// should not happen
-					//
-					throw new IllegalStateException("unexpected selected column: getSelectedColumn() is " + getSelectedColumn());
-			} else if (getSelectedColumnCount() == 2) {
-				deleteTags();
-			}
-			TagEditorModel model = (TagEditorModel)getModel();
-			if (model.getRowCount() == 0) {
-				model.ensureOneTag();
-				requestFocusInCell(0, 0);
-			}
-		}
-
-		/**
-		 * listens to the table selection model
-		 */
-		public void valueChanged(ListSelectionEvent e) {
-			if (isEditing() && getSelectedColumnCount() == 1 && getSelectedRowCount() == 1) {
-				setEnabled(false);
-			} else if (!isEditing() && getSelectedColumnCount() == 1 && getSelectedRowCount() == 1) {
-				setEnabled(true);
-			} else if (getSelectedColumnCount() > 1 || getSelectedRowCount() > 1) {
-				setEnabled(true);
-			} else {
-				setEnabled(false);
-			}
-		}
-	}
-
-	/**
-	 * Action to be run when the user adds a new tag.
-	 * 
-	 *
-	 */
-	class AddAction extends RunnableAction {
-
-		public AddAction() {
-			putValue(Action.NAME, tr("Add"));
-		}
-
-		@Override
-		public void run() {
-			getCellEditor().stopCellEditing();
-			((TagEditorModel)getModel()).appendNewTag();
-			final int rowIdx = getModel().getRowCount()-1;
-			requestFocusInCell(rowIdx, 0);
-		}
-	}
-
-
-	/** the delete action */
-	private RunnableAction deleteAction = null;
-
-	/** the add action */
-	private RunnableAction addAction = null;
-
-	/**
-	 * 
-	 * @return the delete action used by this table
-	 */
-	public RunnableAction getDeleteAction() {
-		return deleteAction;
-	}
-
-	public RunnableAction getAddAction() {
-		return addAction;
-	}
-
-	/**
-	 * initialize the table
-	 */
-	protected void init() {
-		setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
-		setCellSelectionEnabled(true);
-		setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
-
-		// make ENTER behave like TAB
-		//
-		getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
-		.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "selectNextColumnCell");
-
-		// install custom navigation actions
-		//
-		getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
-		getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
-
-		// create a delete action. Installing this action in the input and action map
-		// didn't work. We therefore handle delete requests in processKeyBindings(...)
-		//
-		deleteAction = new DeleteAction();
-
-		// create the add action
-		//
-		addAction = new AddAction();
-		getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
-		.put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, KeyEvent.CTRL_MASK), "addTag");
-		getActionMap().put("addTag", addAction);
-
-		// create the table cell editor and set it to key and value columns
-		//
-		editor = new TableCellEditor();
-		editor.setTagEditorModel((TagEditorModel)getModel());
-		getColumnModel().getColumn(0).setCellEditor(editor);
-		getColumnModel().getColumn(1).setCellEditor(editor);
-		
-		
-	}
-
-	/**
-	 * constructor
-	 * 
-	 * @param model
-	 * @param columnModel
-	 */
-	public TagTable(TableModel model) {
-		super(model, new TagTableColumnModel());
-		init();
-	}
-
-	/**
-	 * adjusts the width of the columns for the tag name and the tag value
-	 * to the width of the scroll panes viewport.
-	 * 
-	 * Note: {@see #getPreferredScrollableViewportSize()} did not work as expected
-	 * 
-	 * @param scrollPaneWidth the width of the scroll panes viewport
-	 */
-	public void adjustColumnWidth(int scrollPaneWidth) {
-		TableColumnModel tcm = getColumnModel();
-		int width = scrollPaneWidth;
-		width = width / 2;
-		if (width > 0) {
-			tcm.getColumn(0).setMinWidth(width);
-			tcm.getColumn(0).setMaxWidth(width);
-			tcm.getColumn(1).setMinWidth(width);
-			tcm.getColumn(1).setMaxWidth(width);
-		}
-	}
-
-	@Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
-			int condition, boolean pressed) {
-
-		// handle delete key
-		//
-		if (e.getKeyCode() == KeyEvent.VK_DELETE) {
-			getDeleteAction().run();
-		}
-		return super.processKeyBinding(ks, e, condition, pressed);
-	}
-
-	/**
-	 * @param autoCompletionList
-	 */
-	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
-		if (autoCompletionList == null)
-			return;
-		if (editor != null) {
-			editor.setAutoCompletionList(autoCompletionList);
-		}
-	}
-
-	public void setAutoCompletionCache(AutoCompletionCache acCache) {
-		if (acCache == null) {
-			logger.warning("argument acCache should not be null. Aborting.");
-			return;
-		}
-		if (editor != null) {
-			editor.setAutoCompletionCache(acCache);
-		}
-	}
-
-	public AutoCompletionList getAutoCompletionList() {
-		if (editor != null)
-			return editor.getAutoCompletionList();
-		else
-			return null;
-	}
-
-
-	public TableCellEditor getTableCellEditor() {
-		return editor;
-	}
-
-
-	public void  addOKAccelatorListener(KeyListener l) {
-		addKeyListener(l);
-		if (editor == null) {
-			logger.warning("editor is null. cannot register OK accelator listener.");
-		}
-		editor.getEditor().addKeyListener(l);
-	}
-
-
-	public void requestFocusInCell(final int row, final int col) {
-
-		// the following code doesn't work reliably. If a table cell
-		// gains focus using editCellAt() and requestFocusInWindow()
-		// it isn't possible to tab to the next table cell using TAB or
-		// ENTER. Don't know why.
-		//
-		// tblTagEditor.editCellAt(row, col);
-		// if (tblTagEditor.getEditorComponent() != null) {
-		//	tblTagEditor.getEditorComponent().requestFocusInWindow();
-		// }
-
-		// this is a workaround. We move the focus to the respective cell
-		// using a simulated mouse click. In this case one can tab out of
-		// the cell using TAB and ENTER.
-		//
-		Rectangle r = getCellRect(row,col, false);
-		Point p = new Point(r.x + r.width/2, r.y + r.height/2);
-		SwingUtilities.convertPointToScreen(p, this);
-		// logger.info("simulating mouse click event at point " + p.toString());
-
-		try {
-			Robot robot = new Robot();
-			robot.mouseMove(p.x,p.y);
-			robot.mousePress(InputEvent.BUTTON1_MASK);
-			robot.mouseRelease(InputEvent.BUTTON1_MASK);
-		} catch(AWTException e) {
-			logger.log(Level.SEVERE, "failed to simulate mouse click event at (" + r.x + "," + r.y + "). Exception: " + e.toString());
-			return;
-		}
-	}
-}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionCache.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionCache.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionCache.java	(revision 20058)
@@ -0,0 +1,114 @@
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+/**
+ * AutoCompletionCache temporarily holds a cache of keys with a list of
+ * possible auto completion values for each key.
+ * 
+ * The cache can initialize itself from the current JOSM data set such that
+ * <ol>
+ *   <li>any key used in a tag in the data set is part of the key list in the cache</li>
+ *   <li>any value used in a tag for a specific key is part of the autocompletion list of
+ *     this key</li>
+ * </ol>
+ * 
+ * Building up auto completion lists should not
+ * slow down tabbing from input field to input field. Looping through the complete
+ * data set in order to build up the auto completion list for a specific input
+ * field is not efficient enough, hence this cache.
+ *
+ */
+public class AutoCompletionCache {
+
+	/** the cache */
+	private HashMap<String, ArrayList<String>> cache;
+
+	/**
+	 * constructor
+	 */
+	public AutoCompletionCache() {
+		cache = new HashMap<String, ArrayList<String>>();
+	}
+
+	/**
+	 * make sure, <code>key</code> is in the cache
+	 * 
+	 * @param key  the key
+	 */
+	protected void cacheKey(String key) {
+		if (cache.containsKey(key))
+			return;
+		else {
+			cache.put(key, new ArrayList<String>());
+		}
+	}
+
+	/**
+	 * make sure, value is one of the auto completion values allowed for key
+	 * 
+	 * @param key the key
+	 * @param value the value
+	 */
+	protected void cacheValue(String key, String value) {
+		cacheKey(key);
+		ArrayList<String> values = cache.get(key);
+		if (!values.contains(value)) {
+			values.add(value);
+		}
+	}
+
+	/**
+	 * make sure, the keys and values of all tags held by primitive are
+	 * in the auto completion cache
+	 * 
+	 * @param primitive an OSM primitive
+	 */
+	protected void cachePrimitive(OsmPrimitive primitive) {
+		for (String key: primitive.keySet()) {
+			String value = primitive.get(key);
+			cacheValue(key, value);
+		}
+	}
+
+	/**
+	 * initializes the cache from the current JOSM dataset {@link OsmPrimitive}s.
+	 * 
+	 */
+	public void initFromJOSMDataset() {
+		cache = new HashMap<String, ArrayList<String>>();
+		Collection<OsmPrimitive> ds = Main.main.getCurrentDataSet().allNonDeletedPrimitives();
+		for (OsmPrimitive primitive : ds) {
+			cachePrimitive(primitive);
+		}
+	}
+
+	/**
+	 * replies the keys held by the cache
+	 * 
+	 * @return the list of keys held by the cache
+	 */
+	public List<String> getKeys() {
+		return new ArrayList<String>(cache.keySet());
+	}
+
+
+	/**
+	 * replies the auto completion values allowed for a specific key. Replies
+	 * an empty list if key is null or if key is not in {@link #getKeys()}.
+	 * 
+	 * @param key
+	 * @return the list of auto completion values
+	 */
+	public List<String> getValues(String key) {
+		if (!cache.containsKey(key))
+			return new ArrayList<String>();
+		else
+			return cache.get(key);
+	}
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionItemPritority.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionItemPritority.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionItemPritority.java	(revision 20058)
@@ -0,0 +1,26 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+public enum AutoCompletionItemPritority implements Comparable<AutoCompletionItemPritority> {
+
+	/** indicates that a value is in the current selection */
+	IS_IN_SELECTION,
+
+	/** indicates that this is a standard value, i.e. a standard tag name 
+	 *  or a standard value for a given tag name 
+	 */
+	IS_IN_STANDARD,
+	
+	
+	/**
+	 * indicates that this is an arbitrary value from the data set, i.e. 
+	 * the value of a tag name=xxx
+	 */
+	IS_IN_DATASET,
+	
+	/** unknown priority. This is the lowest priority. */
+	UNKNOWN
+	
+	
+	
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionList.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionList.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionList.java	(revision 20058)
@@ -0,0 +1,286 @@
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.JTable;
+import javax.swing.table.AbstractTableModel;
+
+
+/**
+ * AutoCompletionList manages a list of {@see AutoCompletionListItem}s.
+ * 
+ * The list is sorted, items with higher priority first, then according to lexicographic order
+ * on the value of the {@see AutoCompletionListItem}.
+ * 
+ * AutoCompletionList maintains two views on the list of {@see AutoCompletionListItem}s.
+ * <ol>
+ *   <li>the bare, unfiltered view which includes all items</li>
+ *   <li>a filtered view, which includes only items which match a current filter expression</li>
+ * </ol>
+ * 
+ * AutoCompletionList is an {@link AbstractTableModel} which serves the list of filtered
+ * items to a {@link JTable}.
+ * 
+ * @author gubaer
+ */
+public class AutoCompletionList extends AbstractTableModel {
+
+	/** the bare list of AutoCompletionItems */
+	private ArrayList<AutoCompletionListItem> list = null;
+	/**  the filtered list of AutoCompletionItems */
+	private ArrayList<AutoCompletionListItem> filtered = null;
+	/** the filter expression */
+	private String filter = null;
+
+	/**
+	 * constructor
+	 */
+	public AutoCompletionList() {
+		list = new ArrayList<AutoCompletionListItem>();
+		filtered = new ArrayList<AutoCompletionListItem>();
+	}
+
+
+	/**
+	 * applies a filter expression to the list of {@see AutoCompletionListItem}s.
+	 * 
+	 * The matching criterion is a case insensitive substring match.
+	 * 
+	 * @param filter  the filter expression; must not be null
+	 * 
+	 * @exception IllegalArgumentException thrown, if filter is null
+	 */
+	public void applyFilter(String filter) {
+		if (filter == null)
+			throw new IllegalArgumentException("argument 'filter' must not be null");
+		this.filter = filter;
+		filter();
+	}
+
+	/**
+	 * clears the current filter
+	 * 
+	 */
+	public void clearFilter() {
+		filter = null;
+		filter();
+	}
+
+	/**
+	 * @return the current filter expression; null, if no filter expression is set
+	 */
+	public String getFilter() {
+		return filter;
+	}
+
+
+	/**
+	 * adds an AutoCompletionListItem to the list. Only adds the item if it
+	 * is not null and if not in the list yet.
+	 * 
+	 * @param item the item
+	 */
+	public void add(AutoCompletionListItem item) {
+		if (item == null)
+			return;
+		appendOrUpdatePriority(item);
+		sort();
+		filter();
+	}
+
+
+	/**
+	 * adds another AutoCompletionList to this list. An item is only
+	 * added it is not null and if it does not exist in the list yet.
+	 * 
+	 * @param other another auto completion list; must not be null
+	 * @exception IllegalArgumentException thrown, if other is null
+	 */
+	public void add(AutoCompletionList other) {
+		if (other == null)
+			throw new IllegalArgumentException("argument 'other' must not be null");
+		for (AutoCompletionListItem item : other.list) {
+			appendOrUpdatePriority(item);
+		}
+		sort();
+		filter();
+	}
+
+
+	/**
+	 * adds a list of AutoCompletionListItem to this list. Only items which
+	 * are not null and which do not exist yet in the list are added.
+	 * 
+	 * @param other a list of AutoCompletionListItem; must not be null
+	 * @exception IllegalArgumentException thrown, if other is null
+	 */
+	public void add(List<AutoCompletionListItem> other) {
+		if (other == null)
+			throw new IllegalArgumentException("argument 'other' must not be null");
+		for (AutoCompletionListItem toadd : other) {
+			appendOrUpdatePriority(toadd);
+		}
+		sort();
+		filter();
+	}
+
+	protected void appendOrUpdatePriority(AutoCompletionListItem toadd) {
+		AutoCompletionListItem item = lookup(toadd.getValue());
+		if (item == null) {
+			// new item does not exist yet. Add it to the list
+			//
+			list.add(toadd);
+		} else {
+			// new item already exists. Update priority if necessary
+			//
+			if (toadd.getPriority().compareTo(item.getPriority()) < 0) {
+				item.setPriority(toadd.getPriority());
+			}
+		}
+	}
+
+	/**
+	 * checks whether a specific item is already in the list. Matches for the
+	 * the value <strong>and</strong> the priority of the item
+	 * 
+	 * @param item the item to check
+	 * @return true, if item is in the list; false, otherwise
+	 */
+	public boolean contains(AutoCompletionListItem item) {
+		if (item == null)
+			return false;
+		return list.contains(item);
+	}
+
+	/**
+	 * checks whether an item with the given value is already in the list. Ignores
+	 * priority of the items.
+	 * 
+	 * @param value the value of an auto completion item
+	 * @return true, if value is in the list; false, otherwise
+	 */
+	public boolean contains(String value) {
+		if (value == null)
+			return false;
+		for (AutoCompletionListItem item: list) {
+			if (item.getValue().equals(value))
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * 
+	 * @param value a specific value
+	 * @return  the auto completion item for this value; null, if there is no
+	 *   such auto completion item
+	 */
+	public AutoCompletionListItem lookup(String value) {
+		if (value == null)
+			return null;
+		for (AutoCompletionListItem item : list) {
+			if (item.getValue().equals(value))
+				return item;
+		}
+		return null;
+	}
+
+
+	/**
+	 * removes the auto completion item with key <code>key</code>
+	 * @param key  the key;
+	 */
+	public void remove(String key) {
+		if (key == null)
+			return;
+		for (int i=0;i< list.size();i++) {
+			AutoCompletionListItem item = list.get(i);
+			if (item.getValue().equals(key)) {
+				list.remove(i);
+				return;
+			}
+		}
+	}
+
+
+
+	/**
+	 * sorts the list
+	 */
+	protected void sort() {
+		Collections.sort(list);
+	}
+
+	protected void filter() {
+		filtered.clear();
+		if (filter == null) {
+			// Collections.copy throws an exception "Source does not fit in dest"
+			// Collections.copy(filtered, list);
+			filtered.ensureCapacity(list.size());
+			for (AutoCompletionListItem item: list) {
+				filtered.add(item);
+			}
+			return;
+		}
+
+		// apply the pattern to list of possible values. If it matches, add the
+		// value to the list of filtered values
+		//
+		for (AutoCompletionListItem item : list) {
+			if (item.getValue().startsWith(filter)) {
+				filtered.add(item);
+			}
+		}
+
+		fireTableDataChanged();
+	}
+
+	/**
+	 * replies the number of filtered items
+	 * 
+	 * @return the number of filtered items
+	 */
+	public int getFilteredSize() {
+		return this.filtered.size();
+	}
+
+	/**
+	 * replies the idx-th item from the list of filtered items
+	 * @param idx the index; must be in the range 0<= idx < {@see #getFilteredSize()}
+	 * @return the item
+	 * 
+	 * @exception IndexOutOfBoundsException thrown, if idx is out of bounds
+	 */
+	public AutoCompletionListItem getFilteredItem(int idx) {
+		if (idx < 0 || idx >= getFilteredSize())
+			throw new IndexOutOfBoundsException("idx out of bounds. idx=" + idx);
+		return filtered.get(idx);
+	}
+
+
+	/**
+	 * removes all elements from the auto completion list
+	 * 
+	 */
+	public void clear() {
+		list.clear();
+		fireTableDataChanged();
+	}
+
+
+	public int getColumnCount() {
+		return 1;
+	}
+
+	public int getRowCount() {
+
+		return list == null ? 0 : getFilteredSize();
+	}
+
+	public Object getValueAt(int rowIndex, int columnIndex) {
+		return list == null ? null : getFilteredItem(rowIndex);
+	}
+
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionListItem.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionListItem.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/AutoCompletionListItem.java	(revision 20058)
@@ -0,0 +1,132 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
+
+
+/**
+ * Represents an entry in the list of auto completion values.
+ * 
+ *  An AutoCompletionListItem has a <em>priority</em> and a <em>value</em>.
+ * 
+ *  The priority helps to sort the auto completion items according to their importance. For instance,
+ *  in an auto completion list for tag names, standard tag names would be assigned a higher
+ *  priority than arbitrary tag names present in the current data set. There are three priority levels,
+ *  {@see AutoCompletionItemPritority}.
+ *
+ * The value is a string which will be displayed in the auto completion list.
+ * 
+ * @author gubaer
+ *
+ */
+public class AutoCompletionListItem implements Comparable<AutoCompletionListItem>{
+
+	/** the pritority of this item */
+	private  AutoCompletionItemPritority priority;
+	/** the value of this item */
+	private String value;
+
+	/**
+	 * constructor
+	 */
+	public AutoCompletionListItem() {
+		value = "";
+		priority = AutoCompletionItemPritority.UNKNOWN;
+	}
+
+	public AutoCompletionListItem(String value, AutoCompletionItemPritority priority) {
+		this.value = value;
+		this.priority = priority;
+	}
+
+	/**
+	 * 
+	 * @return the priority
+	 */
+	public AutoCompletionItemPritority getPriority() {
+		return priority;
+	}
+
+	/**
+	 * sets the priority
+	 * @param priority  the priority
+	 */
+	public void setPriority(AutoCompletionItemPritority priority) {
+		this.priority = priority;
+	}
+
+	/**
+	 * 
+	 * @return the value
+	 */
+	public String getValue() {
+		return value;
+	}
+
+	/**
+	 * sets the value
+	 * @param value the value; must not be null
+	 * @exception IllegalArgumentException thrown, if value if null
+	 */
+	public void setValue(String value) {
+		if (value == null)
+			throw new IllegalArgumentException("argument 'value' must not be null");
+		this.value = value;
+	}
+
+	@Override public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append("<AutoCompletionItemPritority: ");
+		sb.append("value='");
+		sb.append(value);
+		sb.append("',");
+		sb.append("priority='");
+		sb.append(priority.toString());
+		sb.append("'>");
+		return sb.toString();
+	}
+
+	@Override public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result
+		+ ((priority == null) ? 0 : priority.hashCode());
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+	@Override public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final AutoCompletionListItem other = (AutoCompletionListItem)obj;
+		if (priority == null) {
+			if (other.priority != null)
+				return false;
+		} else if (!priority.equals(other.priority))
+			return false;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+
+
+	public int compareTo(AutoCompletionListItem other) {
+		int ret = this.priority.compareTo(other.priority);
+		if (ret != 0)
+			return ret;
+		else
+			return this.value.compareTo(other.value);
+	}
+
+
+
+
+
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/RunnableAction.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/RunnableAction.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/RunnableAction.java	(revision 20058)
@@ -0,0 +1,17 @@
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+public abstract class RunnableAction extends AbstractAction implements Runnable {
+
+	public RunnableAction() {
+	}
+
+	public abstract void run();
+
+	public void actionPerformed(ActionEvent arg0) {
+		run();
+	}
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TableCellEditor.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TableCellEditor.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TableCellEditor.java	(revision 20058)
@@ -0,0 +1,242 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import java.awt.Component;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractCellEditor;
+import javax.swing.JTable;
+
+import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionContext;
+import org.openstreetmap.josm.plugins.tageditor.ac.IAutoCompletionListListener;
+import org.openstreetmap.josm.plugins.tageditor.editor.TagEditorModel;
+import org.openstreetmap.josm.plugins.tageditor.tagspec.TagSpecifications;
+
+
+/**
+ * This is the table cell editor for the tag editor dialog.
+ * 
+ *
+ */
+@SuppressWarnings("serial")
+public class TableCellEditor extends AbstractCellEditor implements javax.swing.table.TableCellEditor, IAutoCompletionListListener{
+
+	/** the logger object */
+	static private Logger logger = Logger.getLogger(TableCellEditor.class.getName());
+
+	private TagFieldEditor editor = null;
+	private TagModel currentTag = null;
+	private TagEditorModel tagEditorModel = null;
+	private int currentColumn = 0;
+
+	/** the cache of auto completion items derived from the current JOSM data set */
+	private AutoCompletionCache acCache = null;
+
+	/** user input is matched against this list of auto completion items */
+	private AutoCompletionList autoCompletionList = null;
+
+	/**
+	 * constructor
+	 */
+	public TableCellEditor() {
+		editor = new TagFieldEditor();
+		acCache = new AutoCompletionCache();
+	}
+
+	/**
+	 * initializes  the auto completion list when the table cell editor starts
+	 * to edit the key of a tag. In this case the auto completion list is
+	 * initialized with the set of standard key values and the set of current key
+	 * values from the the current JOSM data set. Keys already present in the
+	 * current tag model are removed from the auto completion list.
+	 * 
+	 * @param model  the tag editor model
+	 * @param currentTag  the current tag
+	 */
+	protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) {
+		AutoCompletionContext context = new AutoCompletionContext();
+		context.initFromJOSMSelection();
+
+		if (autoCompletionList == null) {
+			logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
+			return;
+		}
+
+		autoCompletionList.clear();
+
+		// add the list of standard keys
+		//
+		try {
+			//autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
+		} catch(Exception e) {
+			logger.log(Level.WARNING, "failed to initialize auto completion list with standard keys.", e);
+		}
+
+		// add the list of keys in the current data set
+		//
+		for (String key : acCache.getKeys()) {
+//			autoCompletionList.add(
+//					new AutoCompletionListItem(key, AutoCompletionItemPritority.IS_IN_DATASET)
+//			);
+		}
+
+		// remove the keys already present in the current tag model
+		//
+		for (String key : model.getKeys()) {
+			if (! key.equals(currentTag.getName())) {
+				autoCompletionList.remove(key);
+			}
+		}
+		autoCompletionList.fireTableDataChanged();
+	}
+
+
+	/**
+	 * initializes the auto completion list when the cell editor starts to edit
+	 * a tag value. In this case the auto completion list is initialized with the
+	 * set of standard values for a given key and the set of values present in the
+	 * current data set for the given key.
+	 * 
+	 * @param forKey the key
+	 */
+	protected void initAutoCompletionListForValues(String forKey) {
+
+		if (autoCompletionList == null) {
+			logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
+			return;
+		}
+		autoCompletionList.clear();
+		AutoCompletionContext context = new AutoCompletionContext();
+		context.initFromJOSMSelection();
+
+		// add the list of standard values for the given key
+		//
+		try {
+//			autoCompletionList.add(
+//					TagSpecifications.getInstance().getLabelsForAutoCompletion(forKey, context)
+//			);
+		} catch(Exception e){
+			logger.log(Level.WARNING, "failed to initialize auto completion list with standard values", e);
+		}
+
+		for (String value : acCache.getValues(forKey)) {
+//			autoCompletionList.add(
+//					new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_DATASET)
+//			);
+		}
+
+		//  add the list of possible values for a key from the current selection
+		//
+		if (currentTag.getValueCount() > 1) {
+			for (String value : currentTag.getValues()) {
+				//logger.info("adding ac item " + value + " with priority IN_SELECTION");;
+//				autoCompletionList.add(
+//						new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION)
+//				);
+			}
+		}
+	}
+
+
+	/**
+	 * replies the table cell editor
+	 */
+	public Component getTableCellEditorComponent(JTable table,
+			Object value, boolean isSelected, int row, int column) {
+		currentTag = (TagModel) value;
+
+		if (column == 0) {
+			editor.setText(currentTag.getName());
+			currentColumn = 0;
+			TagEditorModel model = (TagEditorModel)table.getModel();
+			initAutoCompletionListForKeys(model, currentTag);
+			return editor;
+		} else if (column == 1) {
+
+			if (currentTag.getValueCount() == 0) {
+				editor.setText("");
+			} else if (currentTag.getValueCount() == 1) {
+				editor.setText(currentTag.getValues().get(0));
+			} else {
+				editor.setText("");
+			}
+			currentColumn = 1;
+			initAutoCompletionListForValues(currentTag.getName());
+			return editor;
+		} else {
+			logger.warning("column this table cell editor is requested for is out of range. column=" + column);
+			return null;
+		}
+	}
+
+	public Object getCellEditorValue() {
+		return editor.getText();
+	}
+
+	@Override
+	public void cancelCellEditing() {
+		super.cancelCellEditing();
+	}
+
+	@Override
+	public boolean stopCellEditing() {
+		if (tagEditorModel == null) {
+			logger.warning("no tag editor model set. Can't update edited values. Please set tag editor model first");
+			return super.stopCellEditing();
+		}
+
+		if (currentColumn == 0) {
+			//tagEditorModel.updateTagName(currentTag, editor.getText());
+		} else if (currentColumn == 1){
+			if (currentTag.getValueCount() > 1 && ! editor.getText().equals("")) {
+				//tagEditorModel.updateTagValue(currentTag, editor.getText());
+			} else if (currentTag.getValueCount() <= 1) {
+				//tagEditorModel.updateTagValue(currentTag, editor.getText());
+			}
+		}
+
+		return super.stopCellEditing();
+	}
+
+	/**
+	 * replies the {@link AutoCompletionList} this table cell editor synchronizes with
+	 * 
+	 * @return the auto completion list
+	 */
+	public AutoCompletionList getAutoCompletionList() {
+		return autoCompletionList;
+	}
+
+	/**
+	 * sets the {@link AutoCompletionList} this table cell editor synchronizes with
+	 * @param autoCompletionList the auto completion list
+	 */
+	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
+		this.autoCompletionList = autoCompletionList;
+		editor.setAutoCompletionList(autoCompletionList);
+	}
+
+	public void setAutoCompletionCache(AutoCompletionCache acCache) {
+		this.acCache = acCache;
+	}
+
+	public void autoCompletionItemSelected(String item) {
+		editor.setText(item);
+		editor.selectAll();
+		editor.requestFocus();
+	}
+
+	public TagFieldEditor getEditor() {
+		return editor;
+	}
+
+	/**
+	 * sets the tag editor model
+	 * 
+	 * @param tagEditorModel  the tag editor model
+	 */
+	public void setTagEditorModel(TagEditorModel tagEditorModel) {
+		this.tagEditorModel = tagEditorModel;
+	}
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagFieldEditor.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagFieldEditor.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagFieldEditor.java	(revision 20058)
@@ -0,0 +1,145 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.logging.Logger;
+
+import javax.swing.JTextField;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.PlainDocument;
+
+
+
+
+/**
+ * TagFieldEditor is an editor for tag names or tag values. It supports auto completion
+ * from a list of auto completion items.
+ *
+ */
+public class TagFieldEditor extends JTextField  {
+
+	static private Logger logger = Logger.getLogger(TagFieldEditor.class.getName());
+
+
+	/**
+	 * The document model for the editor
+	 */
+	class AutoCompletionDocument extends PlainDocument {
+
+		/**
+		 * inserts a string at a specific position
+		 * 
+		 */
+		@Override
+		public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+			if (autoCompletionList == null) {
+				super.insertString(offs, str, a);
+				return;
+			}
+			// if the current offset isn't at the end of the document we don't autocomplete.
+			// If a highlighted autocompleted suffix was present and we get here Swing has
+			// already removed it from the document. getLength() therefore doesn't include the
+			// autocompleted suffix.
+			//
+			if (offs < getLength()) {
+				super.insertString(offs, str, a);
+				return;
+			}
+
+			String currentText = getText(0, getLength());
+			String prefix = currentText.substring(0, offs);
+			autoCompletionList.applyFilter(prefix+str);
+			if (autoCompletionList.getFilteredSize()>0) {
+				// there are matches. Insert the new text and highlight the
+				// auto completed suffix
+				//
+				String matchingString = autoCompletionList.getFilteredItem(0).getValue();
+				remove(0,getLength());
+				super.insertString(0,matchingString,a);
+
+				// highlight from end to insert position
+				//
+				setCaretPosition(getLength());
+				moveCaretPosition(offs + str.length());
+			} else {
+				// there are no matches. Insert the new text, do not highlight
+				//
+				String newText = prefix + str;
+				remove(0,getLength());
+				super.insertString(0,newText,a);
+				setCaretPosition(getLength());
+			}
+		}
+
+
+	}
+
+
+	/** the auto completion list user input is matched against */
+	protected AutoCompletionList autoCompletionList = null;
+
+	/**
+	 * creates the default document model for this editor
+	 * 
+	 */
+	@Override
+	protected Document createDefaultModel() {
+		return new AutoCompletionDocument();
+	}
+
+	/**
+	 * constructor
+	 */
+	public TagFieldEditor() {
+
+		addFocusListener(
+				new FocusAdapter() {
+					@Override public void focusGained(FocusEvent e) {
+						selectAll();
+						applyFilter(getText());
+					}
+				}
+		);
+
+		addKeyListener(
+				new KeyAdapter() {
+
+					@Override
+					public void keyReleased(KeyEvent e) {
+						if (getText().equals("")) {
+							applyFilter("");
+						}
+					}
+				}
+		);
+	}
+
+	protected void applyFilter(String filter) {
+		if (autoCompletionList != null) {
+			autoCompletionList.applyFilter(filter);
+		}
+	}
+
+	/**
+	 * 
+	 * @return the auto completion list; may be null, if no auto completion list is set
+	 */
+	public AutoCompletionList getAutoCompletionList() {
+		return autoCompletionList;
+	}
+
+	/**
+	 * sets the auto completion list
+	 * @param autoCompletionList the auto completion list; if null, auto completion is
+	 *   disabled
+	 */
+	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
+		this.autoCompletionList = autoCompletionList;
+	}
+
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagModel.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagModel.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagModel.java	(revision 20058)
@@ -0,0 +1,130 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TagModel {
+	
+	/** the name of the tag */
+	private String name = null;
+	
+	/** the list of values */
+	private ArrayList<String> values = null;
+	
+	/**
+	 * constructor
+	 */
+	public TagModel() {
+		values = new ArrayList<String>();
+		setName("");
+		setValue("");
+	}
+	
+	/**
+	 * constructor 
+	 * @param name the tag name 
+	 */
+	public TagModel(String name) {
+		this();
+		setName(name);
+	}
+	
+	/**
+	 * constructor 
+	 * 
+	 * @param name the tag name 
+	 * @param value the tag value 
+	 */
+	public TagModel(String name, String value) {
+		this();
+		setName(name);
+		setValue(value);
+	}
+	
+	/**
+	 * sets the name. Converts name to "" if null.
+	 * @param name the tag name 
+	 */
+	public void setName(String name) {
+		name = (name == null) ? "" : name;
+		this.name = name; 
+	}
+	
+	/** 
+	 * @return the tag name 
+	 */
+	public String getName(){
+		return name;
+	}
+	
+	/**
+	 * removes all values from the list of values 
+	 */
+	public void clearValues() {
+		this.values.clear();
+	}
+	
+	/**
+	 * sets a unique value for this tag. Converts value to "", if null.
+	 * @param value the value. 
+	 */
+	public void setValue(String value) {
+		value = (value == null) ? "" : value;
+		clearValues();
+		this.values.add(value);
+	}
+	
+	/**
+	 * 
+	 * @param value the value to be checked; converted to "" if null 
+	 * @return true, if the values of this tag include <code>value</code>; false otherwise 
+	 */
+	public boolean hasValue(String value) {
+		value = (value == null) ? "" : value;
+		return values.contains(value);
+	}
+	
+	public void addValue(String value) {
+		value = (value == null) ? "" : value;
+		if (hasValue(value)) {
+			return; 
+		}
+		values.add(value);
+	}
+	
+	
+	/**
+	 * removes a value from the list of values. Converts value to "" if null
+	 * @param value the value 
+	 */
+	public void removeValue(String value){
+		value = (value == null) ? "" : value; 
+		values.remove(value);
+	}	
+	
+	public List<String> getValues() {
+		return values;
+	}
+	
+	public String getValue() {
+		if (getValueCount() == 0) {
+			return "";
+		} else if (getValueCount() == 1) {
+			return values.get(0);
+		} else {
+			StringBuilder sb = new StringBuilder();			
+			for (int i =0; i < values.size(); i++) {
+				sb.append(values.get(i));
+				if (i + 1 < values.size()) {
+					sb.append(";");
+				}
+			}
+			return sb.toString();
+		}
+	}
+	
+	public int getValueCount() {
+		return values.size();
+	}
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagTable.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagTable.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/old/TagTable.java	(revision 20058)
@@ -0,0 +1,444 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.tageditor.editor.old;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.AWTException;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.KeyStroke;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
+
+import org.openstreetmap.josm.plugins.tageditor.editor.TableCellRenderer;
+import org.openstreetmap.josm.plugins.tageditor.editor.TagEditorModel;
+
+/**
+ * This is the tabular editor component for OSM tags.
+ * 
+ */
+@SuppressWarnings("serial")
+public class TagTable extends JTable  {
+	private static Logger logger = Logger.getLogger(TagTable.class.getName());
+
+	/** the table cell editor used by this table */
+	private TableCellEditor editor = null;
+
+	/**
+	 * The table has three columns. In the first column, we display error and
+	 * warning indications. The second column is used for editing rendering and
+	 * editing tag keys, the third for rendering and editing tag values.
+	 * 
+	 * @author gubaer
+	 *
+	 */
+	static class TagTableColumnModel extends DefaultTableColumnModel {
+
+		public TagTableColumnModel() {
+			TableColumn col = null;
+			TableCellRenderer renderer = new TableCellRenderer();
+
+			// column 0 - tag key
+			col = new TableColumn(0);
+			col.setHeaderValue(tr("Key"));
+			col.setResizable(true);
+			col.setCellRenderer(renderer);
+			addColumn(col);
+
+			// column 1 - tag value
+			col = new TableColumn(1);
+			col.setHeaderValue(tr("Value"));
+			col.setResizable(true);
+			col.setCellRenderer(renderer);
+			addColumn(col);
+
+		}
+	}
+
+	/**
+	 * Action to be run when the user navigates to the next cell in the table,
+	 * for instance by pressing TAB or ENTER. The action alters the standard
+	 * navigation path from cell to cell:
+	 * <ul>
+	 *   <li>it jumps over cells in the first column</li>
+	 *   <li>it automatically add a new empty row when the user leaves the
+	 *   last cell in the table</li>
+	 * <ul>
+	 * 
+	 * @author gubaer
+	 *
+	 */
+	class SelectNextColumnCellAction extends AbstractAction  {
+		public void actionPerformed(ActionEvent e) {
+			run();
+		}
+
+		public void run() {
+			int col = getSelectedColumn();
+			int row = getSelectedRow();
+			if (getCellEditor() != null) {
+				getCellEditor().stopCellEditing();
+			}
+
+			if (col == 0) {
+				col++;
+			} else if (col == 1 && row < getRowCount()-1) {
+				col=0;
+				row++;
+			} else if (col == 1 && row == getRowCount()-1){
+				// we are at the end. Append an empty row and move the focus
+				// to its second column
+				TagEditorModel model = (TagEditorModel)getModel();
+				model.appendNewTag();
+				col=0;
+				row++;
+			}
+			changeSelection(row, col, false, false);
+
+		}
+	}
+
+
+	/**
+	 * Action to be run when the user navigates to the previous cell in the table,
+	 * for instance by pressing Shift-TAB
+	 * 
+	 * @author gubaer
+	 *
+	 */
+	class SelectPreviousColumnCellAction extends AbstractAction  {
+
+		public void actionPerformed(ActionEvent e) {
+
+			int col = getSelectedColumn();
+			int row = getSelectedRow();
+			if (getCellEditor() != null) {
+				getCellEditor().stopCellEditing();
+			}
+
+
+			if (col == 0 && row == 0) {
+				// change nothing
+			} else if (col == 1) {
+				col--;
+			} else {
+				col = 1;
+				row--;
+			}
+			changeSelection(row, col, false, false);
+		}
+	}
+
+	/**
+	 * Action to be run when the user invokes a delete action on the table, for
+	 * instance by pressing DEL.
+	 * 
+	 * Depending on the shape on the current selection the action deletes individual
+	 * values or entire tags from the model.
+	 * 
+	 * If the current selection consists of cells in the second column only, the keys of
+	 * the selected tags are set to the empty string.
+	 * 
+	 * If the current selection consists of cell in the third column only, the values of the
+	 * selected tags are set to the empty string.
+	 * 
+	 *  If the current selection consists of cells in the second and the third column,
+	 *  the selected tags are removed from the model.
+	 * 
+	 *  This action listens to the table selection. It becomes enabled when the selection
+	 *  is non-empty, otherwise it is disabled.
+	 * 
+	 *
+	 */
+	class DeleteAction extends RunnableAction implements ListSelectionListener {
+
+		/**
+		 * delete a selection of tag names
+		 */
+		protected void deleteTagNames() {
+			int[] rows = getSelectedRows();
+			TagEditorModel model = (TagEditorModel)getModel();
+			model.deleteTagNames(rows);
+		}
+
+		/**
+		 * delete a selection of tag values
+		 */
+		protected void deleteTagValues() {
+			int[] rows = getSelectedRows();
+			TagEditorModel model = (TagEditorModel)getModel();
+			model.deleteTagValues(rows);
+		}
+
+		/**
+		 * delete a selection of tags
+		 */
+		protected void deleteTags() {
+			int[] rows = getSelectedRows();
+			TagEditorModel model = (TagEditorModel)getModel();
+			model.deleteTags(rows);
+		}
+
+		/**
+		 * constructor
+		 */
+		public DeleteAction() {
+			putValue(Action.NAME, tr("Delete"));
+			getSelectionModel().addListSelectionListener(this);
+			getColumnModel().getSelectionModel().addListSelectionListener(this);
+		}
+
+		@Override
+		public void run() {
+			if (!isEnabled())
+				return;
+			getCellEditor().stopCellEditing();
+			if (getSelectedColumnCount() == 1) {
+				if (getSelectedColumn() == 0) {
+					deleteTagNames();
+				} else if (getSelectedColumn() == 1) {
+					deleteTagValues();
+				} else
+					// should not happen
+					//
+					throw new IllegalStateException("unexpected selected column: getSelectedColumn() is " + getSelectedColumn());
+			} else if (getSelectedColumnCount() == 2) {
+				deleteTags();
+			}
+			TagEditorModel model = (TagEditorModel)getModel();
+			if (model.getRowCount() == 0) {
+				model.ensureOneTag();
+				requestFocusInCell(0, 0);
+			}
+		}
+
+		/**
+		 * listens to the table selection model
+		 */
+		public void valueChanged(ListSelectionEvent e) {
+			if (isEditing() && getSelectedColumnCount() == 1 && getSelectedRowCount() == 1) {
+				setEnabled(false);
+			} else if (!isEditing() && getSelectedColumnCount() == 1 && getSelectedRowCount() == 1) {
+				setEnabled(true);
+			} else if (getSelectedColumnCount() > 1 || getSelectedRowCount() > 1) {
+				setEnabled(true);
+			} else {
+				setEnabled(false);
+			}
+		}
+	}
+
+	/**
+	 * Action to be run when the user adds a new tag.
+	 * 
+	 *
+	 */
+	class AddAction extends RunnableAction {
+
+		public AddAction() {
+			putValue(Action.NAME, tr("Add"));
+		}
+
+		@Override
+		public void run() {
+			getCellEditor().stopCellEditing();
+			((TagEditorModel)getModel()).appendNewTag();
+			final int rowIdx = getModel().getRowCount()-1;
+			requestFocusInCell(rowIdx, 0);
+		}
+	}
+
+
+	/** the delete action */
+	private RunnableAction deleteAction = null;
+
+	/** the add action */
+	private RunnableAction addAction = null;
+
+	/**
+	 * 
+	 * @return the delete action used by this table
+	 */
+	public RunnableAction getDeleteAction() {
+		return deleteAction;
+	}
+
+	public RunnableAction getAddAction() {
+		return addAction;
+	}
+
+	/**
+	 * initialize the table
+	 */
+	protected void init() {
+		setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+		setCellSelectionEnabled(true);
+		setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+
+		// make ENTER behave like TAB
+		//
+		getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+		.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "selectNextColumnCell");
+
+		// install custom navigation actions
+		//
+		getActionMap().put("selectNextColumnCell", new SelectNextColumnCellAction());
+		getActionMap().put("selectPreviousColumnCell", new SelectPreviousColumnCellAction());
+
+		// create a delete action. Installing this action in the input and action map
+		// didn't work. We therefore handle delete requests in processKeyBindings(...)
+		//
+		deleteAction = new DeleteAction();
+
+		// create the add action
+		//
+		addAction = new AddAction();
+		getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
+		.put(KeyStroke.getKeyStroke(KeyEvent.VK_ADD, KeyEvent.CTRL_MASK), "addTag");
+		getActionMap().put("addTag", addAction);
+
+		// create the table cell editor and set it to key and value columns
+		//
+		editor = new TableCellEditor();
+		editor.setTagEditorModel((TagEditorModel)getModel());
+		getColumnModel().getColumn(0).setCellEditor(editor);
+		getColumnModel().getColumn(1).setCellEditor(editor);
+		
+		
+	}
+
+	/**
+	 * constructor
+	 * 
+	 * @param model
+	 * @param columnModel
+	 */
+	public TagTable(TableModel model) {
+		super(model, new TagTableColumnModel());
+		init();
+	}
+
+	/**
+	 * adjusts the width of the columns for the tag name and the tag value
+	 * to the width of the scroll panes viewport.
+	 * 
+	 * Note: {@see #getPreferredScrollableViewportSize()} did not work as expected
+	 * 
+	 * @param scrollPaneWidth the width of the scroll panes viewport
+	 */
+	public void adjustColumnWidth(int scrollPaneWidth) {
+		TableColumnModel tcm = getColumnModel();
+		int width = scrollPaneWidth;
+		width = width / 2;
+		if (width > 0) {
+			tcm.getColumn(0).setMinWidth(width);
+			tcm.getColumn(0).setMaxWidth(width);
+			tcm.getColumn(1).setMinWidth(width);
+			tcm.getColumn(1).setMaxWidth(width);
+		}
+	}
+
+	@Override protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
+			int condition, boolean pressed) {
+
+		// handle delete key
+		//
+		if (e.getKeyCode() == KeyEvent.VK_DELETE) {
+			getDeleteAction().run();
+		}
+		return super.processKeyBinding(ks, e, condition, pressed);
+	}
+
+	/**
+	 * @param autoCompletionList
+	 */
+	public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
+		if (autoCompletionList == null)
+			return;
+		if (editor != null) {
+			editor.setAutoCompletionList(autoCompletionList);
+		}
+	}
+
+	public void setAutoCompletionCache(AutoCompletionCache acCache) {
+		if (acCache == null) {
+			logger.warning("argument acCache should not be null. Aborting.");
+			return;
+		}
+		if (editor != null) {
+			editor.setAutoCompletionCache(acCache);
+		}
+	}
+
+	public AutoCompletionList getAutoCompletionList() {
+		if (editor != null)
+			return editor.getAutoCompletionList();
+		else
+			return null;
+	}
+
+
+	public TableCellEditor getTableCellEditor() {
+		return editor;
+	}
+
+
+	public void  addOKAccelatorListener(KeyListener l) {
+		addKeyListener(l);
+		if (editor == null) {
+			logger.warning("editor is null. cannot register OK accelator listener.");
+		}
+		editor.getEditor().addKeyListener(l);
+	}
+
+
+	public void requestFocusInCell(final int row, final int col) {
+
+		// the following code doesn't work reliably. If a table cell
+		// gains focus using editCellAt() and requestFocusInWindow()
+		// it isn't possible to tab to the next table cell using TAB or
+		// ENTER. Don't know why.
+		//
+		// tblTagEditor.editCellAt(row, col);
+		// if (tblTagEditor.getEditorComponent() != null) {
+		//	tblTagEditor.getEditorComponent().requestFocusInWindow();
+		// }
+
+		// this is a workaround. We move the focus to the respective cell
+		// using a simulated mouse click. In this case one can tab out of
+		// the cell using TAB and ENTER.
+		//
+		Rectangle r = getCellRect(row,col, false);
+		Point p = new Point(r.x + r.width/2, r.y + r.height/2);
+		SwingUtilities.convertPointToScreen(p, this);
+		// logger.info("simulating mouse click event at point " + p.toString());
+
+		try {
+			Robot robot = new Robot();
+			robot.mouseMove(p.x,p.y);
+			robot.mousePress(InputEvent.BUTTON1_MASK);
+			robot.mouseRelease(InputEvent.BUTTON1_MASK);
+		} catch(AWTException e) {
+			logger.log(Level.SEVERE, "failed to simulate mouse click event at (" + r.x + "," + r.y + "). Exception: " + e.toString());
+			return;
+		}
+	}
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/AbstractNameIconProvider.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/AbstractNameIconProvider.java	(revision 20058)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/AbstractNameIconProvider.java	(revision 20058)
@@ -0,0 +1,46 @@
+package org.openstreetmap.josm.plugins.tageditor.preset;
+
+import java.awt.Image;
+import java.io.File;
+import java.util.Collection;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+public abstract class AbstractNameIconProvider implements INameIconProvider {
+	
+	protected String name;
+	protected String iconName;
+	protected ImageIcon icon;
+	protected File zipIconArchive;
+	
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getIconName() {
+		return iconName;
+	}
+
+	public void setIconName(String iconName, File zipIconArchive) {
+		this.iconName = iconName;
+	}
+	
+	public Icon getIcon() {
+		if (icon == null) {
+			Collection<String> s = Main.pref.getCollection("taggingpreset.icon.sources", null);
+	        icon = ImageProvider.getIfAvailable(s, "presets", null, getIconName(), zipIconArchive);
+	        if (icon == null) return null;
+	        Image i = icon.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT);
+			icon = new ImageIcon(i);
+		}
+		return icon;
+	}
+}
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Group.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Group.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Group.java	(revision 20058)
@@ -1,29 +1,16 @@
 package org.openstreetmap.josm.plugins.tageditor.preset;
 
-import java.awt.Image;
-import java.io.IOException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Logger;
 
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.plugins.tageditor.util.IndentWriter;
-
 /**
  * Group represents a named group of preset items. Groups can be nested.
  * 
- *
  */
-public class Group implements INameIconProvider {
+public class Group extends AbstractNameIconProvider {
 	
-	static private Logger logger = Logger.getLogger(Group.class.getName());
+	static final private Logger logger = Logger.getLogger(Group.class.getName());
 	
-	private String name;
-	private String iconName;
-	private ImageIcon icon;
 	private List<Item> items = null;
 	
@@ -35,38 +22,4 @@
 		this();
 		setName(name);
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getIconName() {
-		return iconName;
-	}
-
-	public void setIconName(String iconName) {
-		this.iconName = iconName;
-	}
-	
-	public Icon getIcon() {
-		if (icon == null) {
-			// load the icon from the JOSM resources, use Main classloader
-			// for loading 
-			URL url = Main.class.getResource("/images/" + getIconName());
-			if (url == null) {
-				logger.warning("failed to create URL for resource 'images/" + getIconName() + "'");
-				this.icon = null;
-			} else {
-				icon =new ImageIcon(url);
-				Image i = icon.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT);
-				icon = new ImageIcon(i);
-
-			}
-		}
-		return icon;
 	}
 	
@@ -83,18 +36,3 @@
 		return items; 
 	}
-	
-	public void dump(IndentWriter writer) throws IOException {
-		writer.indent();
-		writer.write("<group ");
-		writer.write(String.format("name=\"%s\" ", name));
-		writer.write(String.format("iconName=\"%s\" ", iconName));
-		writer.write(">");
-		writer.write("\n");
-		writer.incLevel();
-		for(Item item: items) {
-			item.dump(writer);
-		}
-		writer.decLevel();
-		writer.writeLine("</group>");
-	} 
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/INameIconProvider.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/INameIconProvider.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/INameIconProvider.java	(revision 20058)
@@ -4,5 +4,4 @@
 
 public interface INameIconProvider {
-
 	public String getName();
 	public Icon  getIcon();
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Item.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Item.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Item.java	(revision 20058)
@@ -1,25 +1,12 @@
 package org.openstreetmap.josm.plugins.tageditor.preset;
 
-import java.awt.Image;
-import java.io.IOException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.logging.Logger;
 
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
+public class Item  extends AbstractNameIconProvider {
 
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.plugins.tageditor.util.IndentWriter;
+	private final static Logger logger = Logger.getLogger(Item.class.getName());
 
-
-public class Item  implements INameIconProvider {
-
-	private static Logger logger = Logger.getLogger(Item.class.getName());
-
-	private String name;
-	private String iconName;
-	private ImageIcon icon;
 	private String label;
 	private List<Tag> tags;
@@ -38,5 +25,4 @@
 	}
 
-
 	public String getLabel() {
 		return label;
@@ -47,44 +33,6 @@
 	}
 
-
 	public Item(String name) {
 		setName(name);
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getIconName() {
-		return iconName;
-	}
-
-	public void setIconName(String iconName) {
-		this.iconName = iconName;
-	}
-
-	public Icon getIcon() {
-		// FIXME: should also load icons from the image paths configured in the 
-		// preferences for presets
-		//
-		if (icon == null) {
-			// load the icon from the JOSM resources, use Main classloader
-			// for loading
-			URL url = Main.class.getResource("/images/" + getIconName());
-			if (url == null) {
-				logger.warning("failed to create URL for resource 'images/" + getIconName() + "'");
-				return null;
-			} else {
-				icon =new ImageIcon(url);
-			}		
-			Image i = icon.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT);
-			icon = new ImageIcon(i);
-
-		}
-		return icon;
 	}
 
@@ -95,20 +43,4 @@
 	public List<Tag> getTags() {
 		return tags;
-	}
-
-	public void dump(IndentWriter writer) throws IOException {
-		writer.indent();
-		writer.write("<item ");
-		writer.write(String.format("name=\"%s\" ", name));
-		writer.write(String.format("label=\"%s\" ", label));
-		writer.write(String.format("iconName=\"%s\" ", iconName));
-		writer.write(">");
-		writer.write("\n");
-		writer.incLevel();
-		for(Tag tag: tags) {
-			tag.dump(writer);
-		}
-		writer.decLevel();
-		writer.writeLine("</item>");
 	}
 
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Presets.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Presets.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Presets.java	(revision 20058)
@@ -3,5 +3,7 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
@@ -21,5 +23,4 @@
 import org.openstreetmap.josm.plugins.tageditor.preset.io.Parser;
 import org.openstreetmap.josm.plugins.tageditor.preset.io.PresetIOException;
-import org.openstreetmap.josm.plugins.tageditor.util.IndentWriter;
 
 public class Presets {
@@ -37,14 +38,17 @@
 		//
 		if (Main.pref.getBoolean("taggingpreset.enable-defaults", true)) {
-			sources.add("resource://presets/presets.xml");
+			sources.add("resource://data/defaultpresets.xml");
 		}
 		sources.addAll(Main.pref.getCollection("taggingpreset.sources",
 				new LinkedList<String>()));
 
+		File zipIconArchive = null;
 		for (String source : sources) {
-			logger.log(Level.INFO, String.format(
-					"starting to read presets from source '%1$s'", source));
 			try {
 				MirroredInputStream s = new MirroredInputStream(source);
+                InputStream zip = s.getZipEntry("xml","preset");
+                if(zip != null) {
+                	zipIconArchive = s.getFile();
+                }
 				InputStreamReader r;
 				try {
@@ -53,6 +57,5 @@
 					r = new InputStreamReader(s);
 				}
-				presets = loadPresets(r, presets);
-
+				presets = loadPresets(r, presets, zipIconArchive);
 			} catch (PresetIOException e) {
 				logger
@@ -77,5 +80,5 @@
 			con.connect();
 			Reader reader = new InputStreamReader(con.getInputStream());
-			return loadPresets(reader, null);
+			return loadPresets(reader, null, null);
 		} catch (Exception e) {
 			logger.log(Level.SEVERE,
@@ -83,8 +86,7 @@
 			throw new PresetIOException(e);
 		}
-
 	}
 
-	static public Presets loadPresets(Reader reader, Presets p) throws PresetIOException {
+	static public Presets loadPresets(Reader reader, Presets p, File zipIconArchive) throws PresetIOException {
 		try {
 			Parser parser = new Parser();
@@ -120,19 +122,6 @@
 	}
 
-	public void dump(IndentWriter writer) throws IOException {
-		writer.indent();
-		writer.write("<presets>\n");
-		writer.incLevel();
-		for (Group group : groups) {
-			group.dump(writer);
-		}
-		writer.decLevel();
-		writer.indent();
-		writer.write("</presets>");
-	}
-
 	public List<Group> getGroups() {
 		return groups;
 	}
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Tag.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Tag.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Tag.java	(revision 20058)
@@ -1,8 +1,3 @@
 package org.openstreetmap.josm.plugins.tageditor.preset;
-
-import java.io.IOException;
-
-import org.openstreetmap.josm.plugins.tageditor.util.IndentWriter;
-
 
 public class Tag {
@@ -46,22 +41,3 @@
 		this.optional = optional;
 	}
-	
-	
-	public void dump(IndentWriter writer) throws IOException {
-		writer.indent();
-		writer.write("<tag ");
-		writer.write(String.format("key=\"%s\" ", key));
-		writer.write(String.format("optional=\"%s\" ", Boolean.toString(optional)));
-		if (value != null) {
-			writer.write(String.format("value=\"%s\" ", value));
-		}
-		writer.write(String.format("displayName=\"%s\" ", displayName));
-		writer.write("/>");
-		writer.write("\n");
-	}
-	 
-	
-	
-	
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/Parser.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/Parser.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/Parser.java	(revision 20058)
@@ -1,4 +1,5 @@
 package org.openstreetmap.josm.plugins.tageditor.preset.io;
 
+import java.io.File;
 import java.io.Reader;
 import java.util.Stack;
@@ -22,5 +23,6 @@
 public class Parser {
 	
-	static private Logger logger = Logger.getLogger(Parser.class.getName());
+	static final private Logger logger = Logger.getLogger(Parser.class.getName());
+	
     private Presets presets = null;
 	private Reader reader;
@@ -29,4 +31,5 @@
 	private boolean inOptionalKeys = false; 
 	private XMLReader parser;
+	private File zipIconArchive;
 
 	public Parser() {
@@ -49,4 +52,8 @@
 	public Reader getReader() {
 		return reader;
+	}
+	
+	public void setZipIconArchive(File zipIconArchive) {
+		this.zipIconArchive = zipIconArchive;
 	}
 	
@@ -122,5 +129,4 @@
 	}
 	
-	
 	protected String translatedAttributeValue(String attrValue) {
 		if (attrValue == null) {
@@ -134,5 +140,5 @@
 		Group g = new Group();
 		g.setName(translatedAttributeValue(name));
-		g.setIconName(iconName);
+		g.setIconName(iconName, zipIconArchive);
 		currentGroup.push(g);
 	}
@@ -146,5 +152,5 @@
 		currentItem = new Item();
 		currentItem.setName(translatedAttributeValue(name));
-		currentItem.setIconName(iconName);
+		currentItem.setIconName(iconName, zipIconArchive);
 	}
 	
@@ -238,6 +244,5 @@
 					   || "check".equals(qName)) {
 				onTag(getAttribute(atts, "key"), getAttribute(atts, "value"), getAttribute(atts, "text"));
-			}
-			
+			}			
 		}
 		
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/PresetIOException.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/PresetIOException.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/PresetIOException.java	(revision 20058)
@@ -22,6 +22,3 @@
 		// TODO Auto-generated constructor stub
 	}
-
-	
-	
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecification.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecification.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecification.java	(revision 20058)
@@ -5,5 +5,4 @@
 
 import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionContext;
-
 
 /**
@@ -63,5 +62,4 @@
 	}
 
-
 	/**
 	 * sets the list of lables for this tag specification
@@ -79,10 +77,9 @@
 	}
 
-
 	/**
-	 * adds a lable to the list of lables for this tag specification. The lable
+	 * Adds a label to the list of label for this tag specification. The label
 	 * is only added if i
 	 * 
-	 * @param lable the lable to add; must not be null
+	 * @param lable the lalbe to add; must not be null
 	 * @exception IllegalArgumentException thrown, if lable is null
 	 */
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecifications.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecifications.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecifications.java	(revision 20058)
@@ -11,7 +11,7 @@
 import java.util.logging.Logger;
 
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionItemPritority;
+import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
 import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionContext;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionItemPritority;
-import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionListItem;
 import org.xml.sax.Attributes;
 import org.xml.sax.EntityResolver;
@@ -58,6 +58,4 @@
 	private ArrayList<TagSpecification> tagSpecifications = null;
 
-
-
 	private static TagSpecifications instance = null;
 
@@ -123,7 +121,4 @@
 			parser = null;
 		}
-
-
-
 	}
 
@@ -160,6 +155,5 @@
 		return items;
 	}
-
-
+	
 	/**
 	 * replies a list of {@see KeyValuePair}s for all {@see TagSpecification}s and
@@ -292,5 +286,4 @@
 		}
 
-
 		/**
 		 * handles a start element with name <code>label</code>
@@ -359,9 +352,5 @@
 			logger.log(Level.WARNING, "XML parsing warning", e);
 		}
-
-
-
-	}
-
+	}
 
 	/**
@@ -383,8 +372,6 @@
 	}
 
-
 	static public void main(String args[]) throws Exception{
 		TagSpecifications.loadFromResources();
 	}
-
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/ITagSelectorListener.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/ITagSelectorListener.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/ITagSelectorListener.java	(revision 20058)
@@ -3,7 +3,5 @@
 import org.openstreetmap.josm.plugins.tageditor.tagspec.KeyValuePair;
 
-
 public interface ITagSelectorListener {
-
 	public void itemSelected(KeyValuePair pair);
 }
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/KeyValueCellRenderer.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/KeyValueCellRenderer.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/KeyValueCellRenderer.java	(revision 20058)
@@ -1,5 +1,4 @@
 package org.openstreetmap.josm.plugins.tageditor.tagspec.ui;
 
-import java.awt.Color;
 import java.awt.Component;
 import java.awt.Font;
@@ -8,14 +7,13 @@
 import javax.swing.JLabel;
 import javax.swing.JTable;
+import javax.swing.UIManager;
 import javax.swing.table.TableCellRenderer;
 
 public class KeyValueCellRenderer extends JLabel implements TableCellRenderer  {
 
-	private static Logger logger = Logger.getLogger(KeyValueCellRenderer.class.getName());
-	public static final Color BG_COLOR_SELECTED = new Color(143,170,255);
-
+	private static final Logger logger = Logger.getLogger(KeyValueCellRenderer.class.getName());
 
 	protected void init() {
-		setFont(new Font("Courier",Font.PLAIN,12));
+		setFont(new Font("Courier",Font.PLAIN,getFont().getSize()));
 		setOpaque(true);
 	}
@@ -29,7 +27,9 @@
 
 		if (isSelected) {
-			setBackground(BG_COLOR_SELECTED);
+			setBackground(UIManager.getColor("Table.selectionBackground"));
+			setForeground(UIManager.getColor("Table.selectionForeground"));
 		} else  {
-			setBackground(Color.WHITE);
+			setBackground(UIManager.getColor("Table.background"));
+			setForeground(UIManager.getColor("Table.foreground"));
 		}
 		setText((String)value);
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TabularTagSelector.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TabularTagSelector.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TabularTagSelector.java	(revision 20058)
@@ -31,6 +31,4 @@
 import org.openstreetmap.josm.plugins.tageditor.tagspec.KeyValuePair;
 
-
-
 public class TabularTagSelector extends JPanel {
 
@@ -40,5 +38,4 @@
 	private JScrollPane scrollPane;
 	private final ArrayList<ITagSelectorListener> listeners = new ArrayList<ITagSelectorListener>();
-
 
 	protected JPanel buildFilterPanel() {
@@ -123,5 +120,4 @@
 	}
 
-
 	protected JPanel buildControlButtonPanel() {
 		JPanel pnl = new JPanel();
Index: /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTableModel.java
===================================================================
--- /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTableModel.java	(revision 20057)
+++ /applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTableModel.java	(revision 20058)
@@ -12,5 +12,4 @@
 import org.openstreetmap.josm.plugins.tageditor.tagspec.KeyValuePair;
 import org.openstreetmap.josm.plugins.tageditor.tagspec.TagSpecifications;
-
 
 public class TagsTableModel extends AbstractTableModel {
@@ -117,4 +116,3 @@
 		return visibleItems.get(row);
 	}
-
 }
