Index: applications/editors/josm/plugins/public_transport/.project
===================================================================
--- applications/editors/josm/plugins/public_transport/.project	(revision 31994)
+++ applications/editors/josm/plugins/public_transport/.project	(revision 31995)
@@ -11,6 +11,12 @@
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>org.sonarlint.eclipse.core.sonarlintBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
+		<nature>org.sonarlint.eclipse.core.sonarlintNature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
 	</natures>
Index: applications/editors/josm/plugins/public_transport/src/public_transport/AbstractImporterDialog.java
===================================================================
--- applications/editors/josm/plugins/public_transport/src/public_transport/AbstractImporterDialog.java	(revision 31995)
+++ applications/editors/josm/plugins/public_transport/src/public_transport/AbstractImporterDialog.java	(revision 31995)
@@ -0,0 +1,168 @@
+package public_transport;
+
+import static org.openstreetmap.josm.tools.I18n.marktr;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Frame;
+
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.JosmAction;
+
+/**
+ * Abstract superclass of {@link GTFSImporterDialog} and {@link StopImporterDialog}.
+ */
+public abstract class AbstractImporterDialog<T extends JosmAction> {
+
+    private static final String[] stoptypes = new String[]{marktr("bus"), marktr("tram"), marktr("light_rail"), marktr("subway"), marktr("rail")};
+
+    private final JDialog jDialog;
+    protected final JTabbedPane tabbedPane;
+    protected final JComboBox<TransText> cbStoptype;
+
+    protected final JTextField tfGPSTimeStart;
+    protected final JTextField tfStopwatchStart;
+    protected final JTextField tfTimeWindow;
+    protected final JTextField tfThreshold;
+
+    public AbstractImporterDialog(T controller, String dialogTitle, String actionPrefix) {
+        Frame frame = JOptionPane.getFrameForComponent(Main.parent);
+        jDialog = new JDialog(frame, dialogTitle, false);
+        tabbedPane = new JTabbedPane();
+        jDialog.add(tabbedPane);
+        
+        cbStoptype = new JComboBox<>();
+        cbStoptype.setEditable(false);
+        for(String type : stoptypes)
+            cbStoptype.addItem(new TransText(type));
+        cbStoptype.setActionCommand(actionPrefix + ".settingsStoptype");
+        cbStoptype.addActionListener(controller);
+        
+        tfGPSTimeStart = new JTextField("00:00:00", 15);
+        tfGPSTimeStart.setActionCommand(actionPrefix + ".settingsGPSTimeStart");
+        tfGPSTimeStart.addActionListener(controller);
+
+        tfStopwatchStart = new JTextField("00:00:00", 15);
+        tfStopwatchStart.setActionCommand(actionPrefix + ".settingsStopwatchStart");
+        tfStopwatchStart.addActionListener(controller);
+
+        tfTimeWindow = new JTextField("15", 4);
+        tfTimeWindow.setActionCommand(actionPrefix + ".settingsTimeWindow");
+        tfTimeWindow.addActionListener(controller);
+
+        tfThreshold = new JTextField("20", 4);
+        tfThreshold.setActionCommand(actionPrefix + ".settingsThreshold");
+        tfThreshold.addActionListener(controller);
+
+        initDialog(controller);
+        
+        jDialog.pack();
+        jDialog.setLocationRelativeTo(frame);
+    }
+    
+    protected abstract void initDialog(T controller);
+    
+    public void setTrackValid(boolean valid)
+    {
+      tabbedPane.setEnabledAt(2, valid);
+    }
+
+    public void setVisible(boolean visible)
+    {
+      jDialog.setVisible(visible);
+    }
+
+    public void setSettings
+        (String gpsSyncTime, String stopwatchStart,
+         double timeWindow, double threshold)
+    {
+      tfGPSTimeStart.setText(gpsSyncTime);
+      tfStopwatchStart.setText(stopwatchStart);
+      tfTimeWindow.setText(Double.toString(timeWindow));
+      tfThreshold.setText(Double.toString(threshold));
+    }
+
+    public String getStoptype()
+    {
+      return ((TransText)cbStoptype.getSelectedItem()).text;
+    }
+
+    public boolean gpsTimeStartValid()
+    {
+      if (parseTime(tfGPSTimeStart.getText()) >= 0)
+      {
+        return true;
+      }
+      else
+      {
+        JOptionPane.showMessageDialog
+        (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
+         JOptionPane.ERROR_MESSAGE);
+        return false;
+      }
+    }
+    
+    public String getGpsTimeStart()
+    {
+      return tfGPSTimeStart.getText();
+    }
+
+    public void setGpsTimeStart(String s)
+    {
+      tfGPSTimeStart.setText(s);
+    }
+
+    public boolean stopwatchStartValid()
+    {
+      if (parseTime(tfStopwatchStart.getText()) >= 0)
+      {
+        return true;
+      }
+      else
+      {
+        JOptionPane.showMessageDialog
+        (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
+         JOptionPane.ERROR_MESSAGE);
+        return false;
+      }
+    }
+
+    public String getStopwatchStart()
+    {
+      return tfStopwatchStart.getText();
+    }
+
+    public void setStopwatchStart(String s)
+    {
+      tfStopwatchStart.setText(s);
+    }
+
+    public double getTimeWindow()
+    {
+      return Double.parseDouble(tfTimeWindow.getText());
+    }
+    
+    public double getThreshold()
+    {
+      return Double.parseDouble(tfThreshold.getText());
+    }
+
+    public static double parseTime(String s)
+    {
+      if ((s.charAt(2) != ':') || (s.charAt(2) != ':')
+       || (s.length() < 8))
+        return -1;
+      int hour = Integer.parseInt(s.substring(0, 2));
+      int minute = Integer.parseInt(s.substring(3, 5));
+      double second = Double.parseDouble(s.substring(6, s.length()));
+      if ((hour < 0) || (hour > 23) || (minute < 0) || (minute > 59)
+       || (second < 0) || (second >= 60.0))
+        return -1;
+      return (second + minute*60 + hour*60*60);
+    }
+}
Index: applications/editors/josm/plugins/public_transport/src/public_transport/GTFSImporterDialog.java
===================================================================
--- applications/editors/josm/plugins/public_transport/src/public_transport/GTFSImporterDialog.java	(revision 31994)
+++ applications/editors/josm/plugins/public_transport/src/public_transport/GTFSImporterDialog.java	(revision 31995)
@@ -1,46 +1,28 @@
 package public_transport;
 
-import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Frame;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 
 import javax.swing.JButton;
-import javax.swing.JComboBox;
 import javax.swing.JComponent;
-import javax.swing.JDialog;
 import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
-import javax.swing.JTabbedPane;
 import javax.swing.JTable;
-import javax.swing.JTextField;
 import javax.swing.KeyStroke;
 
-import org.openstreetmap.josm.Main;
-
-public class GTFSImporterDialog
+public class GTFSImporterDialog extends AbstractImporterDialog<GTFSImporterAction>
 {
-  private JDialog jDialog = null;
-  private JTabbedPane tabbedPane = null;
-  private JComboBox<TransText> cbStoptype = null;
-  private JList tracksList = null;
-  private JTextField tfGPSTimeStart = null;
-  private JTextField tfStopwatchStart = null;
-  private JTextField tfTimeWindow = null;
-  private JTextField tfThreshold = null;
-  private JTable stoplistTable = null;
   private JTable gtfsStopTable = null;
-  private final String[] stoptypes = new String[]{marktr("bus"), marktr("tram"), marktr("light_rail"), marktr("subway"), marktr("rail")};
 
   public GTFSImporterDialog(GTFSImporterAction controller)
   {
-    Frame frame = JOptionPane.getFrameForComponent(Main.parent);
-    jDialog = new JDialog(frame, tr("Create Stops from GTFS"), false);
-    tabbedPane = new JTabbedPane();
+      super(controller, tr("Create Stops from GTFS"), "gtfsImporter");
+  }
+  
+  @Override
+  protected void initDialog(GTFSImporterAction controller) {
     JPanel tabSettings = new JPanel();
     tabbedPane.addTab(tr("Settings"), tabSettings);
@@ -49,5 +31,4 @@
     tabbedPane.setEnabledAt(0, false);
     tabbedPane.setEnabledAt(1, true);
-    jDialog.add(tabbedPane);
 
     //Settings Tab
@@ -68,11 +49,4 @@
     contentPane.add(label);
 
-    cbStoptype = new JComboBox<>();
-    cbStoptype.setEditable(false);
-    for(String type : stoptypes)
-        cbStoptype.addItem(new TransText(type));
-    cbStoptype.setActionCommand("gtfsImporter.settingsStoptype");
-    cbStoptype.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 1;
@@ -95,8 +69,4 @@
     contentPane.add(label);
 
-    tfGPSTimeStart = new JTextField("00:00:00", 15);
-    tfGPSTimeStart.setActionCommand("gtfsImporter.settingsGPSTimeStart");
-    tfGPSTimeStart.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 3;
@@ -131,8 +101,4 @@
     contentPane.add(label);
 
-    tfStopwatchStart = new JTextField("00:00:00", 15);
-    tfStopwatchStart.setActionCommand("gtfsImporter.settingsStopwatchStart");
-    tfStopwatchStart.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 5;
@@ -167,8 +133,4 @@
     contentPane.add(label);
 
-    tfTimeWindow = new JTextField("15", 4);
-    tfTimeWindow.setActionCommand("gtfsImporter.settingsTimeWindow");
-    tfTimeWindow.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 7;
@@ -201,8 +163,4 @@
     gridbag.setConstraints(label, layoutCons);
     contentPane.add(label);
-
-    tfThreshold = new JTextField("20", 4);
-    tfThreshold.setActionCommand("gtfsImporter.settingsThreshold");
-    tfThreshold.addActionListener(controller);
 
     layoutCons.gridx = 0;
@@ -375,92 +333,4 @@
     gridbag.setConstraints(bDelete, layoutCons);
     contentPane.add(bDelete);
-
-    jDialog.pack();
-    jDialog.setLocationRelativeTo(frame);
-  }
-
-  public void setTrackValid(boolean valid)
-  {
-    tabbedPane.setEnabledAt(2, valid);
-  }
-
-  public void setVisible(boolean visible)
-  {
-    jDialog.setVisible(visible);
-  }
-
-  public void setSettings
-      (String gpsSyncTime, String stopwatchStart,
-       double timeWindow, double threshold)
-  {
-    tfGPSTimeStart.setText(gpsSyncTime);
-    tfStopwatchStart.setText(stopwatchStart);
-    tfTimeWindow.setText(Double.toString(timeWindow));
-    tfThreshold.setText(Double.toString(threshold));
-  }
-
-  public String getStoptype()
-  {
-    return ((TransText)cbStoptype.getSelectedItem()).text;
-  }
-
-  public boolean gpsTimeStartValid()
-  {
-    if (parseTime(tfGPSTimeStart.getText()) >= 0)
-    {
-      return true;
-    }
-    else
-    {
-      JOptionPane.showMessageDialog
-      (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
-       JOptionPane.ERROR_MESSAGE);
-      return false;
-    }
-  }
-
-  public String getGpsTimeStart()
-  {
-    return tfGPSTimeStart.getText();
-  }
-
-  public void setGpsTimeStart(String s)
-  {
-    tfGPSTimeStart.setText(s);
-  }
-
-  public boolean stopwatchStartValid()
-  {
-    if (parseTime(tfStopwatchStart.getText()) >= 0)
-    {
-      return true;
-    }
-    else
-    {
-      JOptionPane.showMessageDialog
-      (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
-       JOptionPane.ERROR_MESSAGE);
-      return false;
-    }
-  }
-
-  public String getStopwatchStart()
-  {
-    return tfStopwatchStart.getText();
-  }
-
-  public void setStopwatchStart(String s)
-  {
-    tfStopwatchStart.setText(s);
-  }
-
-  public double getTimeWindow()
-  {
-    return Double.parseDouble(tfTimeWindow.getText());
-  }
-
-  public double getThreshold()
-  {
-    return Double.parseDouble(tfThreshold.getText());
   }
 
@@ -477,18 +347,4 @@
     gtfsStopTable.getColumnModel().getColumn(1).setPreferredWidth((int)(width * 0.6));
     gtfsStopTable.getColumnModel().getColumn(2).setPreferredWidth((int)(width * 0.1));
-  }
-
-  public static double parseTime(String s)
-  {
-    if ((s.charAt(2) != ':') || (s.charAt(2) != ':')
-     || (s.length() < 8))
-      return -1;
-    int hour = Integer.parseInt(s.substring(0, 2));
-    int minute = Integer.parseInt(s.substring(3, 5));
-    double second = Double.parseDouble(s.substring(6, s.length()));
-    if ((hour < 0) || (hour > 23) || (minute < 0) || (minute > 59)
-     || (second < 0) || (second >= 60.0))
-      return -1;
-    return (second + minute*60 + hour*60*60);
   }
 
Index: applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterDialog.java
===================================================================
--- applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterDialog.java	(revision 31994)
+++ applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterDialog.java	(revision 31995)
@@ -4,5 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.Frame;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
@@ -13,13 +12,9 @@
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
-import javax.swing.JDialog;
 import javax.swing.JLabel;
 import javax.swing.JList;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
-import javax.swing.JTabbedPane;
 import javax.swing.JTable;
-import javax.swing.JTextField;
 import javax.swing.KeyStroke;
 import javax.swing.ListSelectionModel;
@@ -27,26 +22,17 @@
 import javax.swing.event.ListSelectionListener;
 
-import org.openstreetmap.josm.Main;
-
-public class StopImporterDialog
+public class StopImporterDialog extends AbstractImporterDialog<StopImporterAction>
 {
-  private JDialog jDialog = null;
-  private JTabbedPane tabbedPane = null;
-  private JComboBox<TransText> cbStoptype = null;
   private JList<TrackReference> tracksList = null;
-  private JTextField tfGPSTimeStart = null;
-  private JTextField tfStopwatchStart = null;
-  private JTextField tfTimeWindow = null;
-  private JTextField tfThreshold = null;
   private JTable stoplistTable = null;
   private JTable waypointTable = null;
 
-  private final String[] stoptypes = new String[]{marktr("bus"), marktr("tram"), marktr("light_rail"), marktr("subway"), marktr("rail")};
-
   public StopImporterDialog(StopImporterAction controller)
   {
-    Frame frame = JOptionPane.getFrameForComponent(Main.parent);
-    jDialog = new JDialog(frame, tr("Create Stops from GPX"), false);
-    tabbedPane = new JTabbedPane();
+      super(controller, tr("Create Stops from GPX"), "stopImporter");
+  }
+  
+  @Override
+  protected void initDialog(StopImporterAction controller) {
     JPanel tabTracks = new JPanel();
     tabbedPane.addTab(tr("Tracks"), tabTracks);
@@ -61,5 +47,4 @@
     tabbedPane.setEnabledAt(2, false);
     tabbedPane.setEnabledAt(3, true);
-    jDialog.add(tabbedPane);
 
     //Tracks Tab
@@ -114,11 +99,4 @@
     contentPane.add(label);
 
-    cbStoptype = new JComboBox<>();
-    cbStoptype.setEditable(false);
-    for(String type : stoptypes)
-        cbStoptype.addItem(new TransText(type));
-    cbStoptype.setActionCommand("stopImporter.settingsStoptype");
-    cbStoptype.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 1;
@@ -141,8 +119,4 @@
     contentPane.add(label);
 
-    tfGPSTimeStart = new JTextField("00:00:00", 15);
-    tfGPSTimeStart.setActionCommand("stopImporter.settingsGPSTimeStart");
-    tfGPSTimeStart.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 3;
@@ -176,8 +150,4 @@
     contentPane.add(label);
 
-    tfStopwatchStart = new JTextField("00:00:00", 15);
-    tfStopwatchStart.setActionCommand("stopImporter.settingsStopwatchStart");
-    tfStopwatchStart.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 5;
@@ -211,8 +181,4 @@
     contentPane.add(label);
 
-    tfTimeWindow = new JTextField("15", 4);
-    tfTimeWindow.setActionCommand("stopImporter.settingsTimeWindow");
-    tfTimeWindow.addActionListener(controller);
-
     layoutCons.gridx = 0;
     layoutCons.gridy = 7;
@@ -245,8 +211,4 @@
     gridbag.setConstraints(label, layoutCons);
     contentPane.add(label);
-
-    tfThreshold = new JTextField("20", 4);
-    tfThreshold.setActionCommand("stopImporter.settingsThreshold");
-    tfThreshold.addActionListener(controller);
 
     layoutCons.gridx = 0;
@@ -542,92 +504,4 @@
     gridbag.setConstraints(bDelete, layoutCons);
     contentPane.add(bDelete);
-
-    jDialog.pack();
-    jDialog.setLocationRelativeTo(frame);
-  }
-
-  public void setTrackValid(boolean valid)
-  {
-    tabbedPane.setEnabledAt(2, valid);
-  }
-
-  public void setVisible(boolean visible)
-  {
-    jDialog.setVisible(visible);
-  }
-
-  public void setSettings
-      (String gpsSyncTime, String stopwatchStart,
-       double timeWindow, double threshold)
-  {
-    tfGPSTimeStart.setText(gpsSyncTime);
-    tfStopwatchStart.setText(stopwatchStart);
-    tfTimeWindow.setText(Double.toString(timeWindow));
-    tfThreshold.setText(Double.toString(threshold));
-  }
-
-  public String getStoptype()
-  {
-    return ((TransText)cbStoptype.getSelectedItem()).text;
-  }
-
-  public boolean gpsTimeStartValid()
-  {
-    if (parseTime(tfGPSTimeStart.getText()) >= 0)
-    {
-      return true;
-    }
-    else
-    {
-      JOptionPane.showMessageDialog
-      (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
-       JOptionPane.ERROR_MESSAGE);
-      return false;
-    }
-  }
-
-  public String getGpsTimeStart()
-  {
-    return tfGPSTimeStart.getText();
-  }
-
-  public void setGpsTimeStart(String s)
-  {
-    tfGPSTimeStart.setText(s);
-  }
-
-  public boolean stopwatchStartValid()
-  {
-    if (parseTime(tfStopwatchStart.getText()) >= 0)
-    {
-      return true;
-    }
-    else
-    {
-      JOptionPane.showMessageDialog
-      (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
-       JOptionPane.ERROR_MESSAGE);
-      return false;
-    }
-  }
-
-  public String getStopwatchStart()
-  {
-    return tfStopwatchStart.getText();
-  }
-
-  public void setStopwatchStart(String s)
-  {
-    tfStopwatchStart.setText(s);
-  }
-
-  public double getTimeWindow()
-  {
-    return Double.parseDouble(tfTimeWindow.getText());
-  }
-
-  public double getThreshold()
-  {
-    return Double.parseDouble(tfThreshold.getText());
   }
 
@@ -674,18 +548,4 @@
   }
 
-  public static double parseTime(String s)
-  {
-    if ((s.charAt(2) != ':') || (s.charAt(2) != ':')
-     || (s.length() < 8))
-      return -1;
-    int hour = Integer.parseInt(s.substring(0, 2));
-    int minute = Integer.parseInt(s.substring(3, 5));
-    double second = Double.parseDouble(s.substring(6, s.length()));
-    if ((hour < 0) || (hour > 23) || (minute < 0) || (minute > 59)
-     || (second < 0) || (second >= 60.0))
-      return -1;
-    return (second + minute*60 + hour*60*60);
-  }
-
   private class TracksLSL implements ListSelectionListener
   {
@@ -697,4 +557,5 @@
     }
 
+    @Override
     public void valueChanged(ListSelectionEvent e)
     {
