Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 115)
+++ src/org/openstreetmap/josm/Main.java	(revision 116)
@@ -268,6 +268,7 @@
 			if (args.containsKey("reset-preferences")) {
 				Main.pref.resetToDefault();
-			} else
+			} else {
 				Main.pref.load();
+			}
 		} catch (final IOException e1) {
 			e1.printStackTrace();
@@ -276,4 +277,11 @@
 			Main.pref.resetToDefault();
 		}
+
+		try {
+	        Main.pref.upgrade(Integer.parseInt(AboutAction.version));
+        } catch (NumberFormatException e1) {
+        }
+
+		
 		if (errMsg != null)
 			JOptionPane.showMessageDialog(null, errMsg);
Index: src/org/openstreetmap/josm/actions/AboutAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/AboutAction.java	(revision 115)
+++ src/org/openstreetmap/josm/actions/AboutAction.java	(revision 116)
@@ -37,4 +37,21 @@
 public class AboutAction extends JosmAction {
 
+	public static final String version;
+	
+	private static JTextArea revision;
+	private static String time;
+
+	static {
+		JTextArea revision = loadFile(Main.class.getResource("/REVISION"));
+
+		Pattern versionPattern = Pattern.compile(".*?Revision: ([0-9]*).*", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
+		Matcher match = versionPattern.matcher(revision.getText());
+		version = match.matches() ? match.group(1) : "UNKNOWN";
+		
+		Pattern timePattern = Pattern.compile(".*?Last Changed Date: ([^\n]*).*", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
+		match = timePattern.matcher(revision.getText());
+		time = match.matches() ? match.group(1) : "UNKNOWN";
+	}
+	
 	public AboutAction() {
 		super(tr("About"), "about",tr("Display the about screen."), KeyEvent.VK_A);
@@ -45,14 +62,5 @@
 		
 		JTextArea readme = loadFile(Main.class.getResource("/README"));
-		JTextArea revision = loadFile(Main.class.getResource("/REVISION"));
-		
-		Pattern versionPattern = Pattern.compile(".*?Revision: ([0-9]*).*", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
-		Pattern timePattern = Pattern.compile(".*?Last Changed Date: ([^\n]*).*", Pattern.CASE_INSENSITIVE|Pattern.DOTALL);
 
-		Matcher match = versionPattern.matcher(revision.getText());
-		String version = match.matches() ? match.group(1) : "UNKNOWN";
-		match = timePattern.matcher(revision.getText());
-		String time = match.matches() ? match.group(1) : "UNKNOWN";
-		
 		JPanel info = new JPanel(new GridBagLayout());
 		info.add(new JLabel(tr("Java OpenStreetMap Editor Version {0}",version)), GBC.eop());
@@ -80,5 +88,5 @@
 	 * @return	An read-only text area with the content of "resource"
 	 */
-	private JTextArea loadFile(URL resource) {
+	private static JTextArea loadFile(URL resource) {
 		JTextArea area = new JTextArea(tr("File could not be found."));
 		area.setEditable(false);
Index: src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- src/org/openstreetmap/josm/data/Preferences.java	(revision 115)
+++ src/org/openstreetmap/josm/data/Preferences.java	(revision 116)
@@ -32,12 +32,12 @@
 		void preferenceChanged(String key, String newValue);
 	}
-	
+
 	public final ArrayList<PreferenceChangedListener> listener = new ArrayList<PreferenceChangedListener>();
-	
+
 	/**
 	 * Map the property name to the property object.
 	 */
 	private final SortedMap<String, String> properties = new TreeMap<String, String>();
-	
+
 	/**
 	 * Return the location of the preferences file
@@ -112,5 +112,4 @@
 	}
 
-
 	public void load() throws IOException {
 		properties.clear();
@@ -138,5 +137,11 @@
 		properties.put("color."+marktr("gps point"), ColorHelper.color2html(Color.gray));
 		properties.put("color."+marktr("conflict"), ColorHelper.color2html(Color.gray));
+		properties.put("color."+marktr("scale"), ColorHelper.color2html(Color.white));
 		save();
 	}
+
+	public final void upgrade(int oldVersion) {
+		if (oldVersion > 115) return;
+		properties.put("color.scale", ColorHelper.color2html(Color.white));
+	}
 }
Index: src/org/openstreetmap/josm/data/projection/Epsg4326.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 115)
+++ src/org/openstreetmap/josm/data/projection/Epsg4326.java	(revision 116)
@@ -26,3 +26,7 @@
         return "epsg4326";
     }
+
+	public double scaleFactor() {
+	    return 1.0/360;
+    }
 }
Index: src/org/openstreetmap/josm/data/projection/Mercator.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 115)
+++ src/org/openstreetmap/josm/data/projection/Mercator.java	(revision 116)
@@ -34,3 +34,7 @@
         return "mercator";
     }
+
+	public double scaleFactor() {
+	    return 1/Math.PI/2;
+    }
 }
Index: src/org/openstreetmap/josm/data/projection/Projection.java
===================================================================
--- src/org/openstreetmap/josm/data/projection/Projection.java	(revision 115)
+++ src/org/openstreetmap/josm/data/projection/Projection.java	(revision 116)
@@ -47,3 +47,9 @@
      */
     String getCacheDirectoryName();
+    
+    /**
+     * The factor to multiply with an easting coordinate to get from "easting 
+     * units per pixel" to "meters per pixel"
+     */
+    double scaleFactor();
 }
Index: src/org/openstreetmap/josm/gui/MapScaler.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapScaler.java	(revision 115)
+++ src/org/openstreetmap/josm/gui/MapScaler.java	(revision 116)
@@ -1,9 +1,11 @@
 package org.openstreetmap.josm.gui;
 
-import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.geom.Rectangle2D;
 
 import javax.swing.JComponent;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.ColorHelper;
 
 public class MapScaler extends JComponent {
@@ -18,7 +20,7 @@
 
 	@Override public void paint(Graphics g) {
-		double circum = mv.getScale()*100/Math.PI/2*40041455; // circumference of the earth in meter
+		double circum = mv.getScale()*100*Main.proj.scaleFactor()*40041455; // circumference of the earth in meter
 		String text = circum > 1000 ? (Math.round(circum/100)/10.0)+"km" : Math.round(circum)+"m";
-		g.setColor(Color.white);
+		g.setColor(ColorHelper.html2color(Main.pref.get("color.scale", "#ffffff")));
 		g.drawLine(0, 5, 99, 5);
 		g.drawLine(0, 0, 0, 10);
Index: src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapView.java	(revision 115)
+++ src/org/openstreetmap/josm/gui/MapView.java	(revision 116)
@@ -98,5 +98,5 @@
 		MapSlider zoomSlider = new MapSlider(this);
 		add(zoomSlider);
-		zoomSlider.setBounds(0,0, 100, 30);
+		zoomSlider.setBounds(3, 0, 114, 30);
 		
 		MapScaler scaler = new MapScaler(this);
Index: src/org/openstreetmap/josm/gui/PreferenceDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 115)
+++ src/org/openstreetmap/josm/gui/PreferenceDialog.java	(revision 116)
@@ -11,4 +11,5 @@
 import java.awt.event.ActionListener;
 import java.util.Map;
+import java.util.StringTokenizer;
 import java.util.TreeMap;
 import java.util.Vector;
@@ -19,4 +20,5 @@
 import javax.swing.Box;
 import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
@@ -81,4 +83,11 @@
 			Main.pref.put("draw.segment.direction", directionHint.isSelected());
 
+			if (annotationSources.getModel().getSize() > 0) {
+				StringBuilder sb = new StringBuilder();
+				for (int i = 0; i < annotationSources.getModel().getSize(); ++i)
+					sb.append(";"+annotationSources.getModel().getElementAt(i));
+				Main.pref.put("annotation.sources", sb.toString().substring(1));
+			}
+
 			for (int i = 0; i < colors.getRowCount(); ++i) {
 				String name = (String)colors.getValueAt(i, 0);
@@ -121,8 +130,4 @@
 	private JComboBox lafCombo = new JComboBox(UIManager.getInstalledLookAndFeels());
 	/**
-	 * Combobox with all projections available
-	 */
-	private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
-	/**
 	 * The main tab panel.
 	 */
@@ -161,4 +166,10 @@
 	private JCheckBox directionHint = new JCheckBox(tr("Draw Direction Arrows"));
 	private JTable colors;
+
+	/**
+	 * Combobox with all projections available
+	 */
+	private JComboBox projectionCombo = new JComboBox(Projection.allProjections);
+	private JList annotationSources = new JList(new DefaultListModel());
 
 
@@ -227,4 +238,8 @@
 		directionHint.setSelected(Main.pref.getBoolean("draw.segment.direction"));
 
+		String annos = Main.pref.get("annotation.sources");
+		StringTokenizer st = new StringTokenizer(annos, ";");
+		while (st.hasMoreTokens())
+			((DefaultListModel)annotationSources.getModel()).addElement(st.nextToken());
 
 
@@ -275,4 +290,54 @@
 			}
 		});
+
+		// Annotation source panels
+		JPanel annoButton = new JPanel(new GridBagLayout());
+		JButton addAnno = new JButton(tr("Add"));
+		addAnno.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				String source = JOptionPane.showInputDialog(Main.parent, tr("Annotation preset source"));
+				if (source == null)
+					return;
+				((DefaultListModel)annotationSources.getModel()).addElement(source);
+				requiresRestart = true;
+			}
+		});
+		GBC g = GBC.eol().fill(GBC.HORIZONTAL);
+		g.weightx = 0;
+		annoButton.add(addAnno,g);
+
+		JButton editAnno = new JButton(tr("Edit"));
+		editAnno.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				if (annotationSources.getSelectedIndex() == -1)
+					JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to edit."));
+				else {
+					String source = JOptionPane.showInputDialog(Main.parent, tr("Annotation preset source"), annotationSources.getSelectedValue());
+					if (source == null)
+						return;
+					((DefaultListModel)annotationSources.getModel()).setElementAt(source, annotationSources.getSelectedIndex());
+					requiresRestart = true;
+				}
+			}
+		});
+		annoButton.add(GBC.glue(0, 2), GBC.eol());
+		annoButton.add(editAnno,g);
+
+		JButton deleteAnno = new JButton(tr("Delete"));
+		deleteAnno.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				if (annotationSources.getSelectedIndex() == -1)
+					JOptionPane.showMessageDialog(Main.parent, tr("Please select the row to delete."));
+				else {
+					((DefaultListModel)annotationSources.getModel()).remove(annotationSources.getSelectedIndex());
+					requiresRestart = true;
+				}
+			}
+		});
+		annoButton.add(GBC.glue(0, 2), GBC.eol());
+		annoButton.add(deleteAnno,g);
+		annotationSources.setVisibleRowCount(5);
+
+
 
 		// setting tooltips
@@ -290,4 +355,7 @@
 		drawRawGpsLines.setToolTipText(tr("If your gps device draw to few lines, select this to draw lines along your way."));
 		colors.setToolTipText(tr("Colors used by different objects in JOSM."));
+		annotationSources.setToolTipText(tr("The sources (url or filename) of annotation preset definition files. See http://josm.eigenheimstrasse.de/wiki/AnnotationPresets for help."));
+		addAnno.setToolTipText(tr("Add a new annotation preset source to the list."));
+		deleteAnno.setToolTipText(tr("Delete the selected source from the list."));
 
 		// creating the gui
@@ -333,5 +401,9 @@
 		map.add(new JLabel(tr("Projection method")), GBC.std());
 		map.add(GBC.glue(5,0), GBC.std().fill(GBC.HORIZONTAL));
-		map.add(projectionCombo, GBC.eol().fill(GBC.HORIZONTAL).insets(0,0,0,5));
+		map.add(projectionCombo, GBC.eop().fill(GBC.HORIZONTAL).insets(0,0,0,5));
+		map.add(new JLabel(tr("Annotation preset sources")), GBC.eol());
+		map.add(new JScrollPane(annotationSources), GBC.std().fill(GBC.HORIZONTAL).insets(10,0,10,0));
+		map.add(annoButton, GBC.eol());
+
 		map.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
 
Index: src/org/openstreetmap/josm/gui/WorldChooser.java
===================================================================
--- src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 115)
+++ src/org/openstreetmap/josm/gui/WorldChooser.java	(revision 116)
@@ -77,4 +77,7 @@
             public String getCacheDirectoryName() {
                 throw new UnsupportedOperationException();
+            }
+			public double scaleFactor() {
+	            return 1;
             }
 		};
Index: src/org/openstreetmap/josm/gui/dialogs/AnnotationPreset.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/AnnotationPreset.java	(revision 116)
+++ src/org/openstreetmap/josm/gui/dialogs/AnnotationPreset.java	(revision 116)
@@ -0,0 +1,194 @@
+package org.openstreetmap.josm.gui.dialogs;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.GridBagLayout;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+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.tools.GBC;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import uk.co.wilson.xml.MinML2;
+
+
+/**
+ * This class read encapsulate one annotation preset. A class method can
+ * read in all predefined presets, either shipped with JOSM or that are
+ * in the config directory.
+ * 
+ * It is also able to construct dialogs out of preset definitions.
+ */
+public class AnnotationPreset {
+
+	private static interface Item {
+		void addToPanel(JPanel p);
+		void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds);
+	}
+
+	public static class Text implements Item {
+		String key;
+		String label;
+		JTextField value = new JTextField();
+
+		public void addToPanel(JPanel p) {
+			p.add(new JLabel(label), GBC.std().insets(0,0,10,0));
+			p.add(value, GBC.eol().fill(GBC.HORIZONTAL));
+		}
+		public Text(String key, String label, String value) {
+			this.key = key;
+			this.label = label;
+			this.value.setText(value == null ? "" : value);
+		}
+		public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
+			cmds.add(new ChangePropertyCommand(sel, key, value.getText()));
+		}
+	}
+
+	public static class Check implements Item {
+		String key;
+		JCheckBox check = new JCheckBox();
+
+		public void addToPanel(JPanel p) {
+			p.add(check, GBC.eol().fill(GBC.HORIZONTAL));
+		}
+		public Check(String key, String label, boolean check) {
+			this.key = key;
+			this.check.setText(label);
+			this.check.setSelected(check);
+		}
+		public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
+			cmds.add(new ChangePropertyCommand(sel, key, check.isSelected() ? "true" : null));
+		}
+	}
+
+	public static class Label implements Item {
+		String text;
+
+		public void addToPanel(JPanel p) {
+			p.add(new JLabel(text), GBC.eol());
+		}
+		public Label(String text) {
+			this.text = text;
+		}
+		public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {}
+	}
+
+	public static class Key implements Item {
+		String key;
+		String value;
+
+		public void addToPanel(JPanel p) {}
+		public Key(String key, String value) {
+			this.key = key;
+			this.value = value;
+		}
+		public void addCommands(Collection<OsmPrimitive> sel, List<Command> cmds) {
+			cmds.add(new ChangePropertyCommand(sel, key, value != null && !value.equals("") ? value : null));
+		}
+	}
+
+	private static class Parser extends MinML2 {
+		List<AnnotationPreset> data = new LinkedList<AnnotationPreset>();
+		List<Item> current;
+		String currentName;
+		private static int unknownCounter = 1;
+
+		@Override public void startElement(String ns, String lname, String qname, Attributes a) throws SAXException {
+			if (qname.equals("annotations"))
+				return;
+			if (qname.equals("item")) {
+				current = new LinkedList<Item>();
+				currentName = a.getValue("name");
+				if (currentName == null)
+					currentName = "Unnamed Preset #"+(unknownCounter++);
+			} else if (qname.equals("text"))
+				current.add(new Text(a.getValue("key"), a.getValue("label"), a.getValue("default")));
+			else if (qname.equals("check")) {
+				String s = a.getValue("default");
+				boolean check = s == null || s.equals("0") || s.startsWith("off") || s.startsWith("false") || s.startsWith("no");
+				current.add(new Check(a.getValue("key"), a.getValue("label"), check));
+			} else if (qname.equals("label"))
+				current.add(new Label(a.getValue("label")));
+			else if (qname.equals("key"))
+				current.add(new Key(a.getValue("key"), a.getValue("value")));
+			else
+				throw new SAXException(tr("Unknown annotation object {0} at line {1} column {2}", qname, getLineNumber(), getColumnNumber()));
+		}
+		@Override public void endElement(String ns, String lname, String qname) {
+			if (qname.equals("item"))
+				data.add(new AnnotationPreset(current, currentName));
+		}
+	}
+
+	private List<Item> data;
+	String name;
+
+	public AnnotationPreset(List<Item> data, String name) {
+		this.data = data;
+		this.name = name;
+	}
+
+	/**
+	 * Create an empty annotation preset. This will not have any items and
+	 * will be an empty string as text. createPanel will return null.
+	 * Use this as default item for "do not select anything".
+	 */
+	public AnnotationPreset() {
+		name = "";
+	}
+
+	public static List<AnnotationPreset> readAll(InputStream inStream) throws IOException, SAXException {
+		BufferedReader in = null;
+		try {
+			in = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+			in = new BufferedReader(new InputStreamReader(inStream));
+		}
+		Parser p = new Parser();
+		p.parse(in);
+		return p.data;
+	}
+
+	public JPanel createPanel() {
+		if (data == null)
+			return null;
+		JPanel p = new JPanel(new GridBagLayout());
+		for (Item i : data)
+			i.addToPanel(p);
+		return p;
+	}
+	
+	@Override public String toString() {
+		return name;
+	}
+
+	public Command createCommand(Collection<OsmPrimitive> sel) {
+		List<Command> cmds = new LinkedList<Command>();
+		for (Item i : data)
+			i.addCommands(sel, cmds);
+		if (cmds.size() == 0)
+			return null;
+		else if (cmds.size() == 1)
+			return cmds.get(0);
+		else
+			return new SequenceCommand(tr("Change Properties"), cmds);
+    }
+}
Index: src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 115)
+++ src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java	(revision 116)
@@ -15,7 +15,12 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.StringTokenizer;
 import java.util.TreeMap;
 import java.util.TreeSet;
@@ -23,4 +28,5 @@
 import java.util.Map.Entry;
 
+import javax.swing.DefaultComboBoxModel;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
@@ -42,4 +48,5 @@
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.xml.sax.SAXException;
 
 /**
@@ -196,4 +203,5 @@
 	 */
 	private final JTable propertyTable = new JTable(data);
+	private JComboBox annotationPresets = new JComboBox();
 
 	/**
@@ -202,6 +210,52 @@
 	public PropertiesDialog(MapFrame mapFrame) {
 		super(tr("Properties"), "propertiesdialog", tr("Property for selected objects."), KeyEvent.VK_P);
-
 		setPreferredSize(new Dimension(320,150));
+		
+		Vector<AnnotationPreset> allPresets = new Vector<AnnotationPreset>();
+		String allAnnotations = Main.pref.get("annotation.sources");
+		StringTokenizer st = new StringTokenizer(allAnnotations, ";");
+		while (st.hasMoreTokens()) {
+			InputStream in = null;
+			String source = st.nextToken();
+			try {
+	            if (source.startsWith("http") || source.startsWith("ftp") || source.startsWith("file"))
+	            	in = new URL(source).openStream();
+	            else if (source.startsWith("resource://"))
+	            	in = Main.class.getResourceAsStream(source.substring("resource:/".length()));
+	            else
+	            	in = new FileInputStream(source);
+	            allPresets.addAll(AnnotationPreset.readAll(in));
+            } catch (IOException e) {
+	            e.printStackTrace();
+	            JOptionPane.showMessageDialog(Main.parent, tr("Could not read annotation preset source: {0}",source));
+            } catch (SAXException e) {
+	            e.printStackTrace();
+	            JOptionPane.showMessageDialog(Main.parent, tr("Error parsing {0}: ", source)+e.getMessage());
+            }
+		}
+		if (allPresets.size() > 0) {
+			allPresets.add(0, new AnnotationPreset());
+			annotationPresets.setModel(new DefaultComboBoxModel(allPresets));
+			add(annotationPresets, BorderLayout.NORTH);
+		}
+		annotationPresets.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				Collection<OsmPrimitive> sel = Main.ds.getSelected();
+				AnnotationPreset preset = (AnnotationPreset)annotationPresets.getSelectedItem();
+				JPanel p = preset.createPanel();
+				if (p == null)
+					return;
+				int answer;
+				if (p.getComponentCount() == 0)
+					answer = JOptionPane.OK_OPTION;
+				else
+					answer = JOptionPane.showConfirmDialog(Main.parent, p, trn("Change {0} object", "Change {0} objects", sel.size(), sel.size()), JOptionPane.OK_CANCEL_OPTION);
+				if (answer == JOptionPane.OK_OPTION) {
+					Main.main.editLayer().add(preset.createCommand(sel));
+					selectionChanged(sel); // update whole table
+				}
+				annotationPresets.setSelectedIndex(0);
+            }
+		});
 
 		data.setColumnIdentifiers(new String[]{tr("Key"),tr("Value")});
