Index: /CONTRIBUTION
===================================================================
--- /CONTRIBUTION	(revision 188)
+++ /CONTRIBUTION	(revision 189)
@@ -15,9 +15,8 @@
 The jar-file is licensed under LGPL.
 
+Some plugins (hosted elsewhere) are from Nick Whitelegg.
+Frederik Ramm did some of the actions and the MarkerLayer.
 Several smaller patches are contributed by community members
 of OSM.
-
-Some plugins are from Nick Whitelegg (currently mappaint and
-landsat).
 
 Internalisation:
Index: /src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- /src/org/openstreetmap/josm/actions/OpenAction.java	(revision 188)
+++ /src/org/openstreetmap/josm/actions/OpenAction.java	(revision 189)
@@ -18,6 +18,8 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.layer.MarkerLayer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer;
+import org.openstreetmap.josm.gui.layer.MarkerLayer.Marker;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
 import org.openstreetmap.josm.io.OsmReader;
@@ -57,13 +59,20 @@
 		try {
 			if (asRawData(fn)) {
-				Collection<Collection<GpsPoint>> data;
+				Collection<Collection<GpsPoint>> gpsData = null;
+				Collection<Marker> markerData = null;
 				if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-					data = RawGpsReader.parse(new FileInputStream(file));
+					RawGpsReader r = new RawGpsReader(new FileInputStream(file));
+					gpsData = r.trackData;
+					markerData = r.markerData;
 				} else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
-					data = new LinkedList<Collection<GpsPoint>>();
-					data.add(new RawCsvReader(new FileReader(file)).parse());
+					gpsData = new LinkedList<Collection<GpsPoint>>();
+					gpsData.add(new RawCsvReader(new FileReader(file)).parse());
 				} else
 					throw new IllegalStateException();
-				Main.main.addLayer(new RawGpsLayer(data, file.getName(), file));
+				if ((gpsData != null) && (!gpsData.isEmpty()))
+					Main.main.addLayer(new RawGpsLayer(gpsData, tr("Tracks from {0}", file.getName()), file));
+				if ((markerData != null) && (!markerData.isEmpty()))
+					Main.main.addLayer(new MarkerLayer(markerData, tr ("Markers from {0}", file.getName()), file));
+				
 			} else {
 				DataSet dataSet;
Index: /src/org/openstreetmap/josm/gui/layer/MarkerLayer.java
===================================================================
--- /src/org/openstreetmap/josm/gui/layer/MarkerLayer.java	(revision 189)
+++ /src/org/openstreetmap/josm/gui/layer/MarkerLayer.java	(revision 189)
@@ -0,0 +1,172 @@
+package org.openstreetmap.josm.gui.layer;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static org.openstreetmap.josm.tools.I18n.trn;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.Collection;
+
+import javax.swing.Icon;
+import javax.swing.JColorChooser;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JSeparator;
+import javax.swing.SwingUtilities;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.RenameLayerAction;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
+import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
+import org.openstreetmap.josm.tools.ColorHelper;
+import org.openstreetmap.josm.tools.ImageProvider;
+
+/**
+ * A layer holding markers.
+ * 
+ * Markers are GPS points with a name and, optionally, a symbol code attached;
+ * marker layers can be created from waypoints when importing raw GPS data,
+ * but they may also come from other sources.
+ * 
+ * The symbol code is for future use.
+ * 
+ * The data is read only.
+ */
+public class MarkerLayer extends Layer {
+
+	public static class Marker {
+		public final EastNorth eastNorth;
+		public final String text;
+		public final Icon symbol;
+		public Marker(LatLon ll, String t, String s) {
+			eastNorth = Main.proj.latlon2eastNorth(ll); 
+			text = t;
+			Icon symbol = null;
+			try {
+                symbol = ImageProvider.get("symbols",s);
+            } catch (RuntimeException e) {
+    			try {
+                    symbol = ImageProvider.get("nodes",s);
+                } catch (RuntimeException e2) {
+                }
+            }
+            this.symbol = symbol;
+		}
+	}
+
+	/**
+	 * A list of markers.
+	 */
+	public final Collection<Marker> data;
+
+	public MarkerLayer(Collection<Marker> data, String name, File associatedFile) {
+		super(name);
+		this.associatedFile = associatedFile;
+		this.data = data;
+		SwingUtilities.invokeLater(new Runnable(){
+			public void run() {
+				Main.map.mapView.addLayerChangeListener(new LayerChangeListener(){
+					public void activeLayerChange(Layer oldLayer, Layer newLayer) {}
+					public void layerAdded(Layer newLayer) {}
+					public void layerRemoved(Layer oldLayer) {
+						Main.pref.listener.remove(MarkerLayer.this);
+					}
+				});
+			}
+		});
+	}
+
+	/**
+	 * Return a static icon.
+	 */
+	@Override public Icon getIcon() {
+		return ImageProvider.get("layer", "marker");
+	}
+
+	@Override public void paint(Graphics g, MapView mv) {
+		String mkrCol = Main.pref.get("color.gps marker");
+		String mkrColSpecial = Main.pref.get("color.layer "+name);
+		if (!mkrColSpecial.equals(""))
+			g.setColor(ColorHelper.html2color(mkrColSpecial));
+		else if (!mkrCol.equals(""))
+			g.setColor(ColorHelper.html2color(mkrCol));
+		else
+			g.setColor(Color.GRAY);
+
+		for (Marker mkr : data) {
+			Point screen = mv.getPoint(mkr.eastNorth);
+			if (mkr.symbol != null)
+				mkr.symbol.paintIcon(Main.map.mapView, g, screen.x-mkr.symbol.getIconWidth()/2, screen.y-mkr.symbol.getIconHeight()/2);
+			else {
+				g.drawLine(screen.x-2, screen.y-2, screen.x+2, screen.y+2);
+				g.drawLine(screen.x+2, screen.y-2, screen.x-2, screen.y+2);
+			}
+			g.drawString(mkr.text, screen.x+4, screen.y+2);
+		}
+	}
+
+	@Override public String getToolTipText() {
+		return data.size()+" "+trn("marker", "markers", data.size());
+	}
+
+	@Override public void mergeFrom(Layer from) {
+		MarkerLayer layer = (MarkerLayer)from;
+		data.addAll(layer.data);
+	}
+
+	@Override public boolean isMergable(Layer other) {
+		return other instanceof MarkerLayer;
+	}
+
+	@Override public void visitBoundingBox(BoundingXYVisitor v) {
+		for (Marker mkr : data)
+			v.visit(mkr.eastNorth);
+	}
+
+	@Override public Object getInfoComponent() {
+		return "<html>"+trn("{0} consists of {1} marker", "{0} consists of {1} markers", data.size(), name, data.size()) + "</html>";
+	}
+
+	@Override public Component[] getMenuEntries() {
+		JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
+		color.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent e) {
+				String col = Main.pref.get("color.layer "+name, Main.pref.get("color.gps marker", ColorHelper.color2html(Color.gray)));
+				JColorChooser c = new JColorChooser(ColorHelper.html2color(col));
+				Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
+				int answer = JOptionPane.showOptionDialog(Main.parent, c, tr("Choose a color"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
+				switch (answer) {
+				case 0:
+					Main.pref.put("color.layer "+name, ColorHelper.color2html(c.getColor()));
+					break;
+				case 1:
+					return;
+				case 2:
+					Main.pref.put("color.layer "+name, null);
+					break;
+				}
+				Main.map.repaint();
+			}
+		});
+
+		return new Component[] {
+			new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
+			new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
+			new JSeparator(),
+			color,
+			new JMenuItem(new RenameLayerAction(associatedFile, this)),
+			new JSeparator(),
+			new JMenuItem(new LayerListPopup.InfoAction(this))
+		};
+	}
+}
Index: /src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- /src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 188)
+++ /src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 189)
@@ -48,5 +48,7 @@
     			if (in == null)
     				break;
-    			Collection<Collection<GpsPoint>> allWays = RawGpsReader.parse(in);
+    			// Use only track points, since the server mix everything together 
+    			Collection<Collection<GpsPoint>> allWays = new RawGpsReader(in).trackData;
+
     			boolean foundSomething = false;
     			for (Collection<GpsPoint> t : allWays) {
Index: /src/org/openstreetmap/josm/io/RawGpsReader.java
===================================================================
--- /src/org/openstreetmap/josm/io/RawGpsReader.java	(revision 188)
+++ /src/org/openstreetmap/josm/io/RawGpsReader.java	(revision 189)
@@ -6,4 +6,5 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -11,4 +12,5 @@
 
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.gui.layer.MarkerLayer.Marker;
 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
 import org.xml.sax.Attributes;
@@ -24,5 +26,15 @@
 public class RawGpsReader {
 
-	private static class Parser extends MinML2 {
+	/**
+	 * Hold the resulting gps data (tracks and their track points)
+	 */
+	public Collection<Collection<GpsPoint>> trackData = new LinkedList<Collection<GpsPoint>>();
+
+	/**
+	 * Hold the waypoints of the gps data.
+	 */
+	public Collection<Marker> markerData = new ArrayList<Marker>();
+
+	private class Parser extends MinML2 {
 		/**
 		 * Current track to be read. The last entry is the current trkpt.
@@ -30,7 +42,7 @@
 		 */
 		private Collection<GpsPoint> current = new LinkedList<GpsPoint>();
-		public Collection<Collection<GpsPoint>> data = new LinkedList<Collection<GpsPoint>>();
 		private LatLon currentLatLon;
 		private String currentTime = "";
+		private String currentName = "";
 		private Stack<String> tags = new Stack<String>();
 
@@ -50,4 +62,5 @@
                 }
                 currentTime = "";
+                currentName = "";
 			}
 			tags.push(qName);
@@ -55,23 +68,30 @@
 
 		@Override public void characters(char[] ch, int start, int length) {
-			if (tags.peek().equals("time")) {
-				String time = tags.pop();
+			String peek = tags.peek();
+			if (peek.equals("time") || peek.equals("name")) {
+				String tag = tags.pop();
 				if (tags.empty() || (!tags.peek().equals("wpt") && !tags.peek().equals("trkpt"))) {
-					tags.push(time);
+					tags.push(tag);
 					return;
 				}
-				String ct = new String(ch, start, length);
-				currentTime += ct;
-				tags.push(time);
+				String contents = new String(ch, start, length);
+				if (peek.equals("time")) currentTime += contents; else currentName += contents;
+				tags.push(tag);
 			}
 		}
 
 		@Override public void endElement(String namespaceURI, String localName, String qName) {
-			if (qName.equals("wpt") || qName.equals("trkpt")) {
+			if (qName.equals("trkpt")) {
 				current.add(new GpsPoint(currentLatLon, currentTime));
 				currentTime = "";
+				currentName = "";
+			} else if (qName.equals("wpt")) {
+				markerData.add(new Marker(currentLatLon, currentName, null));
+				currentTime = "";
+				currentName = "";
 			} else if (qName.equals("trkseg") || qName.equals("trk") || qName.equals("gpx")) {
 				newTrack();
 				currentTime = "";
+				currentName = "";
 			}
 			tags.pop();
@@ -80,5 +100,5 @@
 		private void newTrack() {
 			if (!current.isEmpty()) {
-				data.add(current);
+				trackData.add(current);
 				current = new LinkedList<GpsPoint>();
 			}
@@ -86,11 +106,11 @@
 	}
 
+
 	/**
-	 * Parse and return the read data
+	 * Parse the input stream and store the result in trackData and markerData 
 	 */
-	public static Collection<Collection<GpsPoint>> parse(InputStream source) throws SAXException, IOException {
+	public RawGpsReader(InputStream source) throws SAXException, IOException {
 		Parser parser = new Parser();
 		parser.parse(new InputStreamReader(source, "UTF-8"));
-		return parser.data;
 	}
 }
