Index: /applications/editors/josm/plugins/livegps/src/livegps/ILiveGpsSuppressor.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/ILiveGpsSuppressor.java	(revision 19011)
+++ /applications/editors/josm/plugins/livegps/src/livegps/ILiveGpsSuppressor.java	(revision 19011)
@@ -0,0 +1,20 @@
+package livegps;
+
+/**
+ * Interface for class LiveGpsSuppressor, only has a query if currently an update is allowed.
+ * 
+ * @author casualwalker 
+ *
+ */
+public interface ILiveGpsSuppressor {
+
+	/**
+	 * Query, if an update is currently allowed.
+	 * When it is allowed, it will disable the allowUpdate flag as a side effect.
+	 * (this means, one thread got to issue an update event)
+	 *
+	 * @return true, if an update is currently allowed; false, if the update shall be suppressed.
+	 */
+	boolean isAllowUpdate();
+
+}
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java	(revision 19010)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsAcquirer.java	(revision 19011)
@@ -17,279 +17,240 @@
 
 public class LiveGpsAcquirer implements Runnable {
-    Socket gpsdSocket;
-    BufferedReader gpsdReader;
-    boolean connected = false;
-    String gpsdHost = Main.pref.get("livegps.gpsd.host", "localhost");
-    int gpsdPort = Main.pref.getInteger("livegps.gpsd.port", 2947);
-    boolean shutdownFlag = false;
-    private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
-    private PropertyChangeEvent lastStatusEvent;
-    private PropertyChangeEvent lastDataEvent;
-
-    /**
-     * The LiveGpsSuppressor is queried, if an event shall be suppressed.
-     */
-    private LiveGpsSuppressor suppressor = null;
-
-    /**
-     * separate thread, where the LiveGpsSuppressor executes.
-     */
-    private Thread suppressorThread = null;
-
-    /**
-     * 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, "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.
-     * 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) && checkSuppress()) {
-            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;
-
-        initSuppressor();
-
-        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");
-            }
-        }
-    }
-
-    /**
-     * Initialize the suppressor and start its thread.
-     */
-    private void initSuppressor() {
-        suppressor = new LiveGpsSuppressor();
-        suppressorThread = new Thread(suppressor);
-        suppressorThread.start();
-    }
-
-    public void shutdown() {
-        // shut down the suppressor thread, too.
-        suppressor.shutdown();
-        this.suppressor = null;
-        shutdownFlag = true;
-    }
-
-    /**
-     * Check, if an event may be sent now.
-     * @return true, if an event may be sent.
-     */
-    private boolean checkSuppress() {
-        if (suppressor != null) {
-            if (suppressor.isAllowUpdate()) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            return true;
-        }
-    }
+	Socket gpsdSocket;
+	BufferedReader gpsdReader;
+	boolean connected = false;
+	String gpsdHost = Main.pref.get("livegps.gpsd.host", "localhost");
+	int gpsdPort = Main.pref.getInteger("livegps.gpsd.port", 2947);
+	boolean shutdownFlag = false;
+	private final List<PropertyChangeListener> propertyChangeListener = new ArrayList<PropertyChangeListener>();
+	private PropertyChangeEvent lastStatusEvent;
+	private PropertyChangeEvent lastDataEvent;
+
+	/**
+	 * 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, "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.
+	 * 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);
+		}
+	}
+
+	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/LiveGpsLayer.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java	(revision 19010)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsLayer.java	(revision 19011)
@@ -23,135 +23,167 @@
 
 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 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);
-    }
+	/**
+	 * The suppressor is queried, if the GUI shall be re-drawn.
+	 */
+	private ILiveGpsSuppressor suppressor;
 
-    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;
-        }
+	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);
+	}
 
-        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();
-        }
+	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;
+		}
 
-        //Main.map.repaint();
-    }
+		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 && allowRedraw()) {
+			center();
+		}
 
-    public void center()
-    {
-        if (lastPoint != null)
-            Main.map.mapView.zoomTo(lastPoint.getCoor());
-    }
+		// Main.map.repaint();
+	}
 
-//  void setStatus(String status)
-//  {
-//      this.status = status;
-//      Main.map.repaint();
-//        System.out.println("LiveGps status: " + status);
-//  }
+	public void center() {
+		if (lastPoint != null)
+			Main.map.mapView.zoomTo(lastPoint.getCoor());
+	}
 
-    void setSpeed(float metresPerSecond)
-    {
-        speed = metresPerSecond;
-        //Main.map.repaint();
-    }
+	// void setStatus(String status)
+	// {
+	// this.status = status;
+	// Main.map.repaint();
+	// System.out.println("LiveGps status: " + status);
+	// }
 
-    void setCourse(float degrees)
-    {
-        course = degrees;
-        //Main.map.repaint();
-    }
+	void setSpeed(float metresPerSecond) {
+		speed = metresPerSecond;
+		// Main.map.repaint();
+	}
 
-    public void setAutoCenter(boolean ac)
-    {
-        autocenter = ac;
-    }
+	void setCourse(float degrees) {
+		course = degrees;
+		// Main.map.repaint();
+	}
 
-    @Override public void paint(Graphics2D g, MapView mv, Bounds bounds)
-    {
-        //System.out.println("in paint");
-        synchronized (LiveGpsLock.class) {
-            //System.out.println("in synced paint");
-            super.paint(g, mv, bounds);
-//          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);
+	public void setAutoCenter(boolean ac) {
+		autocenter = ac;
+	}
 
-            if (lastPoint != null)
-            {
-                Point screen = mv.getPoint(lastPoint.getCoor());
-                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);
-            }
+	@Override
+	public void paint(Graphics2D g, MapView mv, Bounds bounds) {
+		// System.out.println("in paint");
+		synchronized (LiveGpsLock.class) {
+			// System.out.println("in synced paint");
+			super.paint(g, mv, bounds);
+			// 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);
 
-//          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 (lastPoint != null) {
+				Point screen = mv.getPoint(lastPoint.getCoor());
+				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);
+			}
 
-//          if(status != null) {
-//          g.setColor(Color.WHITE);
-//          g.drawString("gpsd: " + status, 5, mv.getBounds().height - 15); // lower left corner
-//          }
-        }
-    }
+			// 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);
 
-    /* (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()) {
-                setCurrentPosition(data.getLatitude(), data.getLongitude());
-                if(!Float.isNaN(data.getSpeed())) {
-                    setSpeed(data.getSpeed());
-                }
-                if(!Float.isNaN(data.getCourse())) {
-                    setCourse(data.getCourse());
-                }
-                Main.map.repaint();
-            }
-        }
-    }
+			// 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 (!isVisible()) {
+			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());
+				}
+				if (!autocenter && allowRedraw()) {
+					Main.map.repaint();
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param suppressor the suppressor to set
+	 */
+	public void setSuppressor(ILiveGpsSuppressor suppressor) {
+		this.suppressor = suppressor;
+	}
+
+	/**
+	 * @return the suppressor
+	 */
+	public ILiveGpsSuppressor getSuppressor() {
+		return suppressor;
+	}
+
+	/**
+	 * Check, if a redraw is currently allowed.
+	 * 
+	 * @return true, if a redraw is permitted, false, if a re-draw 
+	 * should be suppressed.
+	 */
+	private boolean allowRedraw() {
+		if (this.suppressor != null) {
+			return this.suppressor.isAllowUpdate();
+		} else {
+			return true;
+		}
+	}
 }
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 19010)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 19011)
@@ -25,197 +25,239 @@
 import org.openstreetmap.josm.tools.Shortcut;
 
-public class LiveGpsPlugin extends Plugin implements LayerChangeListener
-{
-    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 = null;
-
-    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 void activeLayerChange(Layer oldLayer, Layer newLayer) {
-    }
-
-    public void layerAdded(Layer newLayer) {
-    }
-
-    public void layerRemoved(Layer oldLayer) {
-        if(oldLayer == lgpslayer)
-        {
-            enableTracking(false);
-            lgpscapture.setSelected(false);
-            removePropertyChangeListener(lgpslayer);
-            Layer.listeners.remove(this);
-            lgpslayer = null;
-        }
-    }
-
-    public LiveGpsPlugin()
-    {
-        MainMenu menu = Main.main.menu;
-        lgpsmenu = menu.addMenu(marktr("LiveGPS"), KeyEvent.VK_G, menu.defaultMenuPos, ht("/Plugin/LiveGPS"));
-
-        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();
-                if (lgpslayer == null) {
-                    lgpslayer = new LiveGpsLayer(data);
-                    Main.main.addLayer(lgpslayer);
-                    Layer.listeners.add(this);
-                    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);
-        }
-    }
-
-    /**
-     * Remove a listener for gps events.
-     * @param listener the listener.
-     */
-    public void removePropertyChangeListener(PropertyChangeListener listener) {
-        if(acquirer != null)
-            acquirer.removePropertyChangeListener(listener);
-        else if(listenerQueue != null && listenerQueue.contains(listener))
-            listenerQueue.remove(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;
-    }
+public class LiveGpsPlugin extends Plugin implements LayerChangeListener {
+	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 = null;
+
+	/**
+	 * The LiveGpsSuppressor is queried, if an event shall be suppressed.
+	 */
+	private LiveGpsSuppressor suppressor;
+
+	/**
+	 * separate thread, where the LiveGpsSuppressor executes.
+	 */
+	private Thread suppressorThread;
+
+	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 void activeLayerChange(Layer oldLayer, Layer newLayer) {
+	}
+
+	public void layerAdded(Layer newLayer) {
+	}
+
+	public void layerRemoved(Layer oldLayer) {
+		if (oldLayer == lgpslayer) {
+			enableTracking(false);
+			lgpscapture.setSelected(false);
+			removePropertyChangeListener(lgpslayer);
+			Layer.listeners.remove(this);
+			lgpslayer = null;
+		}
+	}
+
+	public LiveGpsPlugin() {
+		MainMenu menu = Main.main.menu;
+		lgpsmenu = menu.addMenu(marktr("LiveGPS"), KeyEvent.VK_G,
+				menu.defaultMenuPos, ht("/Plugin/LiveGPS"));
+
+		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;
+
+			// also stop the suppressor
+			if (suppressor != null) {
+				suppressor.shutdown();
+				suppressorThread = null;
+				if (lgpslayer != null) {
+					lgpslayer.setSuppressor(null);
+				}
+			}
+		} else if (enable) {
+			// also start the suppressor
+			if (suppressor == null) {
+				suppressor = new LiveGpsSuppressor();
+			}
+			if (suppressorThread == null) {
+				suppressorThread = new Thread(suppressor);
+				suppressorThread.start();
+			}
+
+			if (acquirer == null) {
+				acquirer = new LiveGpsAcquirer();
+				if (lgpslayer == null) {
+					lgpslayer = new LiveGpsLayer(data);
+					Main.main.addLayer(lgpslayer);
+					Layer.listeners.add(this);
+					lgpslayer.setAutoCenter(isAutoCenter());
+				}
+				// connect layer with acquirer:
+				addPropertyChangeListener(lgpslayer);
+
+				// connect layer with suppressor:
+				lgpslayer.setSuppressor(suppressor);
+				// 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);
+		}
+	}
+
+	/**
+	 * Remove a listener for gps events.
+	 * @param listener the listener.
+	 */
+	public void removePropertyChangeListener(PropertyChangeListener listener) {
+		if (acquirer != null)
+			acquirer.removePropertyChangeListener(listener);
+		else if (listenerQueue != null && listenerQueue.contains(listener))
+			listenerQueue.remove(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/LiveGpsSuppressor.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsSuppressor.java	(revision 19010)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsSuppressor.java	(revision 19011)
@@ -16,5 +16,5 @@
  *
  */
-public class LiveGpsSuppressor implements Runnable {
+public class LiveGpsSuppressor implements Runnable, ILiveGpsSuppressor {
 
 	/**
@@ -36,5 +36,5 @@
 	 * Controls if this thread is still in used.
 	 */
-	boolean shutdownFlag = false;
+	private boolean shutdownFlag = false;
 
 	/**
@@ -91,4 +91,5 @@
 	 *
 	 * @return true, if an update is currently allowed; false, if the update shall be suppressed.
+	 * @see livegps.ILiveGpsSuppressor#isAllowUpdate()
 	 */
 	public synchronized boolean isAllowUpdate() {
