Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGPSPreferences.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGPSPreferences.java	(revision 36107)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGPSPreferences.java	(revision 36107)
@@ -0,0 +1,61 @@
+// License: Public Domain. For details, see LICENSE file.
+package livegps;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+
+import javax.swing.Box;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
+import org.openstreetmap.josm.gui.preferences.PreferenceTabbedPane;
+import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.tools.GBC;
+
+/**
+ * Preferences of LiveGPS
+ */
+public class LiveGPSPreferences extends DefaultTabPreferenceSetting {
+    private final JTextField gpsdHost = new JTextField(30);
+    private final JTextField gpsdPort = new JTextField(30);
+    private final JTextField serialDevice = new JTextField(30);
+
+    public LiveGPSPreferences() {
+        super("dialogs/livegps", tr("LiveGPS settings"), tr("Here you can change some preferences of LiveGPS plugin"));
+    }
+
+    @Override
+    public void addGui(PreferenceTabbedPane gui) {
+        JPanel panel = new JPanel(new GridBagLayout());
+
+        gpsdHost.setText(Config.getPref().get(LiveGpsAcquirer.C_HOST, LiveGpsAcquirer.DEFAULT_HOST));
+        gpsdHost.setToolTipText(tr("Host address of gpsd, default is {0}", LiveGpsAcquirer.DEFAULT_HOST));
+        panel.add(new JLabel(tr("Host address of gpsd")), GBC.std());
+        panel.add(gpsdHost, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(5, 0, 0, 5));
+
+        gpsdPort.setText(String.valueOf(Config.getPref().getInt(LiveGpsAcquirer.C_PORT, LiveGpsAcquirer.DEFAULT_PORT)));
+        gpsdPort.setToolTipText(tr("Port number of gpsd, default is {0}", LiveGpsAcquirer.DEFAULT_PORT));
+        panel.add(new JLabel(tr("Port number gpsd")), GBC.std());
+        panel.add(gpsdPort, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(5, 0, 0, 5));
+
+        serialDevice.setText(Config.getPref().get(LiveGpsAcquirerNMEA.C_SERIAL));
+        serialDevice.setToolTipText(tr("Serial device for direct NMEA input, does not exist by default"));
+        panel.add(new JLabel(tr("Serial device")), GBC.std());
+        panel.add(serialDevice, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(5, 0, 0, 5));
+
+        panel.add(Box.createVerticalGlue(), GBC.eol().fill(GridBagConstraints.VERTICAL));
+        createPreferenceTabWithScrollPane(gui, panel);
+    }
+
+    @Override
+    public boolean ok() {
+        Config.getPref().put(LiveGpsAcquirer.C_HOST, gpsdHost.getText());
+        Config.getPref().put(LiveGpsAcquirer.C_PORT, gpsdPort.getText());
+        Config.getPref().put(LiveGpsAcquirerNMEA.C_SERIAL, serialDevice.getText());
+        return false;
+    }
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java	(revision 35978)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java	(revision 36107)
@@ -25,8 +25,12 @@
 
 public class LiveGpsAcquirer implements Runnable {
-    private static final String DEFAULT_HOST = "localhost";
-    private static final int DEFAULT_PORT = 2947;
-    private static final String C_HOST = "livegps.gpsd.host";
-    private static final String C_PORT = "livegps.gpsd.port";
+    /* default gpsd host address */
+    public static final String DEFAULT_HOST = "localhost";
+    /* default gpsd port number */
+    public static final int DEFAULT_PORT = 2947;
+    /* option to use specify gpsd host address */
+    public static final String C_HOST = "livegps.gpsd.host";
+    /* option to use specify gpsd port number */
+    public static final String C_PORT = "livegps.gpsd.port";
     private String gpsdHost;
     private int gpsdPort;
@@ -37,4 +41,6 @@
     private boolean shutdownFlag = false;
     private boolean JSONProtocol = true;
+    private long skipTime = 0L;
+    private int skipNum = 0;
 
     private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<>();
@@ -139,5 +145,5 @@
             }
 
-            assert (connected);
+            assert connected;
 
             try {
@@ -191,5 +197,13 @@
         String line, type, release;
 
-        Logging.info("LiveGps: trying to connect to gpsd at " + gpsdHost + ":" + gpsdPort);
+        long t = System.currentTimeMillis();
+        if (skipTime == 0 || t > skipTime) {
+            skipTime = 0;
+            Logging.info("LiveGps: trying to connect to gpsd at " + gpsdHost + ":"
+                + gpsdPort + (skipNum != 0 ? " (skipped " + skipNum + " notices)" : ""));
+            skipNum = 0;
+        } else {
+          ++skipNum;
+        }
         fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
 
@@ -200,11 +214,18 @@
                 break;
             } catch (IOException e) {
-                Logging.warn("LiveGps: Could not open connection to gpsd: " + e);
+                if (skipTime == 0) {
+                    Logging.warn("LiveGps: Could not open connection to gpsd ("+addrs[i]+"): " + e);
+                }
                 gpsdSocket = null;
             }
         }
 
-        if (gpsdSocket == null || gpsdSocket.isConnected() == false)
+        if (gpsdSocket == null || gpsdSocket.isConnected() == false) {
+            if (skipTime == 0)
+                skipTime = System.currentTimeMillis()+60000;
             throw new IOException();
+        }
+        skipTime = 0;
+        skipNum = 0;
 
         /*
@@ -311,5 +332,5 @@
 
         words = line.split(",");
-        if ((words.length == 0) || (!words[0].equals("GPSD")))
+        if ((words.length == 0) || !words[0].equals("GPSD"))
             return null;
 
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirerNMEA.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirerNMEA.java	(revision 36107)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirerNMEA.java	(revision 36107)
@@ -0,0 +1,234 @@
+// License: Public Domain. For details, see LICENSE file.
+package livegps;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.io.nmea.NmeaParser;
+import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.tools.Logging;
+
+/**
+ * Acquires NMEA data from a (virtual) serial port
+ */
+public class LiveGpsAcquirerNMEA implements Runnable {
+    /* option to use serial port direct access */
+    public static final String C_SERIAL = "livegps.serial.port";
+    private String serName;
+
+    private InputStreamReader serReader;
+    private NmeaParser parser;
+    private boolean connected = false;
+    private boolean shutdownFlag = false;
+
+    private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<>();
+    private PropertyChangeEvent lastStatusEvent;
+    private PropertyChangeEvent lastDataEvent;
+
+    /**
+     * Constructor, initializes the configurable settings.
+     */
+    public LiveGpsAcquirerNMEA() {
+        serName = Config.getPref().get(C_SERIAL);
+    }
+
+    /**
+     * 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);
+        }
+    }
+
+    /**
+     * Remove a property change listener from the acquirer.
+     * @param listener the new listener
+     */
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+        if (propertyChangeListener.contains(listener)) {
+            propertyChangeListener.remove(listener);
+        }
+    }
+
+    /**
+     * Fire a gps status change event. Fires events with key "gpsstatus" and a {@link LiveGpsStatus}
+     * object as value.
+     * The status event may be sent any time.
+     * @param status the status.
+     * @param statusMessage the status message.
+     */
+    public void fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus status, String statusMessage) {
+        PropertyChangeEvent event = new PropertyChangeEvent(this, "nmeastatus",
+                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.
+     * This event is only sent, when the suppressor permits it. This
+     * event will cause the UI to re-draw itself, which has some performance penalty,
+     * @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);
+        }
+    }
+
+    @Override
+    public void run() {
+        LiveGpsData oldGpsData = null;
+
+        shutdownFlag = false;
+        while (!shutdownFlag) {
+            while (!connected) {
+                try {
+                    connect();
+                } catch (IOException iox) {
+                    fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTION_FAILED, tr("NMEA Connection Failed"));
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException ignore) {
+                        Logging.trace(ignore);
+                    }
+                }
+            }
+
+            assert connected;
+
+            try {
+                StringBuilder sb = new StringBuilder(1024);
+                int loopstartChar = serReader.read();
+                if (loopstartChar == -1)
+                    throw new IOException();
+                sb.append((char) loopstartChar);
+                Instant lasttime = null;
+                while (true) {
+                    // handle long useless data
+                    if (sb.length() >= 1020) {
+                        sb.delete(0, sb.length()-1);
+                    }
+                    int c = serReader.read();
+                    if (c == '$') {
+                        parser.parseNMEASentence(sb.toString());
+                        sb.delete(0, sb.length());
+                        sb.append('$');
+                    } else if (c == -1) {
+                        throw new IOException();
+                    } else {
+                        sb.append((char) c);
+                    }
+                    if (!serReader.ready()) {
+                        try {
+                            Thread.sleep(50);
+                        } catch (InterruptedException ignore) {
+                            Logging.trace(ignore);
+                        }
+                    }
+                    if (!serReader.ready()) {
+                        WayPoint last = null;
+                        Collection<WayPoint> wpts = parser.getAndDropWaypoints();
+                        for (WayPoint w : wpts) {
+                            if(w.getInstant() == null)
+                                continue;
+                            if (w.getInstant().equals(lasttime)) {
+                                Logging.info("Skip double waypoint at " + lasttime);
+                            } else {
+                                last = w;
+                                float course = 0.0f;
+                                float speed = 0.0f;
+                                if (w.getString("course") != null)
+                                    course = Float.valueOf(w.getString("course"));
+                                if (w.getString("speed") != null)
+                                    speed = Float.valueOf(w.getString("speed"));
+                                LiveGpsData gpsData = new LiveGpsData(w.lat(), w.lon(), course, speed, 0.0f, 0.0f);
+                                gpsData.setWaypoint(w);
+                                fireGpsDataChangeEvent(oldGpsData, gpsData);
+                                oldGpsData = gpsData;
+                            }
+                        }
+                        if (last != null) {
+                            lasttime = last.getInstant();
+                        }
+                    }
+                }
+            } catch (IOException iox) {
+                Logging.log(Logging.LEVEL_WARN, "LiveGps: lost connection to NMEA", iox);
+                fireGpsStatusChangeEvent(
+                        LiveGpsStatus.GpsStatus.CONNECTION_FAILED,
+                        tr("NMEA Connection Failed"));
+                disconnect();
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException ignore) {
+                    Logging.trace(ignore);
+                }
+            } catch (IllegalDataException ex) {
+                Logging.log(Logging.LEVEL_WARN, "LiveGps: Illegal NMEA", ex);
+            }
+        }
+
+        Logging.info("LiveGps: Disconnected from NMEA");
+        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.DISCONNECTED,
+                tr("NMEA Not connected"));
+        disconnect();
+    }
+
+    public void shutdown() {
+        shutdownFlag = true;
+    }
+
+    private void connect() throws IOException {
+        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
+        serReader = new InputStreamReader(new FileInputStream(serName), StandardCharsets.UTF_8);
+        parser = new NmeaParser();
+        fireGpsStatusChangeEvent(LiveGpsStatus.GpsStatus.CONNECTED, tr("Connected"));
+        connected = true;
+    }
+
+    private void disconnect() {
+        if (serReader != null) {
+            try {
+                serReader.close();
+            } catch (IOException iox) {
+                Logging.warn("LiveGps: Unable to close NMEA; reconnection may not be possible");
+            }
+            serReader = null;
+        }
+        parser = null;
+        connected = false;
+    }
+}
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java	(revision 35978)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java	(revision 36107)
@@ -7,4 +7,5 @@
 
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.gpx.WayPoint;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Way;
@@ -13,6 +14,6 @@
 
 /**
+ * Representation of a single LiveGPS data epoch
  * @author cdaller
- *
  */
 public class LiveGpsData {
@@ -24,4 +25,5 @@
     private String wayString;
     private Way way;
+    private WayPoint wp;
 
     public LiveGpsData(double latitude, double longitude, float course, float speed) {
@@ -42,5 +44,22 @@
 
     /**
-     * @return the course
+     * Return the waypoint associated with this data set (can be {@code null})
+     * @return waypoint with additional information or {@code null}
+     */
+    public WayPoint getWaypoint() {
+        return this.wp;
+    }
+
+    /**
+     * Set the waypoint to transfer additional data form NMEA input
+     * @param wp waypoint to set
+     */
+    public void setWaypoint(WayPoint wp) {
+        this.wp = wp;
+    }
+
+    /**
+     * Return the course value
+     * @return course value in degree
      */
     public float getCourse() {
@@ -49,5 +68,6 @@
 
     /**
-     * @param course the course to set
+     * Set the course value in degree
+     * @param course course to set
      */
     public void setCourse(float course) {
@@ -56,5 +76,6 @@
 
     /**
-     * @return the haveFix
+     * Return the fix status (whether there is a position solution or not)
+     * @return fix status
      */
     public boolean isFix() {
@@ -63,4 +84,5 @@
 
     /**
+     * Set the fix status (whether there is a position solution or not)
      * @param haveFix the haveFix to set
      */
@@ -70,5 +92,6 @@
 
     /**
-     * @return the latitude
+     * Return the latitude part of the position
+     * @return latitude of position
      */
     public double getLatitude() {
@@ -77,5 +100,6 @@
 
     /**
-     * @return the longitude
+     * Return the longitude part of the position
+     * @return longitude of position
      */
     public double getLongitude() {
@@ -84,5 +108,6 @@
 
     /**
-     * @return the speed in metres per second!
+     * Return the speed (m/s)
+     * @return speed in metres per second!
      */
     public float getSpeed() {
@@ -91,4 +116,5 @@
 
     /**
+     * Set the speed (m/s)
      * @param speed the speed to set
      */
@@ -98,5 +124,6 @@
 
     /**
-     * @return the latlon
+     * Return the position with latitude and logitude combined
+     * @return both position components
      */
     public LatLon getLatLon() {
@@ -104,4 +131,8 @@
     }
 
+    /**
+     * Set the position with latitude and logitude combined
+     * @param latLon position to set
+     */
     public void setLatLon(LatLon latLon) {
         this.latLon = latLon;
@@ -202,7 +233,5 @@
         if (this == obj)
             return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
+        if (!(obj instanceof LiveGpsData))
             return false;
         final LiveGpsData other = (LiveGpsData) obj;
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java	(revision 35978)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java	(revision 36107)
@@ -14,15 +14,19 @@
 import javax.swing.SwingUtilities;
 
+import org.openstreetmap.josm.data.coor.conversion.CoordinateFormatManager;
+import org.openstreetmap.josm.data.coor.conversion.ICoordinateFormat;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
+import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
+ * The LiveGPS dialog window showing the current data and status
  * @author cdaller
- *
  */
 public class LiveGpsDialog extends ToggleDialog implements PropertyChangeListener {
     private static final long serialVersionUID = 6183400754671501117L;
     private JLabel statusLabel;
+    private JLabel nmeaStatusLabel;
     private JLabel wayLabel;
     private JLabel latLabel;
@@ -31,5 +35,6 @@
     private JLabel speedLabel;
     private JPanel panel;
-    private LiveGpsStatus status;
+    private LiveGpsStatus status = new LiveGpsStatus(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
+    private LiveGpsStatus nmeaStatus = new LiveGpsStatus(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
     private LiveGpsData data;
 
@@ -39,7 +44,11 @@
         KeyEvent.VK_G, Shortcut.ALT_CTRL_SHIFT), 100);
         panel = new JPanel();
-        panel.setLayout(new GridLayout(6, 2));
-        panel.add(new JLabel(tr("Status")));
+        panel.setLayout(new GridLayout(7, 2));
+        panel.add(new JLabel(tr("Status gpsd")));
         panel.add(statusLabel = new JLabel());
+        if (!Config.getPref().get(LiveGpsAcquirerNMEA.C_SERIAL).isEmpty()) {
+          panel.add(new JLabel(tr("Status NMEA")));
+          panel.add(nmeaStatusLabel = new JLabel());
+        }
         panel.add(new JLabel(tr("Way Info")));
         panel.add(wayLabel = new JLabel());
@@ -68,9 +77,10 @@
                 if (data.isFix()) {
                     panel.setBackground(Color.WHITE);
-                    latLabel.setText(data.getLatitude() + "deg");
-                    longLabel.setText(data.getLongitude() + "deg");
+                    ICoordinateFormat mCord = CoordinateFormatManager.getDefaultFormat();
+                    latLabel.setText(mCord.latToString(data.getLatLon()));
+                    longLabel.setText(mCord.lonToString(data.getLatLon()));
                     double mySpeed = data.getSpeed() * 3.6f;
-                    speedLabel.setText((Math.round(mySpeed*100)/100) + "km/h");
-                    courseLabel.setText(data.getCourse() + "deg");
+                    speedLabel.setText(tr("{0} km/h", Math.round(mySpeed*100)/100));
+                    courseLabel.setText(tr("{0} deg", data.getCourse()));
 
                     String wayString = data.getWayInfo();
@@ -89,4 +99,5 @@
             } });
         } else if ("gpsstatus".equals(evt.getPropertyName())) {
+            LiveGpsStatus oldStatus = status;
             status = (LiveGpsStatus) evt.getNewValue();
 
@@ -94,6 +105,8 @@
             @Override
             public void run() {
-                statusLabel.setText(status.getStatusMessage());
-                if (status.getStatus() != LiveGpsStatus.GpsStatus.CONNECTED) {
+                /* prevent flickering - skip the connecting message when NMEA input is working */
+                if (!(oldStatus.getStatus() == LiveGpsStatus.GpsStatus.CONNECTION_FAILED && status.getStatus() == LiveGpsStatus.GpsStatus.CONNECTING && nmeaStatus.getStatus() == LiveGpsStatus.GpsStatus.CONNECTED))
+                    statusLabel.setText(status.getStatusMessage());
+                if (status.getStatus() != LiveGpsStatus.GpsStatus.CONNECTED && nmeaStatus.getStatus() != LiveGpsStatus.GpsStatus.CONNECTED) {
                     panel.setBackground(Color.RED);
                 } else {
@@ -101,4 +114,12 @@
                 }
             } });
+        } else if ("nmeastatus".equals(evt.getPropertyName())) {
+            nmeaStatus = (LiveGpsStatus) evt.getNewValue();
+
+            SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                nmeaStatusLabel.setText(nmeaStatus.getStatusMessage());
+            } });
         }
     }
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java	(revision 35978)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java	(revision 36107)
@@ -63,5 +63,5 @@
     }
 
-    void setCurrentPosition(double lat, double lon) {
+    void setCurrentPosition(double lat, double lon, WayPoint wp) {
         LatLon thisPos = new LatLon(lat, lon);
         if (lastPos != null && thisPos.equalsEpsilon(lastPos, ILatLon.MAX_SERVER_PRECISION))
@@ -71,6 +71,10 @@
 
         lastPos = thisPos;
-        lastPoint = new WayPoint(thisPos);
-        lastPoint.attr.put("time", dateFormat.format(new Date()));
+        if (wp != null) {
+          lastPoint = wp;
+        } else {
+          lastPoint = new WayPoint(thisPos);
+          lastPoint.attr.put("time", dateFormat.format(new Date()));
+        }
         trackSegment.addWaypoint(lastPoint);
 
@@ -110,5 +114,5 @@
             lastData = (LiveGpsData) evt.getNewValue();
             if (lastData.isFix()) {
-                setCurrentPosition(lastData.getLatitude(), lastData.getLongitude());
+                setCurrentPosition(lastData.getLatitude(), lastData.getLongitude(), lastData.getWaypoint());
                 if (allowRedraw())
                     this.setFilterStateChanged();
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 35978)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 36107)
@@ -23,6 +23,8 @@
 import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
 import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
+import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -31,4 +33,6 @@
     private LiveGpsAcquirer acquirer = null;
     private Thread acquirerThread = null;
+    private LiveGpsAcquirerNMEA acquirerNMEA = null;
+    private Thread acquirerNMEAThread = null;
     private JMenu lgpsmenu = null;
     private JCheckBoxMenuItem lgpscapture;
@@ -186,6 +190,21 @@
             acquirerThread.start();
 
+            assert (acquirerNMEA == null);
+            assert (acquirerNMEAThread == null);
+
+            if (!Config.getPref().get(LiveGpsAcquirerNMEA.C_SERIAL).isEmpty()) {
+                acquirerNMEA = new LiveGpsAcquirerNMEA();
+                acquirerNMEAThread = new Thread(acquirerNMEA);
+                acquirerNMEA.addPropertyChangeListener(lgpslayer);
+                acquirerNMEA.addPropertyChangeListener(lgpsdialog);
+
+                for (PropertyChangeListener listener : listenerQueue) {
+                    acquirerNMEA.addPropertyChangeListener(listener);
+                }
+
+                acquirerNMEAThread.start();
+            }
+
             enabled = true;
-
         } else if (!enable && enabled) {
             assert (lgpslayer != null);
@@ -197,4 +216,10 @@
             acquirerThread = null;
 
+            if (acquirerNMEAThread != null) {
+                acquirerNMEA.shutdown();
+                acquirerNMEA = null;
+                acquirerNMEAThread = null;
+            }
+
             enabled = false;
         }
@@ -211,4 +236,6 @@
         if (acquirer != null)
             acquirer.addPropertyChangeListener(listener);
+        if (acquirerNMEA != null)
+            acquirerNMEA.addPropertyChangeListener(listener);
     }
 
@@ -223,4 +250,6 @@
         if (acquirer != null)
             acquirer.removePropertyChangeListener(listener);
+        if (acquirerNMEA != null)
+            acquirerNMEA.removePropertyChangeListener(listener);
     }
 
@@ -232,8 +261,14 @@
 
     /**
-     * @return the lgpsmenu
+     * Return the LiveGPS menu
+     * @return the {@code JMenu} entry
      */
     public JMenu getLgpsMenu() {
         return this.lgpsmenu;
     }
+
+    @Override
+    public PreferenceSetting getPreferenceSetting() {
+        return new LiveGPSPreferences();
+    }
 }
Index: applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java
===================================================================
--- applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java	(revision 35978)
+++ applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java	(revision 36107)
@@ -3,6 +3,6 @@
 
 /**
+ * Representation of the LiveGPS connection status
  * @author cdaller
- *
  */
 public class LiveGpsStatus {
@@ -14,4 +14,9 @@
     private GpsStatus status;
 
+    /**
+     * Create a status representation
+     * @param status current status code
+     * @param statusMessage current status description message
+     */
     public LiveGpsStatus(GpsStatus status, String statusMessage) {
         super();
@@ -21,5 +26,6 @@
 
     /**
-     * @return the status
+     * Retrieve the current status
+     * @return current status
      */
     public GpsStatus getStatus() {
@@ -28,4 +34,5 @@
 
     /**
+     * Set the current status
      * @param status the status to set
      */
@@ -35,5 +42,6 @@
 
     /**
-     * @return the statusMessage
+     * Access the status message
+     * @return status message
      */
     public String getStatusMessage() {
@@ -42,5 +50,6 @@
 
     /**
-     * @param statusMessage the statusMessage to set
+     * Set the current status message
+     * @param statusMessage the status message to set
      */
     public void setStatusMessage(String statusMessage) {
