Index: /applications/editors/josm/plugins/openstreetbugs/LICENSE.txt
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/LICENSE.txt	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/LICENSE.txt	(revision 11157)
@@ -0,0 +1,26 @@
+Copyright (c) 2008, Henrik Niehaus
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice, 
+   this list of conditions and the following disclaimer in the documentation 
+   and/or other materials provided with the distribution.
+3. Neither the name of the project nor the names of its 
+   contributors may be used to endorse or promote products derived from this 
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
Index: /applications/editors/josm/plugins/openstreetbugs/build.properties
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/build.properties	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/build.properties	(revision 11157)
@@ -0,0 +1,11 @@
+#Sat Oct 11 16:53:01 CEST 2008
+
+# plugin version
+version=0.5
+
+# the path to JOSM source code (project directory)
+josm.base.dir=../JOSM
+
+# a osm file, which will be loaded, when running
+# the test target
+osmfile=/tmp/hoe.osm
Index: /applications/editors/josm/plugins/openstreetbugs/build.xml
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/build.xml	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/build.xml	(revision 11157)
@@ -0,0 +1,73 @@
+<project name="osb" default="dist" basedir=".">
+
+	<property file="build.properties"/>
+	
+	<!-- compilation properties -->
+	<property name="josm.build.dir" value="${josm.base.dir}/build" />
+	<property name="josm.home.dir" value="${user.home}/.josm" />
+	<property name="josm" location="${josm.base.dir}/dist/josm-custom.jar" />
+	<property name="lib.dir" value="lib" />
+	<property name="plugin.build.dir" value="build" />
+	<property name="plugin.name" value="${ant.project.name}" />
+	<property name="plugin.jar" value="${plugin.build.dir}/${plugin.name}.jar" />
+
+	<property name="ant.build.javac.target" value="1.5" />
+
+	<target name="init">
+		<mkdir dir="${plugin.build.dir}" />
+	</target>
+
+	<target name="compile" depends="init">
+		<echo message="creating ${plugin.jar}" />
+		<javac srcdir="src" classpath="${josm}" destdir="${plugin.build.dir}" debug="true">
+			<include name="**/*.java" />
+		</javac>
+	</target>
+
+	<target name="dist" depends="clean, compile">
+		<!-- set build time -->
+		<tstamp>
+			<format property="current.time" pattern="dd.MM.yyyy HH:mm" />
+		</tstamp>
+
+		<!-- copy images to jar -->
+		<copy todir="${plugin.build.dir}/images">
+			<fileset dir="images" />
+		</copy>
+		
+		<!-- copy language files -->
+		<copy todir="${plugin.build.dir}">
+			<fileset dir="src">
+				<include name="**/*.properties" />
+			</fileset>
+		</copy>
+
+		<!-- create the jar file -->
+		<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
+			<manifest>
+				<attribute name="Plugin-Class" value="org.openstreetmap.josm.plugins.osb.OsbPlugin" />
+				<attribute name="Plugin-Description" value="Imports issues from OpenStreetBugs" />
+				<attribute name="Plugin-Version" value="${version}" />
+				<attribute name="Plugin-Date" value="${current.time}" />
+				<attribute name="Author" value="Henrik Niehaus" />
+			</manifest>
+		</jar>
+	</target>
+
+	<!-- clean target -->
+	<target name="clean">
+		<delete dir="build" />
+	</target>
+
+	<target name="install" depends="dist">
+		<copy file="${plugin.jar}" todir="${user.home}/.josm/plugins" />
+	</target>
+
+	<target name="test" depends="install">
+		<java jar="${josm}" fork="true">
+			<arg value="${osmfile}" />
+			<jvmarg value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=7777"/>
+		</java>
+	</target>
+
+</project>
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/ConfigKeys.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/ConfigKeys.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/ConfigKeys.java	(revision 11157)
@@ -0,0 +1,38 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb;
+
+public class ConfigKeys {
+	public static final String OSB_API_DISABLED = "osb.api.disabled";
+	public static final String OSB_API_URI_CLOSE = "osb.uri.close";
+	public static final String OSB_API_URI_EDIT = "osb.uri.edit";
+	public static final String OSB_API_URI_DOWNLOAD = "osb.uri.download";
+	public static final String OSB_API_URI_NEW = "osb.uri.new";
+	public static final String OSB_NICKNAME = "osb.nickname";
+	public static final String OSB_AUTO_DOWNLOAD = "osb.auto_download";
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbDownloadLoop.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbDownloadLoop.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbDownloadLoop.java	(revision 11157)
@@ -0,0 +1,105 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb;
+
+import java.awt.geom.Point2D;
+import java.util.concurrent.TimeUnit;
+
+import org.openstreetmap.josm.Main;
+
+public class OsbDownloadLoop extends Thread {
+	
+	private static OsbDownloadLoop instance;
+	
+	private long countdown = TimeUnit.SECONDS.toMillis(1);
+	
+	private boolean downloadDone = false;
+	
+	private final int INTERVAL = 100;
+	
+	private OsbPlugin plugin;
+	
+	private Point2D lastCenter;
+	
+	public OsbDownloadLoop() {
+		start();
+	}
+	
+	public static synchronized OsbDownloadLoop getInstance() {
+		if(instance == null) {
+			instance = new OsbDownloadLoop();
+		}
+		return instance;
+	}
+	
+	@Override
+	public void run() {
+		try {
+			while(true) {
+				countdown -= INTERVAL;
+				
+				// if the center of the map has changed, the user has dragged or
+				// zoomed the map
+				if(Main.map != null && Main.map.mapView != null) {
+					Point2D currentCenter = Main.map.mapView.getCenter();
+					if(currentCenter != null && !currentCenter.equals(lastCenter)) {
+						resetCountdown();
+						lastCenter = currentCenter;
+					}
+				}
+				
+				// auto download if configured
+				if( Main.pref.getBoolean(ConfigKeys.OSB_AUTO_DOWNLOAD) && OsbPlugin.active ) {
+					if(countdown < 0) {
+						if(!downloadDone) {
+							if(plugin != null) {
+								plugin.updateData();
+								downloadDone = true;
+							}
+						} else {
+							countdown = -1;
+						}
+					}
+				}
+				
+				Thread.sleep(INTERVAL);
+			}
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	public void resetCountdown() {
+		downloadDone = false;
+		countdown = TimeUnit.SECONDS.toMillis(1);
+	}
+
+	public void setPlugin(OsbPlugin plugin) {
+		this.plugin = plugin;
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbLayer.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbLayer.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbLayer.java	(revision 11157)
@@ -0,0 +1,250 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ImageObserver;
+import java.util.Collection;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JMenuItem;
+import javax.swing.JSeparator;
+import javax.swing.JToolTip;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.RenameLayerAction;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.plugins.osb.gui.action.OsbAction;
+import org.openstreetmap.josm.plugins.osb.gui.action.PopupFactory;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+import org.openstreetmap.josm.tools.ColorHelper;
+
+public class OsbLayer extends Layer implements MouseListener {
+	
+	private DataSet data;
+	
+	private Collection<? extends OsmPrimitive> selection;
+	
+	private JToolTip tooltip = new JToolTip();
+	
+	public OsbLayer(DataSet dataSet, String name) {
+		super(name);
+		this.data = dataSet;
+		DataSet.selListeners.add(new SelectionChangedListener() {
+			@Override
+			public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+				selection = newSelection;
+			}
+		});
+		
+		Main.map.mapView.addMouseListener(this);
+	}
+	
+	@Override
+	public Object getInfoComponent() {
+		return getToolTipText();
+	}
+
+	@Override
+	public Component[] getMenuEntries() {
+		return new Component[]{
+                new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
+                new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
+                new JSeparator(),
+                new JMenuItem(new RenameLayerAction(null, this)),
+                new JSeparator(),
+                new JMenuItem(new LayerListPopup.InfoAction(this))};
+	}
+
+	@Override
+	public String getToolTipText() {
+		return Messages.translate(getClass(), "tooltip");
+	}
+
+	@Override
+	public boolean isMergable(Layer other) {
+		return false;
+	}
+
+	@Override
+	public void mergeFrom(Layer from) {}
+
+	@Override
+	public void paint(Graphics g, MapView mv) {
+		for (Node node : data.nodes) {
+			// don't paint deleted nodes
+			if(node.deleted) {
+				continue;
+			}
+			
+			Point p = mv.getPoint(node.eastNorth);
+			
+			ImageIcon icon = OsbPlugin.loadIcon("icon_error16.png");
+			if("1".equals(node.get("state"))) {
+	        	icon = OsbPlugin.loadIcon("icon_valid16.png");
+	        }
+			int width = icon.getIconWidth();
+			int height = icon.getIconHeight();
+			
+			g.drawImage(icon.getImage(), p.x - (width / 2), p.y - (height / 2), new ImageObserver() {
+				@Override
+				public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+					return false;
+				}
+			});
+			
+
+			if(selection != null && selection.contains(node)) {
+				// draw description
+				String desc = node.get("note");
+				if(desc != null) {
+					// format with html
+					StringBuilder sb = new StringBuilder("<html>");
+					//sb.append(desc.replaceAll("\\|", "<br>"));
+					sb.append(desc);
+					sb.append("</html>");
+					desc = sb.toString();
+					
+					// determine tooltip dimensions
+					int tooltipWidth = 0;
+					Rectangle2D fontBounds = null;
+					String[] lines = desc.split("<hr />");
+					for (int i = 0; i < lines.length; i++) {
+						String line = lines[i];
+						fontBounds = g.getFontMetrics().getStringBounds(line, g);
+						tooltipWidth = Math.max(tooltipWidth, (int)fontBounds.getWidth());
+					}
+
+					// FIXME hiehgt calculations doesn't work with all LAFs
+					int lineCount = lines.length;
+					int HR_SIZE = 10;
+					int tooltipHeight = lineCount * (int)fontBounds.getHeight() + HR_SIZE * (lineCount - 1); 
+					
+					// draw description as a tooltip
+					tooltip.setTipText(desc);
+					tooltip.setSize(tooltipWidth+10, tooltipHeight + 6);
+					
+					int tx = p.x + (width / 2) + 5;
+					int ty = (int)(p.y - height / 2);
+					g.translate(tx, ty);
+					tooltip.paint(g);
+					g.translate(-tx, -ty);
+				}
+
+				// draw selection border
+				g.setColor(ColorHelper.html2color(Main.pref.get("color.selected")));
+				g.drawRect(p.x - (width / 2), p.y - (height / 2), 16, 16);
+			}
+		}
+	}
+	
+	@Override
+	public void visitBoundingBox(BoundingXYVisitor v) {}
+
+	@Override
+	public Icon getIcon() {
+		return OsbPlugin.loadIcon("icon_error16.png");
+	}
+	
+	private Node getNearestNode(Point p) {
+		double snapDistance = 10;
+		double minDistanceSq = Double.MAX_VALUE;
+		Node minPrimitive = null;
+		for (Node n : data.nodes) {
+			if (n.deleted || n.incomplete)
+				continue;
+			Point sp = Main.map.mapView.getPoint(n.eastNorth);
+			double dist = p.distanceSq(sp);
+			if (minDistanceSq > dist && p.distance(sp) < snapDistance) {
+				minDistanceSq = p.distanceSq(sp);
+				minPrimitive = n;
+			}
+			// prefer already selected node when multiple nodes on one point
+			else if(minDistanceSq == dist && n.selected && !minPrimitive.selected)
+			{
+				minPrimitive = n;
+			}
+		}
+		return minPrimitive;
+	}
+
+	@Override
+	public void mouseClicked(MouseEvent e) {
+		if(e.getButton() == MouseEvent.BUTTON1) {
+			if(Main.map.mapView.getActiveLayer() == this) {
+				Node n = (Node) getNearestNode(e.getPoint());
+				if(data.nodes.contains(n)) {
+					data.setSelected(n);
+				}
+			}
+		}
+	}
+	
+	@Override
+	public void mousePressed(MouseEvent e) {
+        mayTriggerPopup(e);
+    }
+
+	@Override
+    public void mouseReleased(MouseEvent e) {
+        mayTriggerPopup(e);
+    }
+    
+    private void mayTriggerPopup(MouseEvent e) {
+        if(e.isPopupTrigger()) {
+        	if(Main.map.mapView.getActiveLayer() == this) {
+				Node n = (Node) getNearestNode(e.getPoint());
+				OsbAction.setSelectedNode(n);
+				if(data.nodes.contains(n)) {
+					PopupFactory.createPopup(n).show(e.getComponent(), e.getX(), e.getY());
+				}
+			}
+        }
+    }
+	
+	@Override
+	public void mouseEntered(MouseEvent e) {}
+
+	@Override
+	public void mouseExited(MouseEvent e) {}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbObserver.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbObserver.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbObserver.java	(revision 11157)
@@ -0,0 +1,34 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+
+public interface OsbObserver {
+	public void update(DataSet dataset);
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbPlugin.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbPlugin.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbPlugin.java	(revision 11157)
@@ -0,0 +1,242 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.net.URL;
+import java.util.LinkedList;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+import javax.swing.JToggleButton;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.UploadAction;
+import org.openstreetmap.josm.actions.UploadAction.UploadHook;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.plugins.osb.api.DownloadAction;
+import org.openstreetmap.josm.plugins.osb.gui.OsbDialog;
+
+/**
+ * Shows issues from OpenStreetBugs 
+ *
+ * @author Henrik Niehaus (henrik dot niehaus at gmx dot de)
+ */
+public class OsbPlugin extends Plugin implements LayerChangeListener {
+
+	private DataSet dataSet;
+	
+	private UploadHook uploadHook;
+	
+	private OsbDialog dialog;
+	
+	private OsbLayer layer;
+	
+	public static boolean active = false;
+	
+	private DownloadAction download = new DownloadAction();
+	
+	public OsbPlugin() {
+		initConfig();
+		dataSet = new DataSet();
+		uploadHook = new OsbUploadHook();
+		dialog = new OsbDialog(this);
+		OsbLayer.listeners.add(dialog);
+		OsbLayer.listeners.add(this);
+	}
+	
+	private void initConfig() {
+		String debug = Main.pref.get(ConfigKeys.OSB_API_DISABLED);
+		if(debug == null || debug.length() == 0) {
+			debug = "false";
+			Main.pref.put(ConfigKeys.OSB_API_DISABLED, debug);
+		}
+		
+		String uri = Main.pref.get(ConfigKeys.OSB_API_URI_EDIT);
+		if(uri == null || uri.length() == 0) {
+			uri = "http://openstreetbugs.appspot.com/editPOIexec";
+			Main.pref.put(ConfigKeys.OSB_API_URI_EDIT, uri);
+		}
+		
+		uri = Main.pref.get(ConfigKeys.OSB_API_URI_CLOSE);
+		if(uri == null || uri.length() == 0) {
+			uri = "http://openstreetbugs.appspot.com/closePOIexec";
+			Main.pref.put(ConfigKeys.OSB_API_URI_CLOSE, uri);
+		}
+		
+		uri = Main.pref.get(ConfigKeys.OSB_API_URI_DOWNLOAD);
+		if(uri == null || uri.length() == 0) {
+			uri = "http://openstreetbugs.appspot.com/getBugs";
+			Main.pref.put(ConfigKeys.OSB_API_URI_DOWNLOAD, uri);
+		}
+		
+		uri = Main.pref.get(ConfigKeys.OSB_API_URI_NEW);
+		if(uri == null || uri.length() == 0) {
+			uri = "http://openstreetbugs.appspot.com/addPOIexec";
+			Main.pref.put(ConfigKeys.OSB_API_URI_NEW, uri);
+		}
+		
+		String auto_download = Main.pref.get(ConfigKeys.OSB_AUTO_DOWNLOAD);
+		if(auto_download == null || auto_download.length() == 0) {
+			auto_download = "true";
+			Main.pref.put(ConfigKeys.OSB_AUTO_DOWNLOAD, auto_download);
+		}
+	}
+
+	/**
+	 * Determines the bounds of the current selected layer
+	 * @return
+	 */
+	protected Bounds bounds(){
+		MapView mv = Main.map.mapView;
+		return new Bounds(
+			mv.getLatLon(0, mv.getHeight()),
+			mv.getLatLon(mv.getWidth(), 0));
+	}
+	
+	public void updateData() {
+		// determine the bounds of the currently visible area
+		Bounds bounds = bounds();
+			
+		try {
+			// download the data
+			download.execute(dataSet, bounds);
+
+			// display the parsed data
+			if(!dataSet.nodes.isEmpty()) {
+				updateGui();
+			}
+		} catch (IOException e) {
+			JOptionPane.showMessageDialog(Main.parent, e.getMessage());
+			e.printStackTrace();
+		}
+	}
+	
+	public void updateGui() {
+		// update dialog
+		dialog.update(dataSet);
+		
+		// create a new layer if necessary
+		updateLayer(dataSet);
+		
+		// repaint view, so that changes get visible
+		Main.map.mapView.repaint();
+	}
+	
+	private void updateLayer(DataSet osbData) {
+		if(layer == null) {
+			layer = new OsbLayer(osbData, "OpenStreetBugs");
+			Main.main.addLayer(layer);
+		}
+	}
+
+	@Override
+	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+		if (oldFrame==null && newFrame!=null) { // map frame added
+			// add the dialog
+			newFrame.addToggleDialog(dialog);
+			
+			// add the upload hook
+			LinkedList<UploadHook> hooks = ((UploadAction) Main.main.menu.upload).uploadHooks;
+			hooks.add(0, uploadHook);
+			
+			// add a listener to the plugin toggle button
+			final JToggleButton toggle = (JToggleButton) dialog.action.button;
+			active = toggle.isSelected();
+			toggle.addActionListener(new ActionListener() {
+				private boolean download = true;
+
+				@Override
+				public void actionPerformed(ActionEvent e) {
+					active = toggle.isSelected();
+					if (toggle.isSelected() && download) {
+						Main.worker.execute(new Runnable() {
+							@Override
+							public void run() {
+								updateData();
+							}
+						});
+						download = false;
+					}
+				}
+			});
+		} else if (oldFrame!=null && newFrame==null ) { // map frame removed
+			
+		}
+	}
+	
+	public static ImageIcon loadIcon(String name) {
+		URL url = OsbPlugin.class.getResource("/images/".concat(name));
+		return new ImageIcon(url);
+	}
+
+	@Override
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
+
+	@Override
+	public void layerAdded(Layer newLayer) {
+		if(newLayer instanceof OsmDataLayer) {
+			active = ((JToggleButton)dialog.action.button).isSelected();
+			
+			// start the auto download loop
+			OsbDownloadLoop.getInstance().setPlugin(this);
+		}
+	}
+
+	@Override
+	public void layerRemoved(Layer oldLayer) {
+		if(oldLayer == layer) {
+			layer = null;
+		}
+	}
+
+	public OsbLayer getLayer() {
+		return layer;
+	}
+
+	public void setLayer(OsbLayer layer) {
+		this.layer = layer;
+	}
+
+	public DataSet getDataSet() {
+		return dataSet;
+	}
+
+	public void setDataSet(DataSet dataSet) {
+		this.dataSet = dataSet;
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbUploadHook.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbUploadHook.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/OsbUploadHook.java	(revision 11157)
@@ -0,0 +1,68 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.UploadAction.UploadHook;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+public class OsbUploadHook implements UploadHook {
+
+	@Override
+	public boolean checkUpload(Collection<OsmPrimitive> add, Collection<OsmPrimitive> update,
+			Collection<OsmPrimitive> delete) 
+	{
+		boolean containsOsbData = checkOpenStreetBugs(add);
+		containsOsbData |= checkOpenStreetBugs(update);
+		containsOsbData |= checkOpenStreetBugs(delete);
+		if(containsOsbData) {
+			JOptionPane.showMessageDialog(Main.parent, 
+				"<html>The selected data contains data from OpenStreetBugs.<br>" +
+				"You cannot upload these data. Maybe you have selected the wrong layer?", 
+				"Warning", JOptionPane.WARNING_MESSAGE);
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	private boolean checkOpenStreetBugs(Collection<OsmPrimitive> osmPrimitives) {
+		for (Iterator<OsmPrimitive> iterator = osmPrimitives.iterator(); iterator.hasNext();) {
+			OsmPrimitive osmPrimitive = iterator.next();
+			if(osmPrimitive.get("openstreetbug") != null) {
+				return true;
+			}
+		}
+		return false;
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/CloseAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/CloseAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/CloseAction.java	(revision 11157)
@@ -0,0 +1,68 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.api;
+
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.ConfigKeys;
+import org.openstreetmap.josm.plugins.osb.api.util.HttpUtils;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+
+public class CloseAction {
+	
+	private final String CHARSET = "UTF-8";
+	
+	public void execute(Node n) throws IOException {
+		// create the URI for the data download
+		String uri = Main.pref.get(ConfigKeys.OSB_API_URI_CLOSE);
+		String post = new StringBuilder("id=")
+			.append(n.get("id"))
+			.toString();
+		
+		String result = null;
+		if(Main.pref.getBoolean(ConfigKeys.OSB_API_DISABLED)) {
+			result = "ok";
+		} else {
+			result = HttpUtils.post(uri, null, post, CHARSET);
+		}
+		
+		if("ok".equalsIgnoreCase(result)) {
+			n.put("state", "1");
+			Main.map.mapView.repaint();
+		} else {
+			JOptionPane.showMessageDialog(Main.parent,
+					Messages.translate(getClass(), "error_occured", new Object[] {result}),
+					Messages.translate(getClass(), "error_occured_title"),
+					JOptionPane.ERROR_MESSAGE);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/DownloadAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/DownloadAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/DownloadAction.java	(revision 11157)
@@ -0,0 +1,94 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.api;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.ConfigKeys;
+import org.openstreetmap.josm.plugins.osb.api.util.HttpUtils;
+
+public class DownloadAction {
+	
+	private final String CHARSET = "UTF-8";
+	
+	public void execute(DataSet dataset, Bounds bounds) throws IOException {
+		// create the URI for the data download
+		String uri = Main.pref.get(ConfigKeys.OSB_API_URI_DOWNLOAD);
+
+		// check zoom level
+		if(Main.map.mapView.zoom() > 15 || Main.map.mapView.zoom() < 9) {
+			return;
+		} 
+		
+		// add query params to the uri
+		StringBuilder sb = new StringBuilder(uri)
+			.append("?b=").append(bounds.min.lat())
+			.append("&t=").append(bounds.max.lat())
+			.append("&l=").append(bounds.min.lon())
+			.append("&r=").append(bounds.max.lon());
+		uri = sb.toString();
+
+		// download the data
+		String content = HttpUtils.get(uri, null, CHARSET);
+		
+		// clear dataset
+		dataset.nodes.clear();
+		dataset.relations.clear();
+		dataset.ways.clear();
+		
+		// parse the data
+		parseData(dataset, content);
+	}
+
+	private void parseData(DataSet dataSet, String content) {
+		String idPattern = "\\d+";
+		String floatPattern = "\\d+\\.\\d+";
+		String pattern = "putAJAXMarker\\(("+idPattern+"),("+floatPattern+"),("+floatPattern+"),\"(.*)\",([01])\\)";
+		Pattern p = Pattern.compile(pattern);
+		Matcher m = p.matcher(content);
+		while(m.find()) {
+			double lat = Double.parseDouble(m.group(3));
+			double lon = Double.parseDouble(m.group(2));
+			LatLon latlon = new LatLon(lat, lon); 
+			Node osmNode = new Node(latlon);
+			osmNode.id = Long.parseLong(m.group(1));
+			osmNode.put("id", m.group(1));
+			osmNode.put("note", m.group(4));
+			osmNode.put("openstreetbug", "FIXME");
+			osmNode.put("state", m.group(5));
+			dataSet.addPrimitive(osmNode);
+		} 
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/EditAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/EditAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/EditAction.java	(revision 11157)
@@ -0,0 +1,73 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.api;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.ConfigKeys;
+import org.openstreetmap.josm.plugins.osb.api.util.HttpUtils;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+
+public class EditAction {
+	
+	private final String CHARSET = "UTF-8";
+	
+	public void execute(Node n, String comment) throws IOException {
+		// create the URI for the data download
+		String uri = Main.pref.get(ConfigKeys.OSB_API_URI_EDIT);
+		String post = new StringBuilder("id=")
+			.append(n.get("id"))
+			.append("&text=")
+			.append(URLEncoder.encode(comment, CHARSET))
+			.toString();
+		
+		String result = null;
+		if(Main.pref.getBoolean(ConfigKeys.OSB_API_DISABLED)) {
+			result = "ok";
+		} else {
+			result = HttpUtils.post(uri, null, post, CHARSET);
+		}
+
+		if("ok".equalsIgnoreCase(result)) {
+			String desc = n.get("note");
+			desc = desc.concat("<hr />").concat(comment);
+			n.put("note", desc);
+			Main.map.mapView.repaint();
+		} else {
+			JOptionPane.showMessageDialog(Main.parent,
+					Messages.translate(getClass(), "error_occured", new Object[] {result}),
+					Messages.translate(getClass(), "error_occured_title"),
+					JOptionPane.ERROR_MESSAGE);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/NewAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/NewAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/NewAction.java	(revision 11157)
@@ -0,0 +1,77 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.api;
+
+import java.awt.Point;
+import java.io.IOException;
+import java.net.URLEncoder;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.ConfigKeys;
+import org.openstreetmap.josm.plugins.osb.api.util.HttpUtils;
+
+public class NewAction {
+	
+	private final String CHARSET = "UTF-8";
+	
+	public Node execute(Point p, String text) throws IOException {
+		// where has the issue been added
+		LatLon latlon = Main.map.mapView.getLatLon(p.x, p.y);
+		
+		// create the URI for the data download
+		String uri = Main.pref.get(ConfigKeys.OSB_API_URI_NEW);
+		
+		String post = new StringBuilder("lon=")
+			.append(latlon.lon())
+			.append("&lat=")
+			.append(latlon.lat())
+			.append("&text=")
+			.append(URLEncoder.encode(text, CHARSET))
+			.toString();
+		
+		String result = null;
+		if(Main.pref.getBoolean(ConfigKeys.OSB_API_DISABLED)) {
+			result = "ok";
+		} else {
+			result = HttpUtils.post(uri, null, post, CHARSET);
+		}
+		
+		if(!"ok".equalsIgnoreCase(result)) {
+			throw new RuntimeException("Couldn't create new bug");
+		}
+		
+		Node osmNode = new Node(latlon);
+		osmNode.put("id", "-1");
+		osmNode.put("note", text);
+		osmNode.put("openstreetbug", "FIXME");
+		osmNode.put("state", "0");
+		return osmNode;
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/util/HttpResponse.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/util/HttpResponse.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/util/HttpResponse.java	(revision 11157)
@@ -0,0 +1,59 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.api.util;
+
+import java.util.List;
+import java.util.Map;
+
+public class HttpResponse {
+    private String content;
+
+    private Map<String, List<String>> header;
+
+    public HttpResponse(String content, Map<String, List<String>> header) {
+        super();
+        this.content = content;
+        this.header = header;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Map<String, List<String>> getHeader() {
+        return header;
+    }
+
+    public void setHeader(Map<String, List<String>> header) {
+        this.header = header;
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/util/HttpUtils.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/util/HttpUtils.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/api/util/HttpUtils.java	(revision 11157)
@@ -0,0 +1,170 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.api.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class HttpUtils {
+    public static String get(String url, Map<String, String> headers, String charset) throws IOException {
+        URL page = new URL(url);
+        URLConnection con = page.openConnection();
+        if(headers != null) {
+            for (Iterator<Entry<String,String>> iterator = headers.entrySet().iterator(); iterator.hasNext();) {
+                Entry<String, String> entry = iterator.next();
+                con.setRequestProperty(entry.getKey(), entry.getValue());
+            }
+        }
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        int length = -1;
+        byte[] b = new byte[1024];
+        InputStream in = con.getInputStream();
+        while( (length = in.read(b)) > 0 ) {
+            bos.write(b, 0, length);
+        }
+        
+        return new String(bos.toByteArray(), charset);
+    }
+    
+    public static HttpResponse getResponse(String url, Map<String, String> headers, String charset) throws IOException {
+        URL page = new URL(url);
+        URLConnection con = page.openConnection();
+        if(headers != null) {
+            for (Iterator<Entry<String,String>> iterator = headers.entrySet().iterator(); iterator.hasNext();) {
+                Entry<String, String> entry = iterator.next();
+                con.setRequestProperty(entry.getKey(), entry.getValue());
+            }
+        }
+        
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        int length = -1;
+        byte[] b = new byte[1024];
+        InputStream in = con.getInputStream();
+        while( (length = in.read(b)) > 0 ) {
+            bos.write(b, 0, length);
+        }
+        
+        HttpResponse response = new HttpResponse(new String(bos.toByteArray(), charset), con.getHeaderFields());
+        return response;
+    }
+    
+    /**
+     * 
+     * @param url
+     * @param headers
+     * @param content the post body
+     * @param responseCharset the expected charset of the response
+     * @return
+     * @throws IOException
+     */
+    public static String post(String url, Map<String, String> headers, String content, String responseCharset) throws IOException {
+        // initialize the connection
+        URL page = new URL(url);
+        URLConnection con = page.openConnection();
+        con.setDoOutput(true);
+        if(headers != null) {
+            for (Iterator<Entry<String,String>> iterator = headers.entrySet().iterator(); iterator.hasNext();) {
+                Entry<String, String> entry = iterator.next();
+                con.setRequestProperty(entry.getKey(), entry.getValue());
+            }
+        }
+        
+        //send the post
+        OutputStream os = con.getOutputStream();
+        os.write(content.getBytes("UTF-8"));
+        os.flush();
+        
+        // read the response
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        int length = -1;
+        byte[] b = new byte[1024];
+        InputStream in = con.getInputStream();
+        while( (length = in.read(b)) > 0 ) {
+            bos.write(b, 0, length);
+        }
+        
+        return new String(bos.toByteArray(), responseCharset);
+    }
+    
+    /**
+     * Adds a parameter to a given URI
+     * @param uri
+     * @param param
+     * @param value
+     * @return
+     */
+    public static String addParameter(String uri, String param, String value) {
+        StringBuilder sb = new StringBuilder(uri);
+        if(uri.contains("?")) {
+            sb.append('&');
+        } else {
+            sb.append('?');
+        }
+        
+        sb.append(param);
+        sb.append('=');
+        sb.append(value);
+        
+        return sb.toString();
+    }
+
+    public static Map<String, List<String>> head(String url, Map<String, String> headers, String charset) throws IOException {
+        URL page = new URL(url);
+        URLConnection con = page.openConnection();
+        if(headers != null) {
+            for (Iterator<Entry<String,String>> iterator = headers.entrySet().iterator(); iterator.hasNext();) {
+                Entry<String, String> entry = iterator.next();
+                con.setRequestProperty(entry.getKey(), entry.getValue());
+            }
+        }
+        
+        return con.getHeaderFields();
+    }
+    
+    public static String getHeaderField(Map<String, List<String>> headers, String headerField) {
+        if(!headers.containsKey(headerField)) {
+            return null;
+        }
+        
+        List<String> value = headers.get(headerField);
+        if(value.size() == 1) {
+            return value.get(0);
+        } else {
+            throw new RuntimeException("Header contains several values and cannot be mapped to a single String");
+        }
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbDialog.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbDialog.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbDialog.java	(revision 11157)
@@ -0,0 +1,307 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui;
+
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.swing.Action;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JToggleButton;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.gui.layer.DataChangeListener;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
+import org.openstreetmap.josm.plugins.osb.OsbObserver;
+import org.openstreetmap.josm.plugins.osb.OsbPlugin;
+import org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction;
+import org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction;
+import org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction;
+import org.openstreetmap.josm.plugins.osb.gui.action.OsbAction;
+import org.openstreetmap.josm.plugins.osb.gui.action.OsbActionObserver;
+import org.openstreetmap.josm.plugins.osb.gui.action.PopupFactory;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+import org.openstreetmap.josm.tools.ShortCut;
+
+public class OsbDialog extends ToggleDialog implements OsbObserver, ListSelectionListener, LayerChangeListener,
+		DataChangeListener, MouseListener, OsbActionObserver {
+
+	private DefaultListModel model;
+	private JList list;
+	private OsbPlugin osbPlugin;
+	private boolean fireSelectionChanged = true;
+	private JButton refresh;
+	private JButton addComment = new JButton(new AddCommentAction());
+	private JButton closeIssue = new JButton(new CloseIssueAction());
+	private JToggleButton newIssue = new JToggleButton();
+	
+	public OsbDialog(final OsbPlugin plugin) {
+		super("OpenStreetBugs", "icon_error22", 
+				Messages.translate(OsbDialog.class, "tooltip"), 
+				ShortCut.registerShortCut(
+						Messages.translate(OsbDialog.class, "shortcut"), 
+						Messages.translate(OsbDialog.class, "shortcut"), 
+						KeyEvent.VK_O, ShortCut.GROUP_MENU), 
+				150);
+		
+		osbPlugin = plugin;
+		
+		model = new DefaultListModel();
+		list = new JList(model);
+		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		list.addListSelectionListener(this);
+		list.addMouseListener(this);
+		list.setCellRenderer(new OsbListCellRenderer());
+		add(new JScrollPane(list), BorderLayout.CENTER);
+
+		// create dialog buttons
+		JPanel buttonPanel = new JPanel(new GridLayout(2, 2));
+		add(buttonPanel, BorderLayout.SOUTH);
+		refresh = new JButton(Messages.translate(OsbDialog.class, "refresh"));
+		refresh.setToolTipText(Messages.translate(OsbDialog.class, "refresh"));
+		refresh.setIcon(OsbPlugin.loadIcon("view-refresh22.png"));
+		refresh.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				// check zoom level
+				if(Main.map.mapView.zoom() > 15 || Main.map.mapView.zoom() < 9) {
+					JOptionPane.showMessageDialog(Main.parent, 
+							Messages.translate(OsbDialog.class, "out_of_bounds"),
+							Messages.translate(OsbDialog.class, "out_of_bounds_title"), 
+							JOptionPane.INFORMATION_MESSAGE);
+					return;
+				}
+				
+				plugin.updateData();
+			}
+		});
+		
+		addComment.setEnabled(false);
+		addComment.setToolTipText((String) addComment.getAction().getValue(Action.NAME));
+		addComment.setIcon(OsbPlugin.loadIcon("add_comment22.png"));
+		closeIssue.setEnabled(false);
+		closeIssue.setToolTipText((String) closeIssue.getAction().getValue(Action.NAME));
+		closeIssue.setIcon(OsbPlugin.loadIcon("icon_valid22.png"));
+		NewIssueAction nia = new NewIssueAction(newIssue, osbPlugin);
+		newIssue.setAction(nia);
+		newIssue.setToolTipText((String) newIssue.getAction().getValue(Action.NAME));
+		newIssue.setIcon(OsbPlugin.loadIcon("icon_error_add22.png"));
+
+		buttonPanel.add(refresh);
+		buttonPanel.add(newIssue);
+		buttonPanel.add(addComment);
+		buttonPanel.add(closeIssue);
+		
+		// add a selection listener to the data
+		DataSet.selListeners.add(new SelectionChangedListener() {
+			@Override
+			public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+				fireSelectionChanged = false;
+				list.clearSelection();
+				for (OsmPrimitive osmPrimitive : newSelection) {
+					for (int i = 0; i < model.getSize(); i++) {
+						OsbListItem item = (OsbListItem) model.get(i);
+						if(item.getNode() == osmPrimitive) {
+							list.addSelectionInterval(i, i);
+						}
+					}
+				}
+				fireSelectionChanged = true;
+			}
+		});
+		
+		AddCommentAction.addActionObserver(this);
+		CloseIssueAction.addActionObserver(this);
+	}
+
+	@Override
+	public synchronized void update(final DataSet dataset) {
+		Node lastNode = OsbAction.getSelectedNode();
+		model = new DefaultListModel();
+		List<Node> sortedList = new ArrayList<Node>(dataset.nodes);
+		Collections.sort(sortedList, new BugComparator());
+		
+		for (Node node : sortedList) {
+			if (!node.deleted) {
+				model.addElement(new OsbListItem(node));
+			}
+		}
+		list.setModel(model);
+		list.setSelectedValue(new OsbListItem(lastNode), true);
+	}
+
+	@Override
+	public void valueChanged(ListSelectionEvent e) {
+		if(list.getSelectedValues().length == 0) {
+			addComment.setEnabled(false);
+			closeIssue.setEnabled(false);
+			OsbAction.setSelectedNode(null);
+			return;
+		}
+		
+		List<OsmPrimitive> selected = new ArrayList<OsmPrimitive>();
+		for (Object listItem : list.getSelectedValues()) {
+			Node node = ((OsbListItem) listItem).getNode();
+			selected.add(node);
+
+			if ("1".equals(node.get("state"))) {
+				addComment.setEnabled(false);
+				closeIssue.setEnabled(false);
+			} else {
+				addComment.setEnabled(true);
+				closeIssue.setEnabled(true);
+			}
+			
+			OsbAction.setSelectedNode(node);
+
+			scrollToSelected(node);
+			
+			if (fireSelectionChanged) {
+				Main.ds.setSelected(selected);
+			}
+		}
+	}
+
+	private void scrollToSelected(Node node) {
+		for (int i = 0; i < model.getSize();i++) {
+			Node current = ((OsbListItem)model.get(i)).getNode();
+			if(current.id == node.id) {
+				list.scrollRectToVisible(list.getCellBounds(i, i));
+				list.setSelectedIndex(i);
+				return;
+			}
+		}
+	}
+
+	@Override
+	public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
+
+	@Override
+	public void layerAdded(Layer newLayer) {
+		if(newLayer == osbPlugin.getLayer()) {
+			update(osbPlugin.getDataSet());
+			Main.map.mapView.moveLayer(newLayer, 0);
+		}
+	}
+
+	@Override
+	public void layerRemoved(Layer oldLayer) {
+		if(oldLayer == osbPlugin.getLayer()) {
+			model.removeAllElements();
+		}
+	}
+
+	@Override
+	public void dataChanged(OsmDataLayer l) {
+		update(l.data);
+	}
+	
+	public void zoomToNode(Node node) {
+		double scale = Main.map.mapView.getScale();
+		Main.map.mapView.zoomTo(node.eastNorth, scale);
+    }
+
+	@Override
+	public void mouseClicked(MouseEvent e) {
+		if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
+			OsbListItem item = (OsbListItem)list.getSelectedValue();
+			zoomToNode(item.getNode());
+		}
+	}
+	
+	@Override
+	public void mousePressed(MouseEvent e) {
+        mayTriggerPopup(e);
+    }
+
+	@Override
+    public void mouseReleased(MouseEvent e) {
+        mayTriggerPopup(e);
+    }
+    
+    private void mayTriggerPopup(MouseEvent e) {
+        if(e.isPopupTrigger()) {
+        	int selectedRow = list.locationToIndex(e.getPoint());
+        	list.setSelectedIndex(selectedRow);
+			Node n = ((OsbListItem)list.getSelectedValue()).getNode();
+			OsbAction.setSelectedNode(n);
+			PopupFactory.createPopup(n).show(e.getComponent(), e.getX(), e.getY());
+        }
+    }
+	
+	@Override
+	public void mouseEntered(MouseEvent e) {}
+
+	@Override
+	public void mouseExited(MouseEvent e) {}
+
+	@Override
+	public void actionPerformed(OsbAction action) {
+		if(action instanceof AddCommentAction || action instanceof CloseIssueAction) {
+			update(osbPlugin.getDataSet());
+		}
+	}
+	
+	private class BugComparator implements Comparator<Node> {
+		@Override
+		public int compare(Node o1, Node o2) {
+			String state1 = o1.get("state");
+			String state2 = o2.get("state");
+			if(state1.equals(state2)) {
+				return o1.get("note").compareTo(o2.get("note"));
+			}
+			return state1.compareTo(state2);
+		}
+		
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbListCellRenderer.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbListCellRenderer.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbListCellRenderer.java	(revision 11157)
@@ -0,0 +1,83 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.OsbPlugin;
+
+public class OsbListCellRenderer implements ListCellRenderer {
+
+    private Color background = Color.WHITE;
+    private Color altBackground = new Color(250, 250, 220);
+    
+	@Override
+	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+			boolean cellHasFocus) {
+		
+		JLabel label = new JLabel();
+		label.setOpaque(true);
+		
+        if(isSelected) {
+        	label.setBackground(UIManager.getColor("List.selectionBackground"));
+        } else {
+        	label.setBackground(index % 2 == 0 ? background : altBackground);
+        }
+        
+        OsbListItem item = (OsbListItem) value;
+        Node n = item.getNode();
+        Icon icon = null;
+        if("0".equals(n.get("state"))) {
+        	icon = OsbPlugin.loadIcon("icon_error16.png");
+        } else if("1".equals(n.get("state"))) {
+        	icon = OsbPlugin.loadIcon("icon_valid16.png");
+        }
+        label.setIcon(icon);
+        String text = n.get("note");
+        if(text.indexOf("<hr />") > 0) {
+        	text = text.substring(0, text.indexOf("<hr />"));
+        }
+        label.setText(text);
+		
+		Dimension d = label.getPreferredSize();
+		d.height += 10;
+		label.setPreferredSize(d);
+		
+		return label;
+	}
+
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbListItem.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbListItem.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/OsbListItem.java	(revision 11157)
@@ -0,0 +1,71 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui;
+
+import org.openstreetmap.josm.data.osm.Node;
+
+public class OsbListItem {
+	private Node node;
+	
+	public OsbListItem(Node node) {
+		super();
+		this.node = node;
+	}
+
+	public Node getNode() {
+		return node;
+	}
+
+	public void setNode(Node node) {
+		this.node = node;
+	}
+	
+	@Override
+	public String toString() {
+		if(node.get("note") != null) {
+			StringBuilder sb = new StringBuilder("<html>");
+			sb.append(node.get("note").replaceAll("\\|", "<br>"));
+			sb.append("</html>");
+			return sb.toString();
+		} else {
+			return "N/A";
+		}
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if(obj instanceof OsbListItem) {
+			OsbListItem other = (OsbListItem)obj; 
+			if(getNode() != null && other.getNode() != null) {
+				return getNode().id == other.getNode().id;
+			}
+		}
+		
+		return false;
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/AddCommentAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/AddCommentAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/AddCommentAction.java	(revision 11157)
@@ -0,0 +1,66 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.osb.ConfigKeys;
+import org.openstreetmap.josm.plugins.osb.api.EditAction;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+
+public class AddCommentAction extends OsbAction {
+
+	private EditAction editAction = new EditAction();
+	
+	public AddCommentAction() {
+		super(Messages.translate(AddCommentAction.class, "name"));
+	}
+	
+	@Override
+	protected void doActionPerformed(ActionEvent e) throws Exception {
+		// get the user nickname
+		String nickname = Main.pref.get(ConfigKeys.OSB_NICKNAME);
+		if(nickname == null || nickname.length() == 0) {
+			nickname = JOptionPane.showInputDialog(Main.parent, Messages.translate(getClass(), "enter_nickname"));
+			if(nickname == null) {
+				nickname = "NoName";
+			} else {
+				Main.pref.put(ConfigKeys.OSB_NICKNAME, nickname);
+			}
+		}
+		
+		String comment = JOptionPane.showInputDialog(Main.parent, Messages.translate(getClass(), "enter_comment"));
+		if(comment != null) {
+			comment = comment.concat(" [").concat(nickname).concat("]");
+			editAction.execute(getSelectedNode(), comment);
+		}
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/CloseIssueAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/CloseIssueAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/CloseIssueAction.java	(revision 11157)
@@ -0,0 +1,58 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.action;
+
+import java.awt.event.ActionEvent;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.osb.api.CloseAction;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+
+public class CloseIssueAction extends OsbAction {
+
+	private CloseAction closeAction = new CloseAction();
+	
+	public CloseIssueAction() {
+		super(Messages.translate(CloseIssueAction.class, "name"));
+	}
+	
+	@Override
+	protected void doActionPerformed(ActionEvent e) throws IOException {
+		int result = JOptionPane.showConfirmDialog(Main.parent,
+				Messages.translate(getClass(), "question"),
+				Messages.translate(getClass(), "title"),
+				JOptionPane.YES_NO_OPTION);
+		
+		if(result == JOptionPane.YES_OPTION) {
+			closeAction.execute(getSelectedNode());
+		} 
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/NewIssueAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/NewIssueAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/NewIssueAction.java	(revision 11157)
@@ -0,0 +1,121 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.action;
+
+import java.awt.Cursor;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+import javax.swing.JToggleButton;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.ConfigKeys;
+import org.openstreetmap.josm.plugins.osb.OsbPlugin;
+import org.openstreetmap.josm.plugins.osb.api.NewAction;
+import org.openstreetmap.josm.plugins.osb.i18n.Messages;
+
+public class NewIssueAction extends OsbAction implements MouseListener {
+
+	private NewAction newAction = new NewAction();
+	
+	private JToggleButton button;
+	
+	private OsbPlugin plugin;
+	
+	public NewIssueAction(JToggleButton button, OsbPlugin plugin) {
+		super(Messages.translate(NewIssueAction.class, "name"));
+		this.button = button;
+		this.plugin = plugin;
+	}
+	
+	@Override
+	protected void doActionPerformed(ActionEvent e) throws IOException {
+		if(button.isSelected()) {
+			Main.map.mapView.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
+			Main.map.mapView.addMouseListener(this);
+		} else {
+			reset();
+		}
+	}
+
+	private void reset() {
+		Main.map.mapView.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+		Main.map.mapView.removeMouseListener(this);
+		button.setSelected(false);
+	}
+
+	@Override
+	public void mouseClicked(MouseEvent e) {
+		addNewIssue(e);
+	}
+
+	@Override
+	public void mouseEntered(MouseEvent e) {}
+
+	@Override
+	public void mouseExited(MouseEvent e) {}
+
+	@Override
+	public void mousePressed(MouseEvent e) {
+		addNewIssue(e);
+	}
+
+	private void addNewIssue(MouseEvent e) {
+		String result = JOptionPane.showInputDialog(Main.parent,
+				Messages.translate(getClass(), "question"),
+				Messages.translate(getClass(), "title"),
+				JOptionPane.QUESTION_MESSAGE);
+		
+		if(result != null && !result.isEmpty()) {
+			try {
+				Node n = newAction.execute(e.getPoint(), result);
+				plugin.getDataSet().addPrimitive(n);
+				if(Main.pref.getBoolean(ConfigKeys.OSB_API_DISABLED)) {
+					plugin.updateGui();
+				} else {
+					plugin.updateData();
+				}
+			} catch (Exception e1) {
+				e1.printStackTrace();
+				JOptionPane.showMessageDialog(Main.parent,
+						Messages.translate(getClass(), "error_occured", new Object[] {result}),
+						Messages.translate(getClass(), "error_occured_title"),
+						JOptionPane.ERROR_MESSAGE);
+			}
+		}
+		
+		reset();
+	}
+
+	@Override
+	public void mouseReleased(MouseEvent e) {}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/OsbAction.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/OsbAction.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/OsbAction.java	(revision 11157)
@@ -0,0 +1,78 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+
+import org.openstreetmap.josm.data.osm.Node;
+
+public abstract class OsbAction extends AbstractAction {
+
+	private static List<OsbActionObserver> observers = new ArrayList<OsbActionObserver>(); 
+	
+	private static Node selectedNode;
+	
+	public OsbAction(String name) {
+		super(name);
+	}
+
+	public static Node getSelectedNode() {
+		return selectedNode;
+	}
+
+	public static void setSelectedNode(Node selectedNode) {
+		OsbAction.selectedNode = selectedNode;
+	}
+	
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		try {
+			doActionPerformed(e);
+			for (OsbActionObserver obs : observers) {
+				obs.actionPerformed(this);
+			}
+		} catch (Exception e1) {
+			System.err.println("Couldn't execute action " + getClass().getSimpleName());
+			e1.printStackTrace();
+		}
+	}
+	
+	protected abstract void doActionPerformed(ActionEvent e) throws Exception;
+	
+	public static void addActionObserver(OsbActionObserver obs) {
+		observers.add(obs);
+	}
+	
+	public static void removeActionObserver(OsbActionObserver obs) {
+		observers.remove(obs);
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/OsbActionObserver.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/OsbActionObserver.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/OsbActionObserver.java	(revision 11157)
@@ -0,0 +1,32 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.action;
+
+public interface OsbActionObserver {
+	public void actionPerformed(OsbAction action);
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/PopupFactory.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/PopupFactory.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/gui/action/PopupFactory.java	(revision 11157)
@@ -0,0 +1,84 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.gui.action;
+
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.plugins.osb.OsbPlugin;
+
+public class PopupFactory {
+	
+	private static JPopupMenu issuePopup;
+	private static JPopupMenu fixedPopup;
+	
+	public static synchronized JPopupMenu createPopup(Node node) {
+		if("0".equals(node.get("state"))) {
+			return getIssuePopup();
+		} else if("1".equals(node.get("state"))) {
+			return getFixedPopup();
+		} else {
+			throw new RuntimeException("Unknown issue state");
+		}
+	}
+
+	private static JPopupMenu getIssuePopup() {
+		if(issuePopup == null) {
+			issuePopup = new JPopupMenu();
+			JMenuItem add = new JMenuItem();
+			add.setAction(new AddCommentAction());
+			add.setIcon(OsbPlugin.loadIcon("add_comment16.png"));
+			issuePopup.add(add);
+			JMenuItem close = new JMenuItem();
+			close.setAction(new CloseIssueAction());
+			close.setIcon(OsbPlugin.loadIcon("icon_valid16.png"));
+			issuePopup.add(close);
+		}
+		return issuePopup;
+	}
+	
+	private static JPopupMenu getFixedPopup() {
+		if(fixedPopup == null) {
+			fixedPopup = new JPopupMenu();
+			JMenuItem add = new JMenuItem();
+			AddCommentAction aca = new AddCommentAction();
+			aca.setEnabled(false);
+			add.setAction(aca);
+			add.setIcon(OsbPlugin.loadIcon("add_comment16.png"));
+			JMenuItem close = new JMenuItem();
+			CloseIssueAction cia = new CloseIssueAction();
+			cia.setEnabled(false);
+			close.setAction(cia);
+			close.setIcon(OsbPlugin.loadIcon("icon_valid16.png"));
+			fixedPopup.add(add);
+			fixedPopup.add(close);
+		}
+		return fixedPopup;
+	}
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/Messages.java
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/Messages.java	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/Messages.java	(revision 11157)
@@ -0,0 +1,94 @@
+/* Copyright (c) 2008, Henrik Niehaus
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, 
+ *    this list of conditions and the following disclaimer in the documentation 
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its 
+ *    contributors may be used to endorse or promote products derived from this 
+ *    software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.openstreetmap.josm.plugins.osb.i18n;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+
+public class Messages {
+    private ResourceBundle bundle;
+
+    private static Messages instance;
+
+    private Messages() {
+        try {
+            loadBundle(Locale.getDefault());
+        } catch (IOException e) {
+        	e.printStackTrace();
+            try {
+                loadBundle(Locale.ENGLISH);
+            } catch (IOException e1) {
+                System.err.println("Couldn't load default resource bundle");
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static ResourceBundle getBundle() {
+        if (instance == null) {
+            instance = new Messages();
+        }
+        return instance.getResourceBundle();
+    }
+    
+    @SuppressWarnings("unchecked")
+    public static String translate(Class clazz, String key) {
+        key = clazz.getName() + "." + key;
+        return getBundle().getString(key);
+    }
+    
+    private void loadBundle(Locale locale) throws IOException {
+        InputStream in = Messages.class.getResourceAsStream("language_" + locale.toString() + ".properties");
+        bundle = new PropertyResourceBundle(in);
+    }
+    
+    private ResourceBundle getResourceBundle() {
+        return bundle;
+    }
+
+    /**
+     * Translates a given key and replaces placeholders with the given parameters.
+     * @param clazz
+     * @param key
+     * @param params
+     *      An Object[] of the params, which will be used to replace the placeholders.
+     *      The message has to be compatible to {@link MessageFormat}
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public static String translate(Class clazz, String key, Object[] params) {
+        String mesg = translate(clazz, key);
+        MessageFormat format = new MessageFormat("");
+        format.applyPattern(mesg);
+        return format.format(params);
+    }
+}
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/language_de.properties
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/language_de.properties	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/language_de.properties	(revision 11157)
@@ -0,0 +1,22 @@
+
+org.openstreetmap.josm.plugins.osb.OsbLayer.tooltip                              = Zeigt OpenStreetBugs-Eintr\u00E4ge an
+org.openstreetmap.josm.plugins.osb.api.CloseAction.error_occured                 = Es ist ein Fehler aufgetreten. {0}
+org.openstreetmap.josm.plugins.osb.api.CloseAction.error_occured_title           = Fehler
+org.openstreetmap.josm.plugins.osb.api.EditAction.error_occured                  = Es ist ein Fehler aufgetreten. {0}
+org.openstreetmap.josm.plugins.osb.api.EditAction.error_occured_title            = Fehler
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.out_of_bounds                   = Der sichtbare Bereich ist entweder zu klein oder zu gro\u00DF, um Daten von OpenStreetBugs abzurufen
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.out_of_bounds_title             = Warnung
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.refresh                         = Neu laden
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.shortcut                        = OpenStreetBugs \u00F6ffnen
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.tooltip                         = \u00D6ffnet das OpenStreetBugs-Fenster und aktiviert den automatische Download
+org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction.enter_comment     = Gib Deinen Kommentar ein
+org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction.enter_nickname    = Bitte einen Benutzernamen angeben
+org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction.name              = Kommentar hinzuf\u00FCgen
+org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction.name              = Problem als erledigt markieren
+org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction.question          = Soll diese Problem wirklich als "erledigt" markiert werden?
+org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction.title             = Wirklich schlie\u00DFen?
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.error_occured       = Es ist ein Fehler aufgetreten. {0}
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.error_occured_title = Fehler
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.name                = Neuer Fehler
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.question            = Beschreibe den Fehler m\u00F6glichst genau.
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.title               = Fehler anlegen
Index: /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/language_en.properties
===================================================================
--- /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/language_en.properties	(revision 11157)
+++ /applications/editors/josm/plugins/openstreetbugs/src/org/openstreetmap/josm/plugins/osb/i18n/language_en.properties	(revision 11157)
@@ -0,0 +1,22 @@
+
+org.openstreetmap.josm.plugins.osb.OsbLayer.tooltip                              = Dsiplays OpenStreetBugs issues
+org.openstreetmap.josm.plugins.osb.api.CloseAction.error_occured                 = An error occured. {0}
+org.openstreetmap.josm.plugins.osb.api.CloseAction.error_occured_title           = Error
+org.openstreetmap.josm.plugins.osb.api.EditAction.error_occured                  = An error occured. {0}
+org.openstreetmap.josm.plugins.osb.api.EditAction.error_occured_title            = Error
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.out_of_bounds                   = The visible area is either too small or too big to download data from OpenStreetBugs
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.out_of_bounds_title             = Warning
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.refresh                         = Refresh
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.shortcut                        = Open OpenStreetBugs
+org.openstreetmap.josm.plugins.osb.gui.OsbDialog.tooltip                         = Open the OpenStreetBugs window and activates the automatic download
+org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction.enter_comment     = Enter your comment
+org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction.enter_nickname    = Please enter a user name
+org.openstreetmap.josm.plugins.osb.gui.action.AddCommentAction.name              = Add a comment
+org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction.name              = Mark as done
+org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction.question          = Really mark this issue as "done"?
+org.openstreetmap.josm.plugins.osb.gui.action.CloseIssueAction.title             = Really close?
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.error_occured       = An error occured. {0}
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.error_occured_title = Error
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.name                = New issue
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.question            = Describe the problem as precise as possible
+org.openstreetmap.josm.plugins.osb.gui.action.NewIssueAction.title               = Create issue
