Index: applications/editors/josm/plugins/livegps/.classpath
===================================================================
--- applications/editors/josm/plugins/livegps/.classpath	(revision 14057)
+++ applications/editors/josm/plugins/livegps/.classpath	(revision 14057)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/sun-jdk-1.5.0.15"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/JOSM"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: applications/editors/josm/plugins/livegps/.project
===================================================================
--- applications/editors/josm/plugins/livegps/.project	(revision 14057)
+++ applications/editors/josm/plugins/livegps/.project	(revision 14057)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>livegps</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: applications/editors/josm/plugins/livegps/src/LiveGpsAcquirer.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsAcquirer.java	(revision 14053)
+++ 	(revision )
@@ -1,249 +1,0 @@
-package livegps;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.openstreetmap.josm.data.coor.LatLon;
-
-public class LiveGpsAcquirer implements Runnable {
-    Socket gpsdSocket;
-    BufferedReader gpsdReader;
-    boolean connected = false;
-    String gpsdHost = "localhost";
-    int gpsdPort = 2947;
-    String configFile = "liveGPS.conf";
-    boolean shutdownFlag = false;
-    private List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
-    private PropertyChangeEvent lastStatusEvent;
-    private PropertyChangeEvent lastDataEvent;
-
-    public LiveGpsAcquirer(String pluginDir) {
-
-        Properties liveGPSconfig = new Properties();
-
-        FileInputStream fis = null;
-
-        try {
-            fis = new FileInputStream(pluginDir + configFile);
-        } catch (FileNotFoundException e) {
-            System.err.println("No liveGPS.conf found, using defaults");
-        }
-
-        if(fis != null)
-        {
-            try {
-                liveGPSconfig.load(fis);
-                this.gpsdHost = liveGPSconfig.getProperty("host");
-                this.gpsdPort = Integer.parseInt(liveGPSconfig.getProperty("port"));
-
-            } catch (IOException e) {
-                System.err.println("Error while loading liveGPS.conf, using defaults");
-            }
-
-            if(this.gpsdHost == null || this.gpsdPort == 0)
-            {
-                System.err.println("Error in liveGPS.conf, using defaults");
-                this.gpsdHost = "localhost";
-                this.gpsdPort = 2947;
-            }
-        }
-
-    }
-
-    /**
-     * Adds a property change listener to the acquirer.
-     * @param listener the new listener
-     */
-    public void addPropertyChangeListener(PropertyChangeListener listener) {
-        if(!propertyChangeListener.contains(listener)) {
-            propertyChangeListener.add(listener);
-        }
-    }
-
-    /**
-     * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
-     * object as value.
-     * @param status the status.
-     * @param statusMessage the status message.
-     */
-    public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status, String statusMessage) {
-        PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus", null, new LiveGpsStatus(status, statusMessage));
-        if(!event.equals(lastStatusEvent)) {
-            firePropertyChangeEvent(event);
-            lastStatusEvent = event;
-        }
-    }
-
-    /**
-     * Fire a gps data change event to all listeners. Fires events with key "gpsdata" and a
-     * {@link LiveGpsData} object as values.
-     * @param oldData the old gps data.
-     * @param newData the new gps data.
-     */
-    public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) {
-        PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata", oldData, newData);
-        if(!event.equals(lastDataEvent)) {
-            firePropertyChangeEvent(event);
-            lastDataEvent = event;
-        }
-    }
-
-    /**
-     * Fires the given event to all listeners.
-     * @param event the event to fire.
-     */
-    protected void firePropertyChangeEvent(PropertyChangeEvent event) {
-        for (PropertyChangeListener listener : propertyChangeListener) {
-            listener.propertyChange(event);
-        }
-    }
-
-    public void run() {
-        LiveGpsData oldGpsData = null;
-        LiveGpsData gpsData = null;
-        shutdownFlag = false;
-        while(!shutdownFlag) {
-            double lat = 0;
-            double lon = 0;
-            float speed = 0;
-            float course = 0;
-            boolean haveFix = false;
-
-            try
-            {
-                if (!connected)
-                {
-                    System.out.println("LiveGps tries to connect to gpsd");
-                    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
-                    InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
-                    for (int i=0; i < addrs.length && gpsdSocket == null; i++) {
-                        try {
-                            gpsdSocket = new Socket(addrs[i], gpsdPort);
-                            break;
-                        } catch (Exception e) {
-                            System.out.println("LiveGps: Could not open connection to gpsd: " + e);
-                            gpsdSocket = null;
-                        }
-                    }
-
-                    if (gpsdSocket != null)
-                    {
-                        gpsdReader = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream()));
-                        gpsdSocket.getOutputStream().write(new byte[] { 'w', 13, 10 });
-                        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
-                        connected = true;
-                    System.out.println("LiveGps: Connected to gpsd");
-                    }
-                }
-
-
-                if(connected) {
-                    // <FIXXME date="23.06.2007" author="cdaller">
-                    // TODO this read is blocking if gps is connected but has no fix, so gpsd does not send positions
-                    String line = gpsdReader.readLine();
-                    // </FIXXME>
-                    if (line == null) break;
-                    String words[] = line.split(",");
-
-                    if ((words.length == 0) || (!words[0].equals("GPSD"))) {
-                        // unexpected response.
-                        continue;
-                    }
-
-                    for (int i = 1; i < words.length; i++) {
-
-                        if ((words[i].length() < 2) || (words[i].charAt(1) != '=')) {
-                            // unexpected response.
-                            continue;
-                        }
-
-                        char what = words[i].charAt(0);
-                        String value = words[i].substring(2);
-                        oldGpsData = gpsData;
-                        gpsData = new LiveGpsData();
-                        switch(what) {
-                        case 'O':
-                            // full report, tab delimited.
-                            String[] status = value.split("\\s+");
-                            if (status.length >= 5) {
-                                lat = Double.parseDouble(status[3]);
-                                lon = Double.parseDouble(status[4]);
-                                try {
-                                    speed = Float.parseFloat(status[9]);
-                                    course = Float.parseFloat(status[8]);
-                                    //view.setSpeed(speed);
-                                    //view.setCourse(course);
-                                } catch (NumberFormatException nex) {}
-                                haveFix = true;
-                            }
-                            break;
-                        case 'P':
-                            // position report, tab delimited.
-                            String[] pos = value.split("\\s+");
-                            if (pos.length >= 2) {
-                                lat = Double.parseDouble(pos[0]);
-                                lon = Double.parseDouble(pos[1]);
-                                speed = Float.NaN;
-                                course = Float.NaN;
-                                haveFix = true;
-                            }
-                        default:
-                            // not interested
-                        }
-                        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected"));
-                        gpsData.setFix(haveFix);
-                        if (haveFix) {
-                            //view.setCurrentPosition(lat, lon);
-                            gpsData.setLatLon(new LatLon(lat, lon));
-                            gpsData.setSpeed(speed);
-                            gpsData.setCourse(course);
-                            fireGpsDataChangeEvent(oldGpsData, gpsData);
-                        }
-                    }
-                } else {
-                    // not connected:
-                    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
-                    try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
-                }
-            } catch(IOException iox) {
-                connected = false;
-                if(gpsData != null) {
-                    gpsData.setFix(false);
-                    fireGpsDataChangeEvent(oldGpsData, gpsData);
-                }
-                fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTION_FAILED, tr("Connection Failed"));
-                try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
-                // send warning to layer
-
-            }
-        }
-
-    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
-        if (gpsdSocket != null) {
-      try {
-        gpsdSocket.close();
-        gpsdSocket = null;
-            System.out.println("LiveGps: Disconnected from gpsd");
-      }
-      catch (Exception e) {
-        System.out.println("LiveGps: Unable to close socket; reconnection may not be possible");
-      };
-      }
-  }
-
-    public void shutdown()
-    {
-        shutdownFlag = true;
-    }
-}
Index: applications/editors/josm/plugins/livegps/src/LiveGpsData.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsData.java	(revision 14053)
+++ 	(revision )
@@ -1,211 +1,0 @@
-/**
- *
- */
-package livegps;
-
-import java.awt.Point;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.EastNorth;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.Way;
-
-/**
- * @author cdaller
- *
- */
-public class LiveGpsData {
-    private LatLon latLon;
-    private float course;
-    private float speed;
-    private boolean fix;
-    private String wayString;
-    private Way way;
-
-    /**
-     * @param latitude
-     * @param longitude
-     * @param course
-     * @param speed
-     * @param haveFix
-     */
-    public LiveGpsData(double latitude, double longitude, float course, float speed, boolean haveFix) {
-        super();
-        this.latLon = new LatLon(latitude, longitude);
-        this.course = course;
-        this.speed = speed;
-        this.fix = haveFix;
-    }
-    /**
-     *
-     */
-    public LiveGpsData() {
-        // TODO Auto-generated constructor stub
-    }
-    /**
-     * @return the course
-     */
-    public float getCourse() {
-        return this.course;
-    }
-    /**
-     * @param course the course to set
-     */
-    public void setCourse(float course) {
-        this.course = course;
-    }
-    /**
-     * @return the haveFix
-     */
-    public boolean isFix() {
-        return this.fix;
-    }
-    /**
-     * @param haveFix the haveFix to set
-     */
-    public void setFix(boolean haveFix) {
-        this.fix = haveFix;
-    }
-    /**
-     * @return the latitude
-     */
-    public double getLatitude() {
-        return this.latLon.lat();
-    }
-    /**
-     * @return the longitude
-     */
-    public double getLongitude() {
-        return this.latLon.lon();
-    }
-    /**
-     * @return the speed in metres per second!
-     */
-    public float getSpeed() {
-        return this.speed;
-    }
-    /**
-     * @param speed the speed to set
-     */
-    public void setSpeed(float speed) {
-        this.speed = speed;
-    }
-
-    /**
-     * @return the latlon
-     */
-    public LatLon getLatLon() {
-        return this.latLon;
-    }
-
-    /**
-     * @param latLon
-     */
-    public void setLatLon(LatLon latLon) {
-        this.latLon = latLon;
-    }
-
-    public String toString() {
-        return getClass().getSimpleName() + "[fix=" + fix + ", lat=" + latLon.lat()
-        + ", long=" + latLon.lon() + ", speed=" + speed + ", course=" + course + "]";
-
-    }
-
-    /**
-     * Returns the name of the way that is closest to the current coordinates or an
-     * empty string if no way is around.
-     *
-     * @return the name of the way that is closest to the current coordinates.
-     */
-    public String getWayInfo() {
-        if(wayString == null) {
-            Way way = getWay();
-            if(way != null) {
-                StringBuilder builder = new StringBuilder();
-                String tmp = way.get("name");
-                if(tmp != null) {
-                    builder.append(tmp);
-                } else {
-                    builder.append("no name");
-                }
-                tmp = way.get("ref");
-                if(tmp != null) {
-                    builder.append(" (").append(tmp).append(")");
-                }
-                tmp = way.get("highway");
-                if(tmp != null) {
-                    builder.append(" {").append(tmp).append("}");
-                }
-                String type = "";
-                tmp = way.get("tunnel");
-                if(tmp != null) {
-                    type = type + "T";
-                }
-                tmp = way.get("bridge");
-                if(tmp != null) {
-                    type = type + "B";
-                }
-                if(type.length() > 0) {
-                    builder.append(" [").append(type).append("]");
-                }
-                wayString = builder.toString();
-            } else {
-                wayString = "";
-            }
-        }
-        return wayString;
-    }
-
-    /**
-     * Returns the closest way to this position.
-     * @return the closest way to this position.
-     */
-    public Way getWay() {
-        if(way == null) {
-            EastNorth eastnorth = Main.proj.latlon2eastNorth(getLatLon());
-            Point xy = Main.map.mapView.getPoint(eastnorth);
-            way = Main.map.mapView.getNearestWay(xy);
-        }
-        return way;
-
-    }
-
-    /* (non-Javadoc)
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Float.floatToIntBits(this.course);
-        result = prime * result + ((this.latLon == null) ? 0 : this.latLon.hashCode());
-        result = prime * result + Float.floatToIntBits(this.speed);
-        return result;
-    }
-    /* (non-Javadoc)
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        final LiveGpsData other = (LiveGpsData) obj;
-        if (Float.floatToIntBits(this.course) != Float.floatToIntBits(other.course))
-            return false;
-        if (this.latLon == null) {
-            if (other.latLon != null)
-                return false;
-        } else if (!this.latLon.equals(other.latLon))
-            return false;
-        if (Float.floatToIntBits(this.speed) != Float.floatToIntBits(other.speed))
-            return false;
-        return true;
-    }
-
-
-
-}
Index: applications/editors/josm/plugins/livegps/src/LiveGpsDialog.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsDialog.java	(revision 14053)
+++ 	(revision )
@@ -1,108 +1,0 @@
-/**
- *
- */
-package livegps;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.GridLayout;
-import java.awt.event.KeyEvent;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-
-import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
-import org.openstreetmap.josm.tools.Shortcut;
-
-/**
- * @author cdaller
- *
- */
-public class LiveGpsDialog extends ToggleDialog implements PropertyChangeListener {
-    private static final long serialVersionUID = 6183400754671501117L;
-    private JLabel statusLabel;
-    private JLabel wayLabel;
-    private JLabel latLabel;
-    private JLabel longLabel;
-    private JLabel courseLabel;
-    private JLabel speedLabel;
-    private JPanel panel;
-
-    /**
-     * @param name
-     * @param iconName
-     * @param tooltip
-     * @param shortcut
-     * @param preferredHeight
-     */
-    public LiveGpsDialog(final MapFrame mapFrame) {
-        super(tr("Live GPS"), "livegps", tr("Show GPS data."),
-        Shortcut.registerShortcut("subwindow:livegps", tr("Toggle: {0}", tr("Live GPS")),
-        KeyEvent.VK_G, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 100);
-        panel = new JPanel();
-        panel.setLayout(new GridLayout(6,2));
-        panel.add(new JLabel(tr("Status")));
-        panel.add(statusLabel = new JLabel());
-        panel.add(new JLabel(tr("Way Info")));
-        panel.add(wayLabel = new JLabel());
-        panel.add(new JLabel(tr("Latitude")));
-        panel.add(latLabel = new JLabel());
-        panel.add(new JLabel(tr("Longitude")));
-        panel.add(longLabel = new JLabel());
-        panel.add(new JLabel(tr("Speed")));
-        panel.add(speedLabel = new JLabel());
-        panel.add(new JLabel(tr("Course")));
-        panel.add(courseLabel = new JLabel());
-        add(new JScrollPane(panel), BorderLayout.CENTER);
-    }
-
-    /* (non-Javadoc)
-     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
-     */
-    public void propertyChange(PropertyChangeEvent evt) {
-        if (!isVisible())
-            return;
-        if("gpsdata".equals(evt.getPropertyName())) {
-            LiveGpsData data = (LiveGpsData) evt.getNewValue();
-            if(data.isFix()) {
-//                fixLabel.setText("fix");
-                panel.setBackground(Color.WHITE);
-                latLabel.setText(data.getLatitude() + "deg");
-                longLabel.setText(data.getLongitude() + "deg");
-                double mySpeed = data.getSpeed() * 3.6f;
-                speedLabel.setText((Math.round(mySpeed*100)/100) + "km/h"); // m(s to km/h
-                courseLabel.setText(data.getCourse() + "deg");
-
-                String wayString = data.getWayInfo();
-                if(wayString.length() > 0) {
-                    wayLabel.setText(wayString);
-                } else {
-                    wayLabel.setText("unknown");
-                }
-
-            } else {
-//                fixLabel.setText("no fix");
-                latLabel.setText("");
-                longLabel.setText("");
-                speedLabel.setText("");
-                courseLabel.setText("");
-                panel.setBackground(Color.RED);
-            }
-        } else if ("gpsstatus".equals(evt.getPropertyName())) {
-            LiveGpsStatus status = (LiveGpsStatus) evt.getNewValue();
-            statusLabel.setText(status.getStatusMessage());
-            if(status.getStatus() != LiveGpsStatus.GpsStatus.CONNECTED) {
-                panel.setBackground(Color.RED);
-            } else {
-                panel.setBackground(Color.WHITE);
-            }
-        }
-
-    }
-}
Index: applications/editors/josm/plugins/livegps/src/LiveGpsLayer.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsLayer.java	(revision 14053)
+++ 	(revision )
@@ -1,159 +1,0 @@
-package livegps;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Point;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.gpx.GpxData;
-import org.openstreetmap.josm.data.gpx.GpxTrack;
-import org.openstreetmap.josm.data.gpx.WayPoint;
-import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.layer.GpxLayer;
-import org.openstreetmap.josm.tools.ColorHelper;
-
-public class LiveGpsLayer extends GpxLayer implements PropertyChangeListener {
-    public static final String LAYER_NAME = tr("LiveGPS layer");
-    public static final String KEY_LIVEGPS_COLOR ="color.livegps.position";
-    LatLon lastPos;
-    WayPoint lastPoint;
-    GpxTrack trackBeingWritten;
-    Collection<WayPoint> trackSegment;
-    float speed;
-    float course;
-    String status;
-    //JLabel lbl;
-    boolean autocenter;
-    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
-
-    public LiveGpsLayer(GpxData data)
-    {
-        super (data, LAYER_NAME);
-        trackBeingWritten = new GpxTrack();
-        trackBeingWritten.attr.put("desc", "josm live gps");
-        trackSegment = new ArrayList<WayPoint>();
-        trackBeingWritten.trackSegs.add(trackSegment);
-        data.tracks.add(trackBeingWritten);
-    }
-
-    void setCurrentPosition(double lat, double lon)
-    {
-        //System.out.println("adding pos " + lat + "," + lon);
-        LatLon thisPos = new LatLon(lat, lon);
-        if ((lastPos != null) && (thisPos.equalsEpsilon(lastPos))) {
-            // no change in position
-            // maybe show a "paused" cursor or some such
-            return;
-        }
-
-        lastPos = thisPos;
-        lastPoint = new WayPoint(thisPos);
-        lastPoint.attr.put("time", dateFormat.format(new Date()));
-        // synchronize when adding data, as otherwise the autosave action
-        // needs concurrent access and this results in an exception!
-        synchronized (LiveGpsLock.class) {
-            trackSegment.add(lastPoint);
-        }
-        if (autocenter) {
-            center();
-        }
-
-        //Main.map.repaint();
-    }
-
-    public void center()
-    {
-        if (lastPoint != null)
-            Main.map.mapView.zoomTo(lastPoint.eastNorth, Main.map.mapView.getScale());
-    }
-
-//  void setStatus(String status)
-//  {
-//      this.status = status;
-//      Main.map.repaint();
-//        System.out.println("LiveGps status: " + status);
-//  }
-
-    void setSpeed(float metresPerSecond)
-    {
-        speed = metresPerSecond;
-        //Main.map.repaint();
-    }
-
-    void setCourse(float degrees)
-    {
-        course = degrees;
-        //Main.map.repaint();
-    }
-
-    public void setAutoCenter(boolean ac)
-    {
-        autocenter = ac;
-    }
-
-    @Override public void paint(Graphics g, MapView mv)
-    {
-        //System.out.println("in paint");
-        synchronized (LiveGpsLock.class) {
-            //System.out.println("in synced paint");
-            super.paint(g, mv);
-//          int statusHeight = 50;
-//          Rectangle mvs = mv.getBounds();
-//          mvs.y = mvs.y + mvs.height - statusHeight;
-//          mvs.height = statusHeight;
-//          g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.8f));
-//          g.fillRect(mvs.x, mvs.y, mvs.width, mvs.height);
-
-            if (lastPoint != null)
-            {
-                Point screen = mv.getPoint(lastPoint.eastNorth);
-                g.setColor(Main.pref.getColor(KEY_LIVEGPS_COLOR, Color.RED));
-                g.drawOval(screen.x-10, screen.y-10,20,20);
-                g.drawOval(screen.x-9, screen.y-9,18,18);
-            }
-
-//          lbl.setText("gpsd: "+status+" Speed: " + speed + " Course: "+course);
-//          lbl.setBounds(0, 0, mvs.width-10, mvs.height-10);
-//          Graphics sub = g.create(mvs.x+5, mvs.y+5, mvs.width-10, mvs.height-10);
-//          lbl.paint(sub);
-
-//          if(status != null) {
-//          g.setColor(Color.WHITE);
-//          g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15); // lower left corner
-//          }
-        }
-    }
-
-    /* (non-Javadoc)
-     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
-     */
-    public void propertyChange(PropertyChangeEvent evt) {
-        if(!visible) {
-            return;
-        }
-        if("gpsdata".equals(evt.getPropertyName())) {
-            LiveGpsData data = (LiveGpsData) evt.getNewValue();
-            if(data.isFix()) {
-                setCurrentPosition(data.getLatitude(), data.getLongitude());
-                if(!Float.isNaN(data.getSpeed())) {
-                    setSpeed(data.getSpeed());
-                }
-                if(!Float.isNaN(data.getCourse())) {
-                    setCourse(data.getCourse());
-                }
-                Main.map.repaint();
-            }
-        }
-
-    }
-
-}
Index: applications/editors/josm/plugins/livegps/src/LiveGpsLock.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsLock.java	(revision 14053)
+++ 	(revision )
@@ -1,16 +1,0 @@
-/**
- *
- */
-package livegps;
-
-/**
- * This class is only used to prevent concurrent object modification. So all classes that
- * read or write live gps data must synchronize to this class. Especially the save action
- * takes quite long, so concurrency problems occur.
- *
- * @author cdaller
- *
- */
-public class LiveGpsLock {
-
-}
Index: applications/editors/josm/plugins/livegps/src/LiveGpsPlugin.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsPlugin.java	(revision 14053)
+++ 	(revision )
@@ -1,197 +1,0 @@
-package livegps;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.beans.PropertyChangeListener;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.gpx.GpxData;
-import org.openstreetmap.josm.gui.MainMenu;
-import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.plugins.Plugin;
-import org.openstreetmap.josm.tools.Shortcut;
-
-public class LiveGpsPlugin extends Plugin
-{
-    private LiveGpsAcquirer acquirer = null;
-    private Thread acquirerThread = null;
-    private JMenu lgpsmenu;
-    private JCheckBoxMenuItem lgpscapture;
-    private JMenuItem lgpscenter;
-    private JCheckBoxMenuItem lgpsautocenter;
-    private LiveGpsDialog lgpsdialog;
-    List<PropertyChangeListener>listenerQueue;
-
-    private GpxData data = new GpxData();
-    private LiveGpsLayer lgpslayer;
-
-
-    public class CaptureAction extends JosmAction {
-        public CaptureAction() {
-            super(tr("Capture GPS Track"), "capturemenu", tr("Connect to gpsd server and show current position in LiveGPS layer."),
-                Shortcut.registerShortcut("menu:livegps:capture", tr("Menu: {0}", tr("Capture GPS Track")),
-                KeyEvent.VK_R, Shortcut.GROUP_MENU), true);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            enableTracking(lgpscapture.isSelected());
-        }
-    }
-
-    public class CenterAction extends JosmAction {
-        public CenterAction() {
-            super(tr("Center Once"), "centermenu", tr("Center the LiveGPS layer to current position."),
-            Shortcut.registerShortcut("edit:centergps", tr("Edit: {0}", tr("Center Once")),
-            KeyEvent.VK_HOME, Shortcut.GROUP_EDIT), true);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if(lgpslayer != null) {
-                lgpslayer.center();
-            }
-        }
-    }
-
-    public class AutoCenterAction extends JosmAction {
-        public AutoCenterAction() {
-            super(tr("Auto-Center"), "autocentermenu", tr("Continuously center the LiveGPS layer to current position."),
-            Shortcut.registerShortcut("menu:livegps:autocenter", tr("Menu: {0}", tr("Capture GPS Track")),
-            KeyEvent.VK_HOME, Shortcut.GROUP_MENU), true);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            if(lgpslayer != null) {
-                setAutoCenter(lgpsautocenter.isSelected());
-            }
-        }
-    }
-
-    public LiveGpsPlugin()
-    {
-        MainMenu menu = Main.main.menu;
-        lgpsmenu = new JMenu(tr("LiveGPS"));
-        menu.add(lgpsmenu, KeyEvent.VK_G, "livegps");
-        menu.add(lgpsmenu, 5);
-
-        JosmAction captureAction = new CaptureAction();
-        lgpscapture = new JCheckBoxMenuItem(captureAction);
-        lgpsmenu.add(lgpscapture);
-        lgpscapture.setAccelerator(captureAction.getShortcut().getKeyStroke());
-
-        JosmAction centerAction = new CenterAction();
-        JMenuItem centerMenu = new JMenuItem(centerAction);
-        lgpsmenu.add(centerMenu);
-        centerMenu.setAccelerator(centerAction.getShortcut().getKeyStroke());
-
-        JosmAction autoCenterAction = new AutoCenterAction();
-        lgpsautocenter = new JCheckBoxMenuItem(autoCenterAction);
-        lgpsmenu.add(lgpsautocenter);
-        lgpsautocenter.setAccelerator(autoCenterAction.getShortcut().getKeyStroke());
-    }
-
-    /**
-     * Set to <code>true</code> if the current position should always be in the center of the map.
-     * @param autoCenter if <code>true</code> the map is always centered.
-     */
-    public void setAutoCenter(boolean autoCenter) {
-        lgpsautocenter.setSelected(autoCenter); // just in case this method was not called from the menu
-        if(lgpslayer != null) {
-            lgpslayer.setAutoCenter(autoCenter);
-            if (autoCenter) lgpslayer.center();
-        }
-    }
-
-    /**
-     * Returns <code>true</code> if autocenter is selected.
-     * @return <code>true</code> if autocenter is selected.
-     */
-    public boolean isAutoCenter() {
-        return lgpsautocenter.isSelected();
-    }
-
-    /**
-     * Enable or disable gps tracking
-     * @param enable if <code>true</code> tracking is started.
-     */
-    public void enableTracking(boolean enable) {
-        if ((acquirer != null) && (!enable))
-        {
-            acquirer.shutdown();
-            acquirerThread = null;
-        }
-        else if(enable)
-        {
-            if (acquirer == null) {
-                acquirer = new LiveGpsAcquirer(getPluginDir());
-                if (lgpslayer == null) {
-                    lgpslayer = new LiveGpsLayer(data);
-                    Main.main.addLayer(lgpslayer);
-                    lgpslayer.setAutoCenter(isAutoCenter());
-                }
-                // connect layer with acquirer:
-                addPropertyChangeListener(lgpslayer);
-                // add all listeners that were added before the acquirer existed:
-                if(listenerQueue != null) {
-                    for(PropertyChangeListener listener : listenerQueue) {
-                        addPropertyChangeListener(listener);
-                    }
-                    listenerQueue.clear();
-                }
-            }
-            if(acquirerThread == null) {
-                acquirerThread = new Thread(acquirer);
-                acquirerThread.start();
-            }
-        }
-    }
-
-
-    /**
-     * Add a listener for gps events.
-     * @param listener the listener.
-     */
-    public void addPropertyChangeListener(PropertyChangeListener listener) {
-        if(acquirer != null) {
-            acquirer.addPropertyChangeListener(listener);
-        } else {
-            if(listenerQueue == null) {
-                listenerQueue = new ArrayList<PropertyChangeListener>();
-            }
-            listenerQueue.add(listener);
-        }
-    }
-
-
-    /* (non-Javadoc)
-     * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame)
-     */
-    @Override
-    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
-        if(newFrame != null) {
-            // add dialog
-            newFrame.addToggleDialog(lgpsdialog = new LiveGpsDialog(newFrame));
-            // connect listeners with acquirer:
-            addPropertyChangeListener(lgpsdialog);
-        }
-    }
-
-
-    /**
-     * @return the lgpsmenu
-     */
-    public JMenu getLgpsMenu() {
-        return this.lgpsmenu;
-    }
-
-}
-
Index: applications/editors/josm/plugins/livegps/src/LiveGpsStatus.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/LiveGpsStatus.java	(revision 14053)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/**
- *
- */
-package livegps;
-
-/**
- * @author cdaller
- *
- */
-public class LiveGpsStatus {
-    public enum GpsStatus {CONNECTING, CONNECTED, DISCONNECTED, CONNECTION_FAILED};
-    private String statusMessage;
-    private GpsStatus status;
-
-    /**
-     * @param status
-     * @param statusMessage
-     */
-    public LiveGpsStatus(GpsStatus status, String statusMessage) {
-        super();
-        this.status = status;
-        this.statusMessage = statusMessage;
-    }
-/**
-     * @return the status
-     */
-    public GpsStatus getStatus() {
-        return this.status;
-    }
-    /**
-     * @param status the status to set
-     */
-    public void setStatus(GpsStatus status) {
-        this.status = status;
-    }
-    /**
-     * @return the statusMessage
-     */
-    public String getStatusMessage() {
-        return this.statusMessage;
-    }
-    /**
-     * @param statusMessage the statusMessage to set
-     */
-    public void setStatusMessage(String statusMessage) {
-        this.statusMessage = statusMessage;
-    }
-
-}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java	(revision 14057)
@@ -0,0 +1,249 @@
+package livegps;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.openstreetmap.josm.data.coor.LatLon;
+
+public class LiveGpsAcquirer implements Runnable {
+    Socket gpsdSocket;
+    BufferedReader gpsdReader;
+    boolean connected = false;
+    String gpsdHost = "localhost";
+    int gpsdPort = 2947;
+    String configFile = "liveGPS.conf";
+    boolean shutdownFlag = false;
+    private List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
+    private PropertyChangeEvent lastStatusEvent;
+    private PropertyChangeEvent lastDataEvent;
+
+    public LiveGpsAcquirer(String pluginDir) {
+
+        Properties liveGPSconfig = new Properties();
+
+        FileInputStream fis = null;
+
+        try {
+            fis = new FileInputStream(pluginDir + configFile);
+        } catch (FileNotFoundException e) {
+            System.err.println("No liveGPS.conf found, using defaults");
+        }
+
+        if(fis != null)
+        {
+            try {
+                liveGPSconfig.load(fis);
+                this.gpsdHost = liveGPSconfig.getProperty("host");
+                this.gpsdPort = Integer.parseInt(liveGPSconfig.getProperty("port"));
+
+            } catch (IOException e) {
+                System.err.println("Error while loading liveGPS.conf, using defaults");
+            }
+
+            if(this.gpsdHost == null || this.gpsdPort == 0)
+            {
+                System.err.println("Error in liveGPS.conf, using defaults");
+                this.gpsdHost = "localhost";
+                this.gpsdPort = 2947;
+            }
+        }
+
+    }
+
+    /**
+     * Adds a property change listener to the acquirer.
+     * @param listener the new listener
+     */
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        if(!propertyChangeListener.contains(listener)) {
+            propertyChangeListener.add(listener);
+        }
+    }
+
+    /**
+     * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
+     * object as value.
+     * @param status the status.
+     * @param statusMessage the status message.
+     */
+    public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status, String statusMessage) {
+        PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsstatus", null, new LiveGpsStatus(status, statusMessage));
+        if(!event.equals(lastStatusEvent)) {
+            firePropertyChangeEvent(event);
+            lastStatusEvent = event;
+        }
+    }
+
+    /**
+     * Fire a gps data change event to all listeners. Fires events with key "gpsdata" and a
+     * {@link LiveGpsData} object as values.
+     * @param oldData the old gps data.
+     * @param newData the new gps data.
+     */
+    public void fireGpsDataChangeEvent(LiveGpsData oldData, LiveGpsData newData) {
+        PropertyChangeEvent event = new PropertyChangeEvent(this, "gpsdata", oldData, newData);
+        if(!event.equals(lastDataEvent)) {
+            firePropertyChangeEvent(event);
+            lastDataEvent = event;
+        }
+    }
+
+    /**
+     * Fires the given event to all listeners.
+     * @param event the event to fire.
+     */
+    protected void firePropertyChangeEvent(PropertyChangeEvent event) {
+        for (PropertyChangeListener listener : propertyChangeListener) {
+            listener.propertyChange(event);
+        }
+    }
+
+    public void run() {
+        LiveGpsData oldGpsData = null;
+        LiveGpsData gpsData = null;
+        shutdownFlag = false;
+        while(!shutdownFlag) {
+            double lat = 0;
+            double lon = 0;
+            float speed = 0;
+            float course = 0;
+            boolean haveFix = false;
+
+            try
+            {
+                if (!connected)
+                {
+                    System.out.println("LiveGps tries to connect to gpsd");
+                    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
+                    InetAddress[] addrs = InetAddress.getAllByName(gpsdHost);
+                    for (int i=0; i < addrs.length && gpsdSocket == null; i++) {
+                        try {
+                            gpsdSocket = new Socket(addrs[i], gpsdPort);
+                            break;
+                        } catch (Exception e) {
+                            System.out.println("LiveGps: Could not open connection to gpsd: " + e);
+                            gpsdSocket = null;
+                        }
+                    }
+
+                    if (gpsdSocket != null)
+                    {
+                        gpsdReader = new BufferedReader(new InputStreamReader(gpsdSocket.getInputStream()));
+                        gpsdSocket.getOutputStream().write(new byte[] { 'w', 13, 10 });
+                        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
+                        connected = true;
+                    System.out.println("LiveGps: Connected to gpsd");
+                    }
+                }
+
+
+                if(connected) {
+                    // <FIXXME date="23.06.2007" author="cdaller">
+                    // TODO this read is blocking if gps is connected but has no fix, so gpsd does not send positions
+                    String line = gpsdReader.readLine();
+                    // </FIXXME>
+                    if (line == null) break;
+                    String words[] = line.split(",");
+
+                    if ((words.length == 0) || (!words[0].equals("GPSD"))) {
+                        // unexpected response.
+                        continue;
+                    }
+
+                    for (int i = 1; i < words.length; i++) {
+
+                        if ((words[i].length() < 2) || (words[i].charAt(1) != '=')) {
+                            // unexpected response.
+                            continue;
+                        }
+
+                        char what = words[i].charAt(0);
+                        String value = words[i].substring(2);
+                        oldGpsData = gpsData;
+                        gpsData = new LiveGpsData();
+                        switch(what) {
+                        case 'O':
+                            // full report, tab delimited.
+                            String[] status = value.split("\\s+");
+                            if (status.length >= 5) {
+                                lat = Double.parseDouble(status[3]);
+                                lon = Double.parseDouble(status[4]);
+                                try {
+                                    speed = Float.parseFloat(status[9]);
+                                    course = Float.parseFloat(status[8]);
+                                    //view.setSpeed(speed);
+                                    //view.setCourse(course);
+                                } catch (NumberFormatException nex) {}
+                                haveFix = true;
+                            }
+                            break;
+                        case 'P':
+                            // position report, tab delimited.
+                            String[] pos = value.split("\\s+");
+                            if (pos.length >= 2) {
+                                lat = Double.parseDouble(pos[0]);
+                                lon = Double.parseDouble(pos[1]);
+                                speed = Float.NaN;
+                                course = Float.NaN;
+                                haveFix = true;
+                            }
+                        default:
+                            // not interested
+                        }
+                        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected"));
+                        gpsData.setFix(haveFix);
+                        if (haveFix) {
+                            //view.setCurrentPosition(lat, lon);
+                            gpsData.setLatLon(new LatLon(lat, lon));
+                            gpsData.setSpeed(speed);
+                            gpsData.setCourse(course);
+                            fireGpsDataChangeEvent(oldGpsData, gpsData);
+                        }
+                    }
+                } else {
+                    // not connected:
+                    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
+                    try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
+                }
+            } catch(IOException iox) {
+                connected = false;
+                if(gpsData != null) {
+                    gpsData.setFix(false);
+                    fireGpsDataChangeEvent(oldGpsData, gpsData);
+                }
+                fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTION_FAILED, tr("Connection Failed"));
+                try { Thread.sleep(1000); } catch (InterruptedException ignore) {};
+                // send warning to layer
+
+            }
+        }
+
+    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED, tr("Not connected"));
+        if (gpsdSocket != null) {
+      try {
+        gpsdSocket.close();
+        gpsdSocket = null;
+            System.out.println("LiveGps: Disconnected from gpsd");
+      }
+      catch (Exception e) {
+        System.out.println("LiveGps: Unable to close socket; reconnection may not be possible");
+      };
+      }
+  }
+
+    public void shutdown()
+    {
+        shutdownFlag = true;
+    }
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java	(revision 14057)
@@ -0,0 +1,211 @@
+/**
+ *
+ */
+package livegps;
+
+import java.awt.Point;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.Way;
+
+/**
+ * @author cdaller
+ *
+ */
+public class LiveGpsData {
+    private LatLon latLon;
+    private float course;
+    private float speed;
+    private boolean fix;
+    private String wayString;
+    private Way way;
+
+    /**
+     * @param latitude
+     * @param longitude
+     * @param course
+     * @param speed
+     * @param haveFix
+     */
+    public LiveGpsData(double latitude, double longitude, float course, float speed, boolean haveFix) {
+        super();
+        this.latLon = new LatLon(latitude, longitude);
+        this.course = course;
+        this.speed = speed;
+        this.fix = haveFix;
+    }
+    /**
+     *
+     */
+    public LiveGpsData() {
+        // TODO Auto-generated constructor stub
+    }
+    /**
+     * @return the course
+     */
+    public float getCourse() {
+        return this.course;
+    }
+    /**
+     * @param course the course to set
+     */
+    public void setCourse(float course) {
+        this.course = course;
+    }
+    /**
+     * @return the haveFix
+     */
+    public boolean isFix() {
+        return this.fix;
+    }
+    /**
+     * @param haveFix the haveFix to set
+     */
+    public void setFix(boolean haveFix) {
+        this.fix = haveFix;
+    }
+    /**
+     * @return the latitude
+     */
+    public double getLatitude() {
+        return this.latLon.lat();
+    }
+    /**
+     * @return the longitude
+     */
+    public double getLongitude() {
+        return this.latLon.lon();
+    }
+    /**
+     * @return the speed in metres per second!
+     */
+    public float getSpeed() {
+        return this.speed;
+    }
+    /**
+     * @param speed the speed to set
+     */
+    public void setSpeed(float speed) {
+        this.speed = speed;
+    }
+
+    /**
+     * @return the latlon
+     */
+    public LatLon getLatLon() {
+        return this.latLon;
+    }
+
+    /**
+     * @param latLon
+     */
+    public void setLatLon(LatLon latLon) {
+        this.latLon = latLon;
+    }
+
+    public String toString() {
+        return getClass().getSimpleName() + "[fix=" + fix + ", lat=" + latLon.lat()
+        + ", long=" + latLon.lon() + ", speed=" + speed + ", course=" + course + "]";
+
+    }
+
+    /**
+     * Returns the name of the way that is closest to the current coordinates or an
+     * empty string if no way is around.
+     *
+     * @return the name of the way that is closest to the current coordinates.
+     */
+    public String getWayInfo() {
+        if(wayString == null) {
+            Way way = getWay();
+            if(way != null) {
+                StringBuilder builder = new StringBuilder();
+                String tmp = way.get("name");
+                if(tmp != null) {
+                    builder.append(tmp);
+                } else {
+                    builder.append("no name");
+                }
+                tmp = way.get("ref");
+                if(tmp != null) {
+                    builder.append(" (").append(tmp).append(")");
+                }
+                tmp = way.get("highway");
+                if(tmp != null) {
+                    builder.append(" {").append(tmp).append("}");
+                }
+                String type = "";
+                tmp = way.get("tunnel");
+                if(tmp != null) {
+                    type = type + "T";
+                }
+                tmp = way.get("bridge");
+                if(tmp != null) {
+                    type = type + "B";
+                }
+                if(type.length() > 0) {
+                    builder.append(" [").append(type).append("]");
+                }
+                wayString = builder.toString();
+            } else {
+                wayString = "";
+            }
+        }
+        return wayString;
+    }
+
+    /**
+     * Returns the closest way to this position.
+     * @return the closest way to this position.
+     */
+    public Way getWay() {
+        if(way == null) {
+            EastNorth eastnorth = Main.proj.latlon2eastNorth(getLatLon());
+            Point xy = Main.map.mapView.getPoint(eastnorth);
+            way = Main.map.mapView.getNearestWay(xy);
+        }
+        return way;
+
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Float.floatToIntBits(this.course);
+        result = prime * result + ((this.latLon == null) ? 0 : this.latLon.hashCode());
+        result = prime * result + Float.floatToIntBits(this.speed);
+        return result;
+    }
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        final LiveGpsData other = (LiveGpsData) obj;
+        if (Float.floatToIntBits(this.course) != Float.floatToIntBits(other.course))
+            return false;
+        if (this.latLon == null) {
+            if (other.latLon != null)
+                return false;
+        } else if (!this.latLon.equals(other.latLon))
+            return false;
+        if (Float.floatToIntBits(this.speed) != Float.floatToIntBits(other.speed))
+            return false;
+        return true;
+    }
+
+
+
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java	(revision 14057)
@@ -0,0 +1,108 @@
+/**
+ *
+ */
+package livegps;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GridLayout;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.tools.Shortcut;
+
+/**
+ * @author cdaller
+ *
+ */
+public class LiveGpsDialog extends ToggleDialog implements PropertyChangeListener {
+    private static final long serialVersionUID = 6183400754671501117L;
+    private JLabel statusLabel;
+    private JLabel wayLabel;
+    private JLabel latLabel;
+    private JLabel longLabel;
+    private JLabel courseLabel;
+    private JLabel speedLabel;
+    private JPanel panel;
+
+    /**
+     * @param name
+     * @param iconName
+     * @param tooltip
+     * @param shortcut
+     * @param preferredHeight
+     */
+    public LiveGpsDialog(final MapFrame mapFrame) {
+        super(tr("Live GPS"), "livegps", tr("Show GPS data."),
+        Shortcut.registerShortcut("subwindow:livegps", tr("Toggle: {0}", tr("Live GPS")),
+        KeyEvent.VK_G, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 100);
+        panel = new JPanel();
+        panel.setLayout(new GridLayout(6,2));
+        panel.add(new JLabel(tr("Status")));
+        panel.add(statusLabel = new JLabel());
+        panel.add(new JLabel(tr("Way Info")));
+        panel.add(wayLabel = new JLabel());
+        panel.add(new JLabel(tr("Latitude")));
+        panel.add(latLabel = new JLabel());
+        panel.add(new JLabel(tr("Longitude")));
+        panel.add(longLabel = new JLabel());
+        panel.add(new JLabel(tr("Speed")));
+        panel.add(speedLabel = new JLabel());
+        panel.add(new JLabel(tr("Course")));
+        panel.add(courseLabel = new JLabel());
+        add(new JScrollPane(panel), BorderLayout.CENTER);
+    }
+
+    /* (non-Javadoc)
+     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+     */
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (!isVisible())
+            return;
+        if("gpsdata".equals(evt.getPropertyName())) {
+            LiveGpsData data = (LiveGpsData) evt.getNewValue();
+            if(data.isFix()) {
+//                fixLabel.setText("fix");
+                panel.setBackground(Color.WHITE);
+                latLabel.setText(data.getLatitude() + "deg");
+                longLabel.setText(data.getLongitude() + "deg");
+                double mySpeed = data.getSpeed() * 3.6f;
+                speedLabel.setText((Math.round(mySpeed*100)/100) + "km/h"); // m(s to km/h
+                courseLabel.setText(data.getCourse() + "deg");
+
+                String wayString = data.getWayInfo();
+                if(wayString.length() > 0) {
+                    wayLabel.setText(wayString);
+                } else {
+                    wayLabel.setText("unknown");
+                }
+
+            } else {
+//                fixLabel.setText("no fix");
+                latLabel.setText("");
+                longLabel.setText("");
+                speedLabel.setText("");
+                courseLabel.setText("");
+                panel.setBackground(Color.RED);
+            }
+        } else if ("gpsstatus".equals(evt.getPropertyName())) {
+            LiveGpsStatus status = (LiveGpsStatus) evt.getNewValue();
+            statusLabel.setText(status.getStatusMessage());
+            if(status.getStatus() != LiveGpsStatus.GpsStatus.CONNECTED) {
+                panel.setBackground(Color.RED);
+            } else {
+                panel.setBackground(Color.WHITE);
+            }
+        }
+
+    }
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java	(revision 14057)
@@ -0,0 +1,159 @@
+package livegps;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.data.gpx.GpxTrack;
+import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.GpxLayer;
+import org.openstreetmap.josm.tools.ColorHelper;
+
+public class LiveGpsLayer extends GpxLayer implements PropertyChangeListener {
+    public static final String LAYER_NAME = tr("LiveGPS layer");
+    public static final String KEY_LIVEGPS_COLOR ="color.livegps.position";
+    LatLon lastPos;
+    WayPoint lastPoint;
+    GpxTrack trackBeingWritten;
+    Collection<WayPoint> trackSegment;
+    float speed;
+    float course;
+    String status;
+    //JLabel lbl;
+    boolean autocenter;
+    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
+
+    public LiveGpsLayer(GpxData data)
+    {
+        super (data, LAYER_NAME);
+        trackBeingWritten = new GpxTrack();
+        trackBeingWritten.attr.put("desc", "josm live gps");
+        trackSegment = new ArrayList<WayPoint>();
+        trackBeingWritten.trackSegs.add(trackSegment);
+        data.tracks.add(trackBeingWritten);
+    }
+
+    void setCurrentPosition(double lat, double lon)
+    {
+        //System.out.println("adding pos " + lat + "," + lon);
+        LatLon thisPos = new LatLon(lat, lon);
+        if ((lastPos != null) && (thisPos.equalsEpsilon(lastPos))) {
+            // no change in position
+            // maybe show a "paused" cursor or some such
+            return;
+        }
+
+        lastPos = thisPos;
+        lastPoint = new WayPoint(thisPos);
+        lastPoint.attr.put("time", dateFormat.format(new Date()));
+        // synchronize when adding data, as otherwise the autosave action
+        // needs concurrent access and this results in an exception!
+        synchronized (LiveGpsLock.class) {
+            trackSegment.add(lastPoint);
+        }
+        if (autocenter) {
+            center();
+        }
+
+        //Main.map.repaint();
+    }
+
+    public void center()
+    {
+        if (lastPoint != null)
+            Main.map.mapView.zoomTo(lastPoint.eastNorth, Main.map.mapView.getScale());
+    }
+
+//  void setStatus(String status)
+//  {
+//      this.status = status;
+//      Main.map.repaint();
+//        System.out.println("LiveGps status: " + status);
+//  }
+
+    void setSpeed(float metresPerSecond)
+    {
+        speed = metresPerSecond;
+        //Main.map.repaint();
+    }
+
+    void setCourse(float degrees)
+    {
+        course = degrees;
+        //Main.map.repaint();
+    }
+
+    public void setAutoCenter(boolean ac)
+    {
+        autocenter = ac;
+    }
+
+    @Override public void paint(Graphics g, MapView mv)
+    {
+        //System.out.println("in paint");
+        synchronized (LiveGpsLock.class) {
+            //System.out.println("in synced paint");
+            super.paint(g, mv);
+//          int statusHeight = 50;
+//          Rectangle mvs = mv.getBounds();
+//          mvs.y = mvs.y + mvs.height - statusHeight;
+//          mvs.height = statusHeight;
+//          g.setColor(new Color(1.0f, 1.0f, 1.0f, 0.8f));
+//          g.fillRect(mvs.x, mvs.y, mvs.width, mvs.height);
+
+            if (lastPoint != null)
+            {
+                Point screen = mv.getPoint(lastPoint.eastNorth);
+                g.setColor(Main.pref.getColor(KEY_LIVEGPS_COLOR, Color.RED));
+                g.drawOval(screen.x-10, screen.y-10,20,20);
+                g.drawOval(screen.x-9, screen.y-9,18,18);
+            }
+
+//          lbl.setText("gpsd: "+status+" Speed: " + speed + " Course: "+course);
+//          lbl.setBounds(0, 0, mvs.width-10, mvs.height-10);
+//          Graphics sub = g.create(mvs.x+5, mvs.y+5, mvs.width-10, mvs.height-10);
+//          lbl.paint(sub);
+
+//          if(status != null) {
+//          g.setColor(Color.WHITE);
+//          g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15); // lower left corner
+//          }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+     */
+    public void propertyChange(PropertyChangeEvent evt) {
+        if(!visible) {
+            return;
+        }
+        if("gpsdata".equals(evt.getPropertyName())) {
+            LiveGpsData data = (LiveGpsData) evt.getNewValue();
+            if(data.isFix()) {
+                setCurrentPosition(data.getLatitude(), data.getLongitude());
+                if(!Float.isNaN(data.getSpeed())) {
+                    setSpeed(data.getSpeed());
+                }
+                if(!Float.isNaN(data.getCourse())) {
+                    setCourse(data.getCourse());
+                }
+                Main.map.repaint();
+            }
+        }
+
+    }
+
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLock.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLock.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLock.java	(revision 14057)
@@ -0,0 +1,16 @@
+/**
+ *
+ */
+package livegps;
+
+/**
+ * This class is only used to prevent concurrent object modification. So all classes that
+ * read or write live gps data must synchronize to this class. Especially the save action
+ * takes quite long, so concurrency problems occur.
+ *
+ * @author cdaller
+ *
+ */
+public class LiveGpsLock {
+
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 14057)
@@ -0,0 +1,197 @@
+package livegps;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.data.gpx.GpxData;
+import org.openstreetmap.josm.gui.MainMenu;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.tools.Shortcut;
+
+public class LiveGpsPlugin extends Plugin
+{
+    private LiveGpsAcquirer acquirer = null;
+    private Thread acquirerThread = null;
+    private JMenu lgpsmenu;
+    private JCheckBoxMenuItem lgpscapture;
+    private JMenuItem lgpscenter;
+    private JCheckBoxMenuItem lgpsautocenter;
+    private LiveGpsDialog lgpsdialog;
+    List<PropertyChangeListener>listenerQueue;
+
+    private GpxData data = new GpxData();
+    private LiveGpsLayer lgpslayer;
+
+
+    public class CaptureAction extends JosmAction {
+        public CaptureAction() {
+            super(tr("Capture GPS Track"), "capturemenu", tr("Connect to gpsd server and show current position in LiveGPS layer."),
+                Shortcut.registerShortcut("menu:livegps:capture", tr("Menu: {0}", tr("Capture GPS Track")),
+                KeyEvent.VK_R, Shortcut.GROUP_MENU), true);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            enableTracking(lgpscapture.isSelected());
+        }
+    }
+
+    public class CenterAction extends JosmAction {
+        public CenterAction() {
+            super(tr("Center Once"), "centermenu", tr("Center the LiveGPS layer to current position."),
+            Shortcut.registerShortcut("edit:centergps", tr("Edit: {0}", tr("Center Once")),
+            KeyEvent.VK_HOME, Shortcut.GROUP_EDIT), true);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if(lgpslayer != null) {
+                lgpslayer.center();
+            }
+        }
+    }
+
+    public class AutoCenterAction extends JosmAction {
+        public AutoCenterAction() {
+            super(tr("Auto-Center"), "autocentermenu", tr("Continuously center the LiveGPS layer to current position."),
+            Shortcut.registerShortcut("menu:livegps:autocenter", tr("Menu: {0}", tr("Capture GPS Track")),
+            KeyEvent.VK_HOME, Shortcut.GROUP_MENU), true);
+        }
+
+        public void actionPerformed(ActionEvent e) {
+            if(lgpslayer != null) {
+                setAutoCenter(lgpsautocenter.isSelected());
+            }
+        }
+    }
+
+    public LiveGpsPlugin()
+    {
+        MainMenu menu = Main.main.menu;
+        lgpsmenu = new JMenu(tr("LiveGPS"));
+        menu.add(lgpsmenu, KeyEvent.VK_G, "livegps");
+        menu.add(lgpsmenu, 5);
+
+        JosmAction captureAction = new CaptureAction();
+        lgpscapture = new JCheckBoxMenuItem(captureAction);
+        lgpsmenu.add(lgpscapture);
+        lgpscapture.setAccelerator(captureAction.getShortcut().getKeyStroke());
+
+        JosmAction centerAction = new CenterAction();
+        JMenuItem centerMenu = new JMenuItem(centerAction);
+        lgpsmenu.add(centerMenu);
+        centerMenu.setAccelerator(centerAction.getShortcut().getKeyStroke());
+
+        JosmAction autoCenterAction = new AutoCenterAction();
+        lgpsautocenter = new JCheckBoxMenuItem(autoCenterAction);
+        lgpsmenu.add(lgpsautocenter);
+        lgpsautocenter.setAccelerator(autoCenterAction.getShortcut().getKeyStroke());
+    }
+
+    /**
+     * Set to <code>true</code> if the current position should always be in the center of the map.
+     * @param autoCenter if <code>true</code> the map is always centered.
+     */
+    public void setAutoCenter(boolean autoCenter) {
+        lgpsautocenter.setSelected(autoCenter); // just in case this method was not called from the menu
+        if(lgpslayer != null) {
+            lgpslayer.setAutoCenter(autoCenter);
+            if (autoCenter) lgpslayer.center();
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if autocenter is selected.
+     * @return <code>true</code> if autocenter is selected.
+     */
+    public boolean isAutoCenter() {
+        return lgpsautocenter.isSelected();
+    }
+
+    /**
+     * Enable or disable gps tracking
+     * @param enable if <code>true</code> tracking is started.
+     */
+    public void enableTracking(boolean enable) {
+        if ((acquirer != null) && (!enable))
+        {
+            acquirer.shutdown();
+            acquirerThread = null;
+        }
+        else if(enable)
+        {
+            if (acquirer == null) {
+                acquirer = new LiveGpsAcquirer(getPluginDir());
+                if (lgpslayer == null) {
+                    lgpslayer = new LiveGpsLayer(data);
+                    Main.main.addLayer(lgpslayer);
+                    lgpslayer.setAutoCenter(isAutoCenter());
+                }
+                // connect layer with acquirer:
+                addPropertyChangeListener(lgpslayer);
+                // add all listeners that were added before the acquirer existed:
+                if(listenerQueue != null) {
+                    for(PropertyChangeListener listener : listenerQueue) {
+                        addPropertyChangeListener(listener);
+                    }
+                    listenerQueue.clear();
+                }
+            }
+            if(acquirerThread == null) {
+                acquirerThread = new Thread(acquirer);
+                acquirerThread.start();
+            }
+        }
+    }
+
+
+    /**
+     * Add a listener for gps events.
+     * @param listener the listener.
+     */
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+        if(acquirer != null) {
+            acquirer.addPropertyChangeListener(listener);
+        } else {
+            if(listenerQueue == null) {
+                listenerQueue = new ArrayList<PropertyChangeListener>();
+            }
+            listenerQueue.add(listener);
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.openstreetmap.josm.plugins.Plugin#mapFrameInitialized(org.openstreetmap.josm.gui.MapFrame, org.openstreetmap.josm.gui.MapFrame)
+     */
+    @Override
+    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+        if(newFrame != null) {
+            // add dialog
+            newFrame.addToggleDialog(lgpsdialog = new LiveGpsDialog(newFrame));
+            // connect listeners with acquirer:
+            addPropertyChangeListener(lgpsdialog);
+        }
+    }
+
+
+    /**
+     * @return the lgpsmenu
+     */
+    public JMenu getLgpsMenu() {
+        return this.lgpsmenu;
+    }
+
+}
+
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java	(revision 14057)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java	(revision 14057)
@@ -0,0 +1,49 @@
+/**
+ *
+ */
+package livegps;
+
+/**
+ * @author cdaller
+ *
+ */
+public class LiveGpsStatus {
+    public enum GpsStatus {CONNECTING, CONNECTED, DISCONNECTED, CONNECTION_FAILED};
+    private String statusMessage;
+    private GpsStatus status;
+
+    /**
+     * @param status
+     * @param statusMessage
+     */
+    public LiveGpsStatus(GpsStatus status, String statusMessage) {
+        super();
+        this.status = status;
+        this.statusMessage = statusMessage;
+    }
+/**
+     * @return the status
+     */
+    public GpsStatus getStatus() {
+        return this.status;
+    }
+    /**
+     * @param status the status to set
+     */
+    public void setStatus(GpsStatus status) {
+        this.status = status;
+    }
+    /**
+     * @return the statusMessage
+     */
+    public String getStatusMessage() {
+        return this.statusMessage;
+    }
+    /**
+     * @param statusMessage the statusMessage to set
+     */
+    public void setStatusMessage(String statusMessage) {
+        this.statusMessage = statusMessage;
+    }
+
+}
