Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPlugin.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPlugin.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPlugin.java	(revision 33525)
@@ -2,5 +2,5 @@
 package org.openstreetmap.josm.plugins.osmrec;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.plugins.Plugin;
@@ -13,41 +13,41 @@
 public class OSMRecPlugin extends Plugin {
 
-    private final MenuExportAction menuExportAction;
-    private static MapFrame mapFrame;
-    public OSMRecPlugin plugin;
+	private final MenuExportAction menuExportAction;
+	private static MapFrame mapFrame;
+	public OSMRecPlugin plugin;
 
-    public OSMRecPlugin(PluginInformation info) { // NO_UCD (unused code)
-        super(info);
-        menuExportAction = new MenuExportAction();
-        Main.main.menu.toolsMenu.add(menuExportAction);
-    }
+	public OSMRecPlugin(PluginInformation info) { // NO_UCD (unused code)
+		super(info);
+		menuExportAction = new MenuExportAction();
+		MainApplication.getMenu().toolsMenu.add(menuExportAction);
+	}
 
-    @Override
-    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
-        if (oldFrame == null && newFrame != null) { // map frame added
-            setCurrentMapFrame(newFrame);
-            setState(this);
-        }
-    }
+	@Override
+	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+		if (oldFrame == null && newFrame != null) { // map frame added
+			setCurrentMapFrame(newFrame);
+			setState(this);
+		}
+	}
 
-    private void setCurrentMapFrame(MapFrame newFrame) {
-        OSMRecPlugin.mapFrame = newFrame;
-    }
+	private void setCurrentMapFrame(MapFrame newFrame) {
+		OSMRecPlugin.mapFrame = newFrame;
+	}
 
-    public static MapFrame getCurrentMapFrame() {
-        return mapFrame;
-    }
+	public static MapFrame getCurrentMapFrame() {
+		return mapFrame;
+	}
 
-    private void setState(OSMRecPlugin plugin) {
-        this.plugin = plugin;
-    }
+	private void setState(OSMRecPlugin plugin) {
+		this.plugin = plugin;
+	}
 
-    public OSMRecPlugin getState() {
-        return plugin;
-    }
+	public OSMRecPlugin getState() {
+		return plugin;
+	}
 
-    //    @Override
-    //    public PreferenceSetting getPreferenceSetting() {
-    //        return new PreferenceEditor();
-    //    }
+	//    @Override
+	//    public PreferenceSetting getPreferenceSetting() {
+	//        return new PreferenceEditor();
+	//    }
 }
Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java	(revision 33525)
@@ -100,4 +100,5 @@
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
 import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
@@ -122,4 +123,5 @@
 import org.openstreetmap.josm.plugins.osmrec.personalization.UserDataExtractAndTrainWorker;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -144,2279 +146,2279 @@
 class OSMRecPluginHelper {
 
-    private final DefaultTableModel tagData;
-    private static Collection<String> fileHistory;
-    private Map<File, Double> filesAndWeights = new HashMap<>();
-    private boolean useCombinedModel;
-
-    //the most recent file from history.
-    //all necessary files will reside in a directory of this file
-    private static String MAIN_PATH;
-    private static String MODEL_PATH;
-    private static String TEXTUAL_LIST_PATH;
-    private static Map<String, List<String>> indirectClasses;
-    private static Map<String, Integer> indirectClassesWithIDs;
-    private static LanguageDetector languageDetector;
-    private static String bestModelPath;
-    private boolean modelWithClasses;
-    private final String modelWithClassesPath;
-    private boolean useCustomSVMModel = false;
-    private String customSVMModelPath;
-    private final String combinedModelClasses;
-    private final String combinedModel;
-
-    // Selection that we are editing by using both dialogs
-    Collection<OsmPrimitive> sel;
-
-    private String changedKey;
-
-    Comparator<AutoCompletionListItem> defaultACItemComparator = new Comparator<AutoCompletionListItem>() {
-        @Override
-        public int compare(AutoCompletionListItem o1, AutoCompletionListItem o2) {
-            return String.CASE_INSENSITIVE_ORDER.compare(o1.getValue(), o2.getValue());
-        }
-    };
-
-    private String lastAddKey = null;
-    private String lastAddValue = null;
-
-    public static final int DEFAULT_LRU_TAGS_NUMBER = 5;
-    public static final int MAX_LRU_TAGS_NUMBER = 30;
-
-    // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
-    private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) {
-        @Override
-        protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) {
-            return size() > MAX_LRU_TAGS_NUMBER;
-        }
-    };
-
-    OSMRecPluginHelper(DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
-        this.tagData = propertyData;
-        fileHistory = Main.pref.getCollection("file-open.history");
-        if (!fileHistory.isEmpty()) {
-            MAIN_PATH = (String) fileHistory.toArray()[0];
-        } else {
-            MAIN_PATH = System.getProperty("user.home");
-        }
-        MODEL_PATH = new File(MAIN_PATH).getParentFile() + "/OSMRec_models";
-        TEXTUAL_LIST_PATH = MODEL_PATH + "/textualList.txt";
-        combinedModelClasses = MODEL_PATH + "/combinedModel.1";
-        combinedModel = MODEL_PATH + "/combinedModel.0";
-        bestModelPath = MODEL_PATH + "/best_model";
-        customSVMModelPath = bestModelPath;
-        modelWithClassesPath = MODEL_PATH + "/model_with_classes";
-        languageDetector = LanguageDetector.getInstance(MODEL_PATH + "/profiles");
-
-        SampleModelsExtractor sampleModelsExtractor = new SampleModelsExtractor();
-
-        sampleModelsExtractor.extractSampleSVMmodel("best_model", bestModelPath);
-        sampleModelsExtractor.extractSampleSVMmodel("model_with_classes", modelWithClassesPath);
-    }
-
-    /**
-     * Open the add selection dialog and add a new key/value to the table (and to the dataset, of course).
-     */
-    public void addTag() {
-        changedKey = null;
-        sel = Main.main.getInProgressSelection();
-        if (sel == null || sel.isEmpty()) return;
-
-        final AddTagsDialog addDialog = new AddTagsDialog();
-
-        addDialog.showDialog();
-
-        addDialog.destroyActions();
-        if (addDialog.getValue() == 1)
-            addDialog.performTagAdding();
-        else
-            addDialog.undoAllTagsAdding();
-    }
-
-    /**
-     * Edit the value in the tags table row.
-     * @param row The row of the table from which the value is edited.
-     * @param focusOnKey Determines if the initial focus should be set on key instead of value
-     * @since 5653
-     */
-    public void editTag(final int row, boolean focusOnKey) {
-        changedKey = null;
-        sel = Main.main.getInProgressSelection();
-        String key = "";
-
-        @SuppressWarnings("unchecked")
-        Map<String, Integer> dumPar = new HashMap<>();
-        dumPar.put(" ", -1);
-        final TrainingDialog editDialog = new TrainingDialog(key, row,
-                dumPar, focusOnKey);
-        editDialog.showDialog();
-    }
-
-    /**
-     * If during last editProperty call user changed the key name, this key will be returned
-     * Elsewhere, returns null.
-     * @return The modified key, or {@code null}
-     */
-    public String getChangedKey() {
-        return changedKey;
-    }
-
-    /**
-     * For a given key k, return a list of keys which are used as keys for
-     * auto-completing values to increase the search space.
-     * @param key the key k
-     * @return a list of keys
-     */
-    private static List<String> getAutocompletionKeys(String key) {
-        if ("name".equals(key) || "addr:street".equals(key))
-            return Arrays.asList("addr:street", "name");
-        else
-            return Arrays.asList(key);
-    }
-
-    /**
-     * Load recently used tags from preferences if needed.
-     */
-    public void loadTagsIfNeeded() {
-        if (PROPERTY_REMEMBER_TAGS.get() && recentTags.isEmpty()) {
-            recentTags.clear();
-            Collection<String> c = Main.pref.getCollection("properties.recent-tags");
-            Iterator<String> it = c.iterator();
-            String key, value;
-            while (it.hasNext()) {
-                key = it.next();
-                value = it.next();
-                recentTags.put(new Tag(key, value), null);
-            }
-        }
-    }
-
-    /**
-     * Store recently used tags in preferences if needed.
-     */
-    public void saveTagsIfNeeded() {
-        if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) {
-            List<String> c = new ArrayList<>(recentTags.size()*2);
-            for (Tag t: recentTags.keySet()) {
-                c.add(t.getKey());
-                c.add(t.getValue());
-            }
-            Main.pref.putCollection("properties.recent-tags", c);
-        }
-    }
-
-    /**
-     * Warns user about a key being overwritten.
-     * @param action The action done by the user. Must state what key is changed
-     * @param togglePref  The preference to save the checkbox state to
-     * @return {@code true} if the user accepts to overwrite key, {@code false} otherwise
-     */
-    private boolean warnOverwriteKey(String action, String togglePref) {
-        ExtendedDialog ed = new ExtendedDialog(
-                Main.parent,
-                tr("Overwrite key"),
-                new String[]{tr("Replace"), tr("Cancel")});
-        ed.setButtonIcons(new String[]{"purge", "cancel"});
-        ed.setContent(action+"\n"+ tr("The new key is already used, overwrite values?"));
-        ed.setCancelButton(2);
-        ed.toggleEnable(togglePref);
-        ed.showDialog();
-
-        return ed.getValue() == 1;
-    }
-
-    public final class TrainingDialog extends AbstractTagsDialog {
-
-        private static final int FIELD_COLUMNS = 4;
-        private final JTextField inputFileField;
-        private final JLabel inputFileLabel;
-        private final JTextField topKField;
-        private final JTextField cParameterField;
-        private final JTextField frequencyField;
-
-        private final JButton fileBrowseButton;
-        private final JButton acceptConfigButton;
-        private JRadioButton frequencyButton;
-        private JRadioButton topKButton;
-        private JCheckBox cParameterCheckBox;
-        private final JButton resetConfigButton;
-        private String inputFileValue;
-        private Double cParameterValue = 0.0;
-        private Integer topKvalue = 0;
-        private Integer frequencyValue = 0;
-        private boolean crossValidateFlag;
-        private final JButton startTrainingButton;
-        private final JLabel cErrorMessageLabel;
-        private final JLabel topKErrorMessageLabel;
-        private final JLabel inputFileErrorMessageLabel;
-        private final JLabel frequencyErrorMessageLabel;
-        private final JProgressBar trainingProgressBar;
-        private final JRadioButton byAreaRadioButton;
-        private final JRadioButton byTimeRadioButton;
-        private final JLabel userNameLabel;
-        private final JTextField userNameField;
-        private final JTextField daysField;
-        private final JLabel daysLabel;
-        private final JCheckBox trainFromUserCheckBox;
-        private final JPanel userHistoryPanel;
-        private Integer daysValue;
-        private String usernameValue;
-        private TrainWorker trainWorker;
-        private UserDataExtractAndTrainWorker userDataExtractAndTrainWorker;
-
-        private TrainingDialog(String key, int row, Map<String, Integer> map, final boolean initialFocusOnKey) {
-            super(Main.parent, tr("Training process configuration"), new String[] {tr("Cancel")});
-
-            setButtonIcons(new String[] {"ok", "cancel"});
-            setCancelButton(2);
-
-            JPanel mainPanel = new JPanel(new BorderLayout(10, 10));   //6,6
-            JPanel configPanel = new JPanel(new BorderLayout(10, 10));  //6,6    //at NORTH of mainPanel
-            JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //NORTH at config panel
-            JPanel paramPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //WEST at config panel //config panel has EAST free
-
-            JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //SOUTH at config panel
-            userHistoryPanel = new JPanel(); //CENTER of config
-
-            trainingProgressBar = new JProgressBar(0, 100);
-
-            ButtonGroup paramGroup = new ButtonGroup();
-            ButtonGroup userGroup = new ButtonGroup();
-            inputFileLabel = new JLabel();
-            inputFileField = new JTextField();
-            cParameterField = new JTextField();
-            topKField = new JTextField();
-            frequencyField = new JTextField();
-
-            cParameterCheckBox = new JCheckBox("Define C parameter");
-            topKButton = new JRadioButton("Top-K terms");
-            frequencyButton = new JRadioButton("Max-Frequency");
-            fileBrowseButton = new JButton();
-            acceptConfigButton = new JButton("Accept Configuration");
-            resetConfigButton = new JButton("Reset Configuration/Cancel training");
-            startTrainingButton = new JButton("Train Model");
-
-            inputFileErrorMessageLabel = new JLabel("");
-            cErrorMessageLabel = new JLabel("");
-            topKErrorMessageLabel = new JLabel("");
-            frequencyErrorMessageLabel = new JLabel("");
-
-            trainFromUserCheckBox = new JCheckBox("Train Model From User");
-            byAreaRadioButton = new JRadioButton("By Area");
-            byTimeRadioButton = new JRadioButton("By Time");
-            userNameLabel = new JLabel("Username:");
-            userNameField = new JTextField();
-
-            daysLabel = new JLabel("Days: ");
-            daysField = new JTextField();
-
-            cParameterCheckBox.setSelected(true);
-            userHistoryPanel.setEnabled(false);
-            byAreaRadioButton.setEnabled(false);
-            byAreaRadioButton.setSelected(true);
-            byTimeRadioButton.setEnabled(false);
-            userNameLabel.setEnabled(false);
-            userNameField.setEnabled(false);
-            daysLabel.setEnabled(false);
-            daysField.setEnabled(false);
-            userNameField.setColumns(FIELD_COLUMNS);
-            daysField.setColumns(FIELD_COLUMNS);
-
-            Collection<String> fileHistory = Main.pref.getCollection("file-open.history");
-            if (!fileHistory.isEmpty()) {
-                inputFileField.setText(MAIN_PATH);
-            }
-
-            fileBrowseButton.setText("...");
-            inputFileLabel.setText("OSM filepath: ");
-            inputFileErrorMessageLabel.setForeground(Color.RED);
-            inputFileErrorMessageLabel.setText("");
-            topKField.setText("50");
-            frequencyField.setText("200");
-            cParameterField.setText("0.01");
-
-            cParameterField.setColumns(FIELD_COLUMNS);
-            cParameterField.setEditable(false);
-            cParameterField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
-            cErrorMessageLabel.setForeground(Color.RED);
-            cErrorMessageLabel.setMinimumSize(new Dimension(150, 10));
-
-            topKButton.setSelected(true);
-            topKField.setColumns(FIELD_COLUMNS);
-            topKField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
-            topKErrorMessageLabel.setForeground(Color.RED);
-
-            frequencyField.setEditable(false);
-            frequencyField.setColumns(FIELD_COLUMNS);
-            frequencyField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
-            frequencyErrorMessageLabel.setForeground(Color.RED);
-
-            fileBrowseButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    inputFileChooserButtonActionPerformed(evt);
-                }
-            });
-            topKButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (topKButton.isSelected()) {
-                        frequencyField.setEditable(false);
-                        topKField.setEditable(true);
-                    } else {
-                        frequencyField.setEditable(true);
-                        topKField.setEditable(false);
-                    }
-                }
-            });
-            frequencyButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (frequencyButton.isSelected()) {
-                        topKField.setEditable(false);
-                        frequencyField.setEditable(true);
-                    } else {
-                        topKField.setEditable(true);
-                        frequencyField.setEditable(false);
-                    }
-                }
-            });
-            cParameterCheckBox.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (cParameterCheckBox.isSelected()) {
-                        cParameterField.setEditable(true);
-                    } else {
-                        cParameterField.setEditable(false);
-                    }
-                }
-            });
-            acceptConfigButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    acceptConfigButtonActionPerformed(evt);
-                }
-            });
-            resetConfigButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    resetConfigButtonActionPerformed();
-                }
-            });
-
-            startTrainingButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (!acceptConfigButton.isEnabled()) {
-                        startTraining();
-                    } else {
-                        System.out.println("Set values first!");
-                    }
-                }
-            });
-
-            trainFromUserCheckBox.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (trainFromUserCheckBox.isSelected()) {
-                        userHistoryPanel.setEnabled(true);
-                        byAreaRadioButton.setEnabled(true);
-                        byTimeRadioButton.setEnabled(true);
-                        userNameLabel.setEnabled(true);
-                        userNameField.setEnabled(true);
-                        daysLabel.setEnabled(true);
-                        daysField.setEnabled(true);
-                    } else {
-                        userHistoryPanel.setEnabled(false);
-                        byAreaRadioButton.setEnabled(false);
-                        byTimeRadioButton.setEnabled(false);
-                        userNameLabel.setEnabled(false);
-                        userNameField.setEnabled(false);
-                        daysLabel.setEnabled(false);
-                        daysField.setEnabled(false);
-                    }
-                }
-            });
-
-            byAreaRadioButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (byAreaRadioButton.isSelected()) {
-                        daysField.setEditable(false);
-                    } else {
-                        daysField.setEditable(true);
-                    }
-                }
-            });
-
-            byTimeRadioButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (byTimeRadioButton.isSelected()) {
-                        daysField.setEditable(true);
-                    } else {
-                        daysField.setEditable(false);
-                    }
-                }
-            });
-
-            //grouplayout for input panel
-            buildInputPanelGroupLayout(inputPanel);
-
-            //grouplayout for param panel
-            buildParamPanelGroupLayout(paramPanel);
-
-            inputPanel.add(inputFileLabel);
-            inputPanel.add(inputFileField);
-            inputPanel.add(fileBrowseButton);
-            inputPanel.add(inputFileErrorMessageLabel);
-
-            paramGroup.add(topKButton);
-            paramGroup.add(frequencyButton);
-
-            paramPanel.add(cParameterCheckBox);
-            paramPanel.add(cParameterField);
-            paramPanel.add(cErrorMessageLabel);
-            paramPanel.add(topKButton);
-            paramPanel.add(topKField);
-            paramPanel.add(topKErrorMessageLabel);
-            paramPanel.add(frequencyButton);
-            paramPanel.add(frequencyField);
-            paramPanel.add(frequencyErrorMessageLabel);
-
-            southPanel.add(acceptConfigButton);
-            southPanel.add(resetConfigButton);
-            southPanel.add(trainFromUserCheckBox);
-
-            userGroup.add(byAreaRadioButton);
-            userGroup.add(byTimeRadioButton);
-            userHistoryPanel.add(byAreaRadioButton);
-            userHistoryPanel.add(byTimeRadioButton);
-            userHistoryPanel.add(daysLabel);
-            userHistoryPanel.add(daysField);
-            userHistoryPanel.add(userNameLabel);
-            userHistoryPanel.add(userNameField);
-
-            //grouplayout for user history panel
-            /*
+	private final DefaultTableModel tagData;
+	private static Collection<String> fileHistory;
+	private Map<File, Double> filesAndWeights = new HashMap<>();
+	private boolean useCombinedModel;
+
+	//the most recent file from history.
+	//all necessary files will reside in a directory of this file
+	private static String MAIN_PATH;
+	private static String MODEL_PATH;
+	private static String TEXTUAL_LIST_PATH;
+	private static Map<String, List<String>> indirectClasses;
+	private static Map<String, Integer> indirectClassesWithIDs;
+	private static LanguageDetector languageDetector;
+	private static String bestModelPath;
+	private boolean modelWithClasses;
+	private final String modelWithClassesPath;
+	private boolean useCustomSVMModel = false;
+	private String customSVMModelPath;
+	private final String combinedModelClasses;
+	private final String combinedModel;
+
+	// Selection that we are editing by using both dialogs
+	Collection<OsmPrimitive> sel;
+
+	private String changedKey;
+
+	Comparator<AutoCompletionListItem> defaultACItemComparator = new Comparator<AutoCompletionListItem>() {
+		@Override
+		public int compare(AutoCompletionListItem o1, AutoCompletionListItem o2) {
+			return String.CASE_INSENSITIVE_ORDER.compare(o1.getValue(), o2.getValue());
+		}
+	};
+
+	private String lastAddKey = null;
+	private String lastAddValue = null;
+
+	public static final int DEFAULT_LRU_TAGS_NUMBER = 5;
+	public static final int MAX_LRU_TAGS_NUMBER = 30;
+
+	// LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
+	private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) {
+		@Override
+		protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) {
+			return size() > MAX_LRU_TAGS_NUMBER;
+		}
+	};
+
+	OSMRecPluginHelper(DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
+		this.tagData = propertyData;
+		fileHistory = Main.pref.getCollection("file-open.history");
+		if (!fileHistory.isEmpty()) {
+			MAIN_PATH = (String) fileHistory.toArray()[0];
+		} else {
+			MAIN_PATH = System.getProperty("user.home");
+		}
+		MODEL_PATH = new File(MAIN_PATH).getParentFile() + "/OSMRec_models";
+		TEXTUAL_LIST_PATH = MODEL_PATH + "/textualList.txt";
+		combinedModelClasses = MODEL_PATH + "/combinedModel.1";
+		combinedModel = MODEL_PATH + "/combinedModel.0";
+		bestModelPath = MODEL_PATH + "/best_model";
+		customSVMModelPath = bestModelPath;
+		modelWithClassesPath = MODEL_PATH + "/model_with_classes";
+		languageDetector = LanguageDetector.getInstance(MODEL_PATH + "/profiles");
+
+		SampleModelsExtractor sampleModelsExtractor = new SampleModelsExtractor();
+
+		sampleModelsExtractor.extractSampleSVMmodel("best_model", bestModelPath);
+		sampleModelsExtractor.extractSampleSVMmodel("model_with_classes", modelWithClassesPath);
+	}
+
+	/**
+	 * Open the add selection dialog and add a new key/value to the table (and to the dataset, of course).
+	 */
+	public void addTag() {
+		changedKey = null;
+		sel = Main.main.getInProgressSelection();
+		if (sel == null || sel.isEmpty()) return;
+
+		final AddTagsDialog addDialog = new AddTagsDialog();
+
+		addDialog.showDialog();
+
+		addDialog.destroyActions();
+		if (addDialog.getValue() == 1)
+			addDialog.performTagAdding();
+		else
+			addDialog.undoAllTagsAdding();
+	}
+
+	/**
+	 * Edit the value in the tags table row.
+	 * @param row The row of the table from which the value is edited.
+	 * @param focusOnKey Determines if the initial focus should be set on key instead of value
+	 * @since 5653
+	 */
+	public void editTag(final int row, boolean focusOnKey) {
+		changedKey = null;
+		sel = Main.main.getInProgressSelection();
+		String key = "";
+
+		@SuppressWarnings("unchecked")
+		Map<String, Integer> dumPar = new HashMap<>();
+		dumPar.put(" ", -1);
+		final TrainingDialog editDialog = new TrainingDialog(key, row,
+				dumPar, focusOnKey);
+		editDialog.showDialog();
+	}
+
+	/**
+	 * If during last editProperty call user changed the key name, this key will be returned
+	 * Elsewhere, returns null.
+	 * @return The modified key, or {@code null}
+	 */
+	public String getChangedKey() {
+		return changedKey;
+	}
+
+	/**
+	 * For a given key k, return a list of keys which are used as keys for
+	 * auto-completing values to increase the search space.
+	 * @param key the key k
+	 * @return a list of keys
+	 */
+	private static List<String> getAutocompletionKeys(String key) {
+		if ("name".equals(key) || "addr:street".equals(key))
+			return Arrays.asList("addr:street", "name");
+		else
+			return Arrays.asList(key);
+	}
+
+	/**
+	 * Load recently used tags from preferences if needed.
+	 */
+	public void loadTagsIfNeeded() {
+		if (PROPERTY_REMEMBER_TAGS.get() && recentTags.isEmpty()) {
+			recentTags.clear();
+			Collection<String> c = Main.pref.getCollection("properties.recent-tags");
+			Iterator<String> it = c.iterator();
+			String key, value;
+			while (it.hasNext()) {
+				key = it.next();
+				value = it.next();
+				recentTags.put(new Tag(key, value), null);
+			}
+		}
+	}
+
+	/**
+	 * Store recently used tags in preferences if needed.
+	 */
+	public void saveTagsIfNeeded() {
+		if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) {
+			List<String> c = new ArrayList<>(recentTags.size()*2);
+			for (Tag t: recentTags.keySet()) {
+				c.add(t.getKey());
+				c.add(t.getValue());
+			}
+			Main.pref.putCollection("properties.recent-tags", c);
+		}
+	}
+
+	/**
+	 * Warns user about a key being overwritten.
+	 * @param action The action done by the user. Must state what key is changed
+	 * @param togglePref  The preference to save the checkbox state to
+	 * @return {@code true} if the user accepts to overwrite key, {@code false} otherwise
+	 */
+	private boolean warnOverwriteKey(String action, String togglePref) {
+		ExtendedDialog ed = new ExtendedDialog(
+				Main.parent,
+				tr("Overwrite key"),
+				new String[]{tr("Replace"), tr("Cancel")});
+		ed.setButtonIcons(new String[]{"purge", "cancel"});
+		ed.setContent(action+"\n"+ tr("The new key is already used, overwrite values?"));
+		ed.setCancelButton(2);
+		ed.toggleEnable(togglePref);
+		ed.showDialog();
+
+		return ed.getValue() == 1;
+	}
+
+	public final class TrainingDialog extends AbstractTagsDialog {
+
+		private static final int FIELD_COLUMNS = 4;
+		private final JTextField inputFileField;
+		private final JLabel inputFileLabel;
+		private final JTextField topKField;
+		private final JTextField cParameterField;
+		private final JTextField frequencyField;
+
+		private final JButton fileBrowseButton;
+		private final JButton acceptConfigButton;
+		private JRadioButton frequencyButton;
+		private JRadioButton topKButton;
+		private JCheckBox cParameterCheckBox;
+		private final JButton resetConfigButton;
+		private String inputFileValue;
+		private Double cParameterValue = 0.0;
+		private Integer topKvalue = 0;
+		private Integer frequencyValue = 0;
+		private boolean crossValidateFlag;
+		private final JButton startTrainingButton;
+		private final JLabel cErrorMessageLabel;
+		private final JLabel topKErrorMessageLabel;
+		private final JLabel inputFileErrorMessageLabel;
+		private final JLabel frequencyErrorMessageLabel;
+		private final JProgressBar trainingProgressBar;
+		private final JRadioButton byAreaRadioButton;
+		private final JRadioButton byTimeRadioButton;
+		private final JLabel userNameLabel;
+		private final JTextField userNameField;
+		private final JTextField daysField;
+		private final JLabel daysLabel;
+		private final JCheckBox trainFromUserCheckBox;
+		private final JPanel userHistoryPanel;
+		private Integer daysValue;
+		private String usernameValue;
+		private TrainWorker trainWorker;
+		private UserDataExtractAndTrainWorker userDataExtractAndTrainWorker;
+
+		private TrainingDialog(String key, int row, Map<String, Integer> map, final boolean initialFocusOnKey) {
+			super(Main.parent, tr("Training process configuration"), new String[] {tr("Cancel")});
+
+			setButtonIcons(new String[] {"ok", "cancel"});
+			setCancelButton(2);
+
+			JPanel mainPanel = new JPanel(new BorderLayout(10, 10));   //6,6
+			JPanel configPanel = new JPanel(new BorderLayout(10, 10));  //6,6    //at NORTH of mainPanel
+			JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //NORTH at config panel
+			JPanel paramPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //WEST at config panel //config panel has EAST free
+
+			JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //SOUTH at config panel
+			userHistoryPanel = new JPanel(); //CENTER of config
+
+			trainingProgressBar = new JProgressBar(0, 100);
+
+			ButtonGroup paramGroup = new ButtonGroup();
+			ButtonGroup userGroup = new ButtonGroup();
+			inputFileLabel = new JLabel();
+			inputFileField = new JTextField();
+			cParameterField = new JTextField();
+			topKField = new JTextField();
+			frequencyField = new JTextField();
+
+			cParameterCheckBox = new JCheckBox("Define C parameter");
+			topKButton = new JRadioButton("Top-K terms");
+			frequencyButton = new JRadioButton("Max-Frequency");
+			fileBrowseButton = new JButton();
+			acceptConfigButton = new JButton("Accept Configuration");
+			resetConfigButton = new JButton("Reset Configuration/Cancel training");
+			startTrainingButton = new JButton("Train Model");
+
+			inputFileErrorMessageLabel = new JLabel("");
+			cErrorMessageLabel = new JLabel("");
+			topKErrorMessageLabel = new JLabel("");
+			frequencyErrorMessageLabel = new JLabel("");
+
+			trainFromUserCheckBox = new JCheckBox("Train Model From User");
+			byAreaRadioButton = new JRadioButton("By Area");
+			byTimeRadioButton = new JRadioButton("By Time");
+			userNameLabel = new JLabel("Username:");
+			userNameField = new JTextField();
+
+			daysLabel = new JLabel("Days: ");
+			daysField = new JTextField();
+
+			cParameterCheckBox.setSelected(true);
+			userHistoryPanel.setEnabled(false);
+			byAreaRadioButton.setEnabled(false);
+			byAreaRadioButton.setSelected(true);
+			byTimeRadioButton.setEnabled(false);
+			userNameLabel.setEnabled(false);
+			userNameField.setEnabled(false);
+			daysLabel.setEnabled(false);
+			daysField.setEnabled(false);
+			userNameField.setColumns(FIELD_COLUMNS);
+			daysField.setColumns(FIELD_COLUMNS);
+
+			Collection<String> fileHistory = Main.pref.getCollection("file-open.history");
+			if (!fileHistory.isEmpty()) {
+				inputFileField.setText(MAIN_PATH);
+			}
+
+			fileBrowseButton.setText("...");
+			inputFileLabel.setText("OSM filepath: ");
+			inputFileErrorMessageLabel.setForeground(Color.RED);
+			inputFileErrorMessageLabel.setText("");
+			topKField.setText("50");
+			frequencyField.setText("200");
+			cParameterField.setText("0.01");
+
+			cParameterField.setColumns(FIELD_COLUMNS);
+			cParameterField.setEditable(false);
+			cParameterField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+			cErrorMessageLabel.setForeground(Color.RED);
+			cErrorMessageLabel.setMinimumSize(new Dimension(150, 10));
+
+			topKButton.setSelected(true);
+			topKField.setColumns(FIELD_COLUMNS);
+			topKField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+			topKErrorMessageLabel.setForeground(Color.RED);
+
+			frequencyField.setEditable(false);
+			frequencyField.setColumns(FIELD_COLUMNS);
+			frequencyField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+			frequencyErrorMessageLabel.setForeground(Color.RED);
+
+			fileBrowseButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					inputFileChooserButtonActionPerformed(evt);
+				}
+			});
+			topKButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (topKButton.isSelected()) {
+						frequencyField.setEditable(false);
+						topKField.setEditable(true);
+					} else {
+						frequencyField.setEditable(true);
+						topKField.setEditable(false);
+					}
+				}
+			});
+			frequencyButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (frequencyButton.isSelected()) {
+						topKField.setEditable(false);
+						frequencyField.setEditable(true);
+					} else {
+						topKField.setEditable(true);
+						frequencyField.setEditable(false);
+					}
+				}
+			});
+			cParameterCheckBox.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (cParameterCheckBox.isSelected()) {
+						cParameterField.setEditable(true);
+					} else {
+						cParameterField.setEditable(false);
+					}
+				}
+			});
+			acceptConfigButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					acceptConfigButtonActionPerformed(evt);
+				}
+			});
+			resetConfigButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					resetConfigButtonActionPerformed();
+				}
+			});
+
+			startTrainingButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (!acceptConfigButton.isEnabled()) {
+						startTraining();
+					} else {
+						System.out.println("Set values first!");
+					}
+				}
+			});
+
+			trainFromUserCheckBox.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (trainFromUserCheckBox.isSelected()) {
+						userHistoryPanel.setEnabled(true);
+						byAreaRadioButton.setEnabled(true);
+						byTimeRadioButton.setEnabled(true);
+						userNameLabel.setEnabled(true);
+						userNameField.setEnabled(true);
+						daysLabel.setEnabled(true);
+						daysField.setEnabled(true);
+					} else {
+						userHistoryPanel.setEnabled(false);
+						byAreaRadioButton.setEnabled(false);
+						byTimeRadioButton.setEnabled(false);
+						userNameLabel.setEnabled(false);
+						userNameField.setEnabled(false);
+						daysLabel.setEnabled(false);
+						daysField.setEnabled(false);
+					}
+				}
+			});
+
+			byAreaRadioButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (byAreaRadioButton.isSelected()) {
+						daysField.setEditable(false);
+					} else {
+						daysField.setEditable(true);
+					}
+				}
+			});
+
+			byTimeRadioButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (byTimeRadioButton.isSelected()) {
+						daysField.setEditable(true);
+					} else {
+						daysField.setEditable(false);
+					}
+				}
+			});
+
+			//grouplayout for input panel
+			buildInputPanelGroupLayout(inputPanel);
+
+			//grouplayout for param panel
+			buildParamPanelGroupLayout(paramPanel);
+
+			inputPanel.add(inputFileLabel);
+			inputPanel.add(inputFileField);
+			inputPanel.add(fileBrowseButton);
+			inputPanel.add(inputFileErrorMessageLabel);
+
+			paramGroup.add(topKButton);
+			paramGroup.add(frequencyButton);
+
+			paramPanel.add(cParameterCheckBox);
+			paramPanel.add(cParameterField);
+			paramPanel.add(cErrorMessageLabel);
+			paramPanel.add(topKButton);
+			paramPanel.add(topKField);
+			paramPanel.add(topKErrorMessageLabel);
+			paramPanel.add(frequencyButton);
+			paramPanel.add(frequencyField);
+			paramPanel.add(frequencyErrorMessageLabel);
+
+			southPanel.add(acceptConfigButton);
+			southPanel.add(resetConfigButton);
+			southPanel.add(trainFromUserCheckBox);
+
+			userGroup.add(byAreaRadioButton);
+			userGroup.add(byTimeRadioButton);
+			userHistoryPanel.add(byAreaRadioButton);
+			userHistoryPanel.add(byTimeRadioButton);
+			userHistoryPanel.add(daysLabel);
+			userHistoryPanel.add(daysField);
+			userHistoryPanel.add(userNameLabel);
+			userHistoryPanel.add(userNameField);
+
+			//grouplayout for user history panel
+			/*
                 userNameLabel       userField
                 arearadiobutton
                 timeradiobutton     daysLabel   daysField
-             */
-            buildUserHistoryPanelGroupLayout();
-
-            configPanel.add(inputPanel, BorderLayout.NORTH);
-            configPanel.add(userHistoryPanel, BorderLayout.EAST);
-            configPanel.add(paramPanel, BorderLayout.WEST);
-            configPanel.add(southPanel, BorderLayout.SOUTH);
-
-            userHistoryPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
-                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "Train by user History"));
-            paramPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
-                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "SVM Configuration"));
-            inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            configPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-
-            mainPanel.add(configPanel, BorderLayout.NORTH);
-            mainPanel.add(startTrainingButton, BorderLayout.CENTER);
-            mainPanel.add(trainingProgressBar, BorderLayout.SOUTH);
-
-            AutoCompletionManager autocomplete = Main.getLayerManager().getEditLayer().data.getAutoCompletionManager();
-            List<AutoCompletionListItem> keyList = autocomplete.getKeys();
-            Collections.sort(keyList, defaultACItemComparator);
-
-            setContent(mainPanel, false);
-        }
-
-        private void buildInputPanelGroupLayout(JPanel inputPanel) {
-            GroupLayout inputGroupLayout = new GroupLayout(inputPanel);
-            inputPanel.setLayout(inputGroupLayout);
-            inputGroupLayout.setAutoCreateGaps(true);
-            inputGroupLayout.setAutoCreateContainerGaps(true);
-
-            GroupLayout.SequentialGroup inputHorGroup = inputGroupLayout.createSequentialGroup();
-            inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileLabel).
-                    addComponent(inputFileErrorMessageLabel));
-            inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileField));
-            inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(fileBrowseButton));
-            inputGroupLayout.setHorizontalGroup(inputHorGroup);
-
-            GroupLayout.SequentialGroup inputVerGroup = inputGroupLayout.createSequentialGroup();
-            inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).addComponent(inputFileLabel).
-                    addComponent(inputFileField).addComponent(fileBrowseButton));
-            inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).
-                    addComponent(inputFileErrorMessageLabel));
-            inputGroupLayout.setVerticalGroup(inputVerGroup);
-        }
-
-        private void buildParamPanelGroupLayout(JPanel paramPanel) {
-            GroupLayout paramGroupLayout = new GroupLayout(paramPanel);
-            paramPanel.setLayout(paramGroupLayout);
-            paramGroupLayout.setAutoCreateGaps(true);
-            paramGroupLayout.setAutoCreateContainerGaps(true);
-
-            GroupLayout.SequentialGroup paramHorGroup = paramGroupLayout.createSequentialGroup();
-            paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(topKButton).
-                    addComponent(frequencyButton).addComponent(cParameterCheckBox));
-            paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cParameterField).
-                    addComponent(topKField).addComponent(frequencyField));
-            paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cErrorMessageLabel).
-                    addComponent(topKErrorMessageLabel).addComponent(frequencyErrorMessageLabel));
-            paramGroupLayout.setHorizontalGroup(paramHorGroup);
-
-            GroupLayout.SequentialGroup paramVerGroup = paramGroupLayout.createSequentialGroup();
-            paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(cParameterCheckBox).addComponent(cParameterField).addComponent(cErrorMessageLabel));
-            paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).addComponent(topKButton).
-                    addComponent(topKField).addComponent(topKErrorMessageLabel));
-            paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(frequencyButton).addComponent(frequencyField).addComponent(frequencyErrorMessageLabel));
-            paramGroupLayout.setVerticalGroup(paramVerGroup);
-        }
-
-        private void buildUserHistoryPanelGroupLayout() {
-            GroupLayout userHistoryGroupLayout = new GroupLayout(userHistoryPanel);
-            userHistoryPanel.setLayout(userHistoryGroupLayout);
-            userHistoryGroupLayout.setAutoCreateGaps(true);
-            userHistoryGroupLayout.setAutoCreateContainerGaps(true);
-            userHistoryGroupLayout.linkSize(SwingConstants.HORIZONTAL, userNameField, daysLabel, daysField);
-
-            GroupLayout.SequentialGroup userHistoryHorGroup = userHistoryGroupLayout.createSequentialGroup();
-
-            userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameLabel)
-                    .addComponent(byAreaRadioButton).addComponent(byTimeRadioButton));
-            userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameField)
-                    .addComponent(daysLabel));
-            userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(daysField));
-            userHistoryGroupLayout.setHorizontalGroup(userHistoryHorGroup);
-
-            GroupLayout.SequentialGroup userHistoryVerGroup = userHistoryGroupLayout.createSequentialGroup();
-            userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(userNameLabel).addComponent(userNameField));
-            userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(byAreaRadioButton));
-            userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(byTimeRadioButton).addComponent(daysLabel).addComponent(daysField));
-            userHistoryGroupLayout.setVerticalGroup(userHistoryVerGroup);
-        }
-
-        private void inputFileChooserButtonActionPerformed(ActionEvent evt) {
-            try {
-                final File file = new File(inputFileField.getText());
-                final JFileChooser fileChooser = new JFileChooser(file);
-
-                final int returnVal = fileChooser.showOpenDialog(this);
-                if (returnVal == JFileChooser.APPROVE_OPTION) {
-                    inputFileField.setText(fileChooser.getSelectedFile().getAbsolutePath());
-                }
-            } catch (RuntimeException ex) {
-                Main.warn(ex);
-            }
-        }
-
-        private void acceptConfigButtonActionPerformed(ActionEvent evt) {
-            //parse values
-            inputFileValue = inputFileField.getText();
-
-            if (!new File(inputFileValue).exists()) {
-                inputFileErrorMessageLabel.setText("OSM file does not exist");
-                resetConfigButtonActionPerformed();
-                return;
-            }
-
-            if (cParameterCheckBox.isSelected()) {
-                String c = cParameterField.getText();
-                try {
-                    cParameterValue = Double.parseDouble(c.replace(",", "."));
-                    cErrorMessageLabel.setText("");
-                } catch (NumberFormatException ex) {
-                    cErrorMessageLabel.setText("Must be a number!");
-                    System.out.println("c must be a number!" + ex); //make empty textLabel beside c param to notify errors
-                    resetConfigButtonActionPerformed();
-                    return;
-                }
-                crossValidateFlag = false;
-            } else {
-                crossValidateFlag = true;
-            }
-
-            if (topKButton.isSelected()) {
-                String k = topKField.getText();
-                try {
-                    topKvalue = Integer.parseInt(k);
-                    topKErrorMessageLabel.setText("");
-                } catch (NumberFormatException ex) {
-                    topKErrorMessageLabel.setText("Must be an Integer!");
-                    resetConfigButtonActionPerformed();
-                    return;
-                }
-            } else {
-                String f = frequencyField.getText();
-                try {
-                    frequencyValue = Integer.parseInt(f);
-                    frequencyErrorMessageLabel.setText("");
-                } catch (NumberFormatException ex) {
-                    frequencyErrorMessageLabel.setText("Must be an Integer!");
-                    resetConfigButtonActionPerformed();
-                    return;
-                }
-            }
-
-            if (trainFromUserCheckBox.isSelected()) {
-                usernameValue = userNameField.getText();
-                if (byTimeRadioButton.isSelected()) {
-                    try {
-                        daysValue = Integer.parseInt(daysField.getText());
-                    } catch (NumberFormatException ex) {
-                        daysField.setText("Integer!");
-                        Main.warn(ex);
-                    }
-                }
-
-                userHistoryPanel.setEnabled(false);
-                byAreaRadioButton.setEnabled(false);
-                byTimeRadioButton.setEnabled(false);
-                userNameLabel.setEnabled(false);
-                userNameField.setEnabled(false);
-                daysLabel.setEnabled(false);
-                daysField.setEnabled(false);
-            }
-
-            System.out.println("Running configuration:" + "\nC parameter: " + cParameterValue +" \ntopK: " + topKvalue
-                    + "\nMax Frequency: " + frequencyValue + "\nCross Validate?: " + crossValidateFlag);
-
-            trainFromUserCheckBox.setEnabled(false);
-            inputFileField.setEditable(false);
-            cParameterField.setEditable(false);
-            topKField.setEditable(false);
-            frequencyField.setEditable(false);
-            cParameterCheckBox.setEnabled(false);
-            topKButton.setEnabled(false);
-            frequencyButton.setEnabled(false);
-            acceptConfigButton.setEnabled(false);
-            fileBrowseButton.setEnabled(false);
-        }
-
-        private void resetConfigButtonActionPerformed() {
-            if (trainWorker != null) {
-                try {
-                    trainWorker.cancel(true);
-                } catch (CancellationException ex) {
-                    startTrainingButton.setEnabled(true);
-                    System.out.println(ex);
-                }
-            }
-            if (userDataExtractAndTrainWorker != null) {
-                try {
-                    userDataExtractAndTrainWorker.cancel(true);
-                } catch (CancellationException ex) {
-                    startTrainingButton.setEnabled(true);
-                    System.out.println(ex);
-                }
-            }
-            inputFileField.setEditable(true);
-            cParameterField.setEditable(true);
-            topKField.setEditable(true);
-            frequencyField.setEditable(true);
-            cParameterCheckBox.setEnabled(true);
-            topKButton.setEnabled(true);
-            frequencyButton.setEnabled(true);
-            acceptConfigButton.setEnabled(true);
-            fileBrowseButton.setEnabled(true);
-            trainFromUserCheckBox.setEnabled(true);
-
-            if (trainFromUserCheckBox.isSelected()) {
-                userHistoryPanel.setEnabled(true);
-                byAreaRadioButton.setEnabled(true);
-                byTimeRadioButton.setEnabled(true);
-                userNameLabel.setEnabled(true);
-                userNameField.setEnabled(true);
-                daysLabel.setEnabled(true);
-                daysField.setEnabled(true);
-            }
-        }
-
-        private void startTraining() {
-            startTrainingButton.setEnabled(false);
-
-            if (trainFromUserCheckBox.isSelected()) { //if user training. train by area or days
-                EventQueue.invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-
-                        userDataExtractAndTrainWorker = new UserDataExtractAndTrainWorker(inputFileValue, usernameValue, daysValue,
-                                byAreaRadioButton.isSelected(), crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
-                                topKButton.isSelected(), languageDetector);
-
-                        userDataExtractAndTrainWorker.addPropertyChangeListener(new PropertyChangeListener() {
-                            @Override
-                            public void propertyChange(PropertyChangeEvent evt) {
-                                if ("progress".equals(evt.getPropertyName())) {
-                                    int progress = (Integer) evt.getNewValue();
-                                    trainingProgressBar.setValue(progress);
-                                    if (progress == 100) {
-                                        startTrainingButton.setEnabled(true);
-                                    }
-                                }
-                            }
-                        });
-
-                        try {
-                            System.out.println("executing userDataExtractAndTrainWorker Thread..");
-                            userDataExtractAndTrainWorker.execute();
-                        } catch (Exception ex) {
-                            Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-                    }
-                });
-            } else {
-                EventQueue.invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-                        trainWorker = new TrainWorker(inputFileValue, crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
-                                topKButton.isSelected(), languageDetector);
-
-                        trainWorker.addPropertyChangeListener(new PropertyChangeListener() {
-                            @Override
-                            public void propertyChange(PropertyChangeEvent evt) {
-                                if ("progress".equals(evt.getPropertyName())) {
-                                    int progress = (Integer) evt.getNewValue();
-                                    trainingProgressBar.setValue(progress);
-                                    if (progress == 100) {
-                                        startTrainingButton.setEnabled(true);
-                                    }
-                                }
-                            }
-                        });
-
-                        try {
-                            trainWorker.execute();
-                        } catch (Exception ex) {
-                            Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-                    }
-                });
-            }
-        }
-    }
-
-    public static final BooleanProperty PROPERTY_FIX_TAG_LOCALE =
-            new BooleanProperty("properties.fix-tag-combobox-locale", false);
-    public static final BooleanProperty PROPERTY_REMEMBER_TAGS =
-            new BooleanProperty("properties.remember-recently-added-tags", true);
-    public static final IntegerProperty PROPERTY_RECENT_TAGS_NUMBER =
-            new IntegerProperty("properties.recently-added-tags", DEFAULT_LRU_TAGS_NUMBER);
-
-    abstract static class AbstractTagsDialog extends ExtendedDialog {
-        AutoCompletingComboBox keys;
-        AutoCompletingComboBox values;
-
-        AbstractTagsDialog(Component parent, String title, String[] buttonTexts) {
-            super(parent, title, buttonTexts);
-            addMouseListener(new PopupMenuLauncher(popupMenu));
-        }
-
-        @Override
-        public void setupDialog() {
-            super.setupDialog();
-            final Dimension size = getSize();
-            // Set resizable only in width
-            setMinimumSize(size);
-            setPreferredSize(size);
-            // setMaximumSize does not work, and never worked, but still it seems not to bother Oracle to fix this 10-year-old bug
-            // https://bugs.openjdk.java.net/browse/JDK-6200438
-            // https://bugs.openjdk.java.net/browse/JDK-6464548
-
-            setRememberWindowGeometry(getClass().getName() + ".geometry",
-                    WindowGeometry.centerInWindow(Main.parent, size));
-        }
-
-        @Override
-        public void setVisible(boolean visible) {
-            // Do not want dialog to be resizable in height, as its size may increase each time because of the recently added tags
-            // So need to modify the stored geometry (size part only) in order to use the automatic positioning mechanism
-            if (visible) {
-                WindowGeometry geometry = initWindowGeometry();
-                Dimension storedSize = geometry.getSize();
-                Dimension size = getSize();
-                if (!storedSize.equals(size)) {
-                    if (storedSize.width < size.width) {
-                        storedSize.width = size.width;
-                    }
-                    if (storedSize.height != size.height) {
-                        storedSize.height = size.height;
-                    }
-                    rememberWindowGeometry(geometry);
-                }
-                if (keys != null) {
-                    keys.setFixedLocale(PROPERTY_FIX_TAG_LOCALE.get());
-                }
-            }
-            super.setVisible(visible);
-        }
-
-        /**
-         * Create a focus handling adapter and apply in to the editor component of value
-         * autocompletion box.
-         * @param autocomplete Manager handling the autocompletion
-         * @param comparator Class to decide what values are offered on autocompletion
-         * @return The created adapter
-         */
-        protected FocusAdapter addFocusAdapter(final AutoCompletionManager autocomplete, final Comparator<AutoCompletionListItem> comparator) {
-            // get the combo box' editor component
-            JTextComponent editor = (JTextComponent) values.getEditor().getEditorComponent();
-            // Refresh the values model when focus is gained
-            FocusAdapter focus = new FocusAdapter() {
-                @Override
-                public void focusGained(FocusEvent e) {
-                    String key = keys.getEditor().getItem().toString();
-
-                    List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key));
-                    Collections.sort(valueList, comparator);
-
-                    values.setPossibleACItems(valueList);
-                    values.getEditor().selectAll();
-                }
-            };
-            editor.addFocusListener(focus);
-            return focus;
-        }
-
-        protected JPopupMenu popupMenu = new JPopupMenu() {
-            JCheckBoxMenuItem fixTagLanguageCb = new JCheckBoxMenuItem(
-                    new AbstractAction(tr("Use English language for tag by default")) {
-                        @Override
-                        public void actionPerformed(ActionEvent e) {
-                            boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
-                            PROPERTY_FIX_TAG_LOCALE.put(sel);
-                        }
-                    });
-            {
-                add(fixTagLanguageCb);
-                fixTagLanguageCb.setState(PROPERTY_FIX_TAG_LOCALE.get());
-            }
-        };
-    }
-
-    class ModelSettingsDialog extends JPanel {
-
-        private final JLabel chooseModelLabel;
-        private final JButton chooseModelButton;
-        private final JTextField chooseModelTextField;
-
-        private final DefaultListModel<String> combinationDefaultListModel = new DefaultListModel<>();
-        private final JList<String> modelCombinationList = new JList<>(combinationDefaultListModel);
-        private final JPanel modelCombinationPanel;
-        private final JPanel weightsPanel;
-        private final JCheckBox useModelCombinationCheckbox;
-        private final JButton acceptWeightsButton;
-        private final JButton resetWeightsButton;
-        private final JButton removeSelectedModelButton;
-        private Map<JTextField, String> weightFieldsAndPaths = new HashMap<>();
-        private final Map<String, Double> normalizedPathsAndWeights = new HashMap<>();
-        private final JOptionPane pane;
-        private final JDialog dlg;
-        private final JPanel mainPanel;
-        private final JPanel singleSelectionPanel;
-        private final JPanel setResetWeightsPanel;
-        private final JScrollPane combinationScrollPane;
-        private final JScrollPane singleSelectionScrollPane;
-        private final TitledBorder modelTitle;
-        private final TitledBorder weightTitle;
-        private final TitledBorder combineTitle;
-        private final Dimension singleSelectionDimension;
-        private final Dimension modelCombinationDimension;
-        private final Dimension mainPanelDimension;
-
-        ModelSettingsDialog(Collection<OsmPrimitive> sel1, final AddTagsDialog addDialog) {
-
-            loadPreviousCombinedSVMModel();
-            singleSelectionDimension = new Dimension(470, 70);
-            modelCombinationDimension = new Dimension(450, 250);
-            mainPanelDimension = new Dimension(600, 350);
-
-            //------- <NORTH of main> ---------//
-            mainPanel = new JPanel(new BorderLayout(10, 10));
-            singleSelectionPanel = new JPanel(new BorderLayout(10, 10));
-            setResetWeightsPanel = new JPanel();
-
-            chooseModelLabel = new JLabel("Choose a Model:");
-            chooseModelTextField = new JTextField();
-            chooseModelButton = new JButton("...");
-            chooseModelTextField.setText(MODEL_PATH);
-
-            singleSelectionPanel.add(chooseModelLabel, BorderLayout.NORTH);
-            singleSelectionPanel.add(chooseModelTextField, BorderLayout.WEST);
-            singleSelectionPanel.add(chooseModelButton, BorderLayout.EAST);
-
-            singleSelectionScrollPane = new JScrollPane(singleSelectionPanel);
-            singleSelectionScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
-            singleSelectionScrollPane.setPreferredSize(singleSelectionDimension);
-
-            //------- </NORTH of main> ---------//
-
-            //------- <WEST of main> ---------//
-            modelCombinationList.setFixedCellHeight(20);
-            modelCombinationList.setEnabled(false);
-            modelCombinationPanel = new JPanel(new BorderLayout(10, 10));
-
-            weightsPanel = new JPanel();
-            weightsPanel.setLayout(new BoxLayout(weightsPanel, BoxLayout.Y_AXIS));
-            weightsPanel.setEnabled(false);
-
-
-            acceptWeightsButton = new JButton("Set Weights/Normalize");
-            resetWeightsButton = new JButton("Reset Weights");
-            removeSelectedModelButton = new JButton("Remove Selected");
-            setResetWeightsPanel.add(acceptWeightsButton);
-            setResetWeightsPanel.add(resetWeightsButton);
-            setResetWeightsPanel.add(removeSelectedModelButton);
-            removeSelectedModelButton.setEnabled(false);
-            acceptWeightsButton.setEnabled(false);
-            resetWeightsButton.setEnabled(false);
-
-            modelCombinationPanel.add(modelCombinationList, BorderLayout.CENTER);
-            modelCombinationPanel.add(weightsPanel, BorderLayout.EAST);
-            modelCombinationPanel.add(setResetWeightsPanel, BorderLayout.SOUTH);
-
-            combinationScrollPane = new JScrollPane(modelCombinationPanel);
-
-            combinationScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
-            combinationScrollPane.setPreferredSize(modelCombinationDimension);   //new Dimension(450, 250) // w/h
-
-            //------- </WEST of main> ---------//
-
-            //------- <SOUTH of main> ---------//
-            useModelCombinationCheckbox = new JCheckBox("Combine different models?");
-
-            //------- </SOUTH of main> ---------//
-
-            //------- <Borders> ---------//
-            modelTitle = BorderFactory.createTitledBorder("Models");
-            weightTitle = BorderFactory.createTitledBorder("W");
-            combineTitle = BorderFactory.createTitledBorder("Combine Models");
-            modelCombinationList.setBorder(modelTitle);
-            weightsPanel.setBorder(weightTitle);
-
-            for (Entry<JTextField, String> entry : weightFieldsAndPaths.entrySet()) {
-                combinationDefaultListModel.addElement(entry.getValue());
-
-                JTextField weightTextField = new JTextField("0.00");
-                weightTextField.setMaximumSize(new Dimension(80, 20));
-                weightsPanel.add(entry.getKey());
-            }
-
-            //modelCombinationPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            modelCombinationPanel.setBorder(combineTitle);
-            singleSelectionPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            //------- </Borders> ---------//
-
-            chooseModelButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    modelChooserButtonActionPerformed(evt);
-                }
-            });
-
-            useModelCombinationCheckbox.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    userCombinationCheckboxActionPerformed(evt);
-                }
-            });
-
-            acceptWeightsButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    acceptWeightsButtonActionPerformed(evt);
-                }
-            });
-
-            resetWeightsButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    resetWeightsButtonActionPerformed(evt);
-                }
-            });
-
-            removeSelectedModelButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    removeSelectedModelButtonActionPerformed(evt);
-                }
-            });
-            mainPanel.add(singleSelectionScrollPane, BorderLayout.NORTH);
-            mainPanel.add(combinationScrollPane, BorderLayout.CENTER);
-            mainPanel.add(useModelCombinationCheckbox, BorderLayout.SOUTH);
-
-            mainPanel.setPreferredSize(mainPanelDimension);
-
-            this.add(mainPanel);
-
-            pane = new JOptionPane(this, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
-                @Override
-                public void setValue(Object newValue) {
-                    super.setValue(newValue);
-                    if (newValue instanceof Integer && (int) newValue == 0 && useModelCombinationCheckbox.isSelected()) {
-                        System.out.println("model settings button value: " + newValue);
-                        System.out.println("\nUSE COMBINED MODEL\n");
-                        useCombinedModel = true;
-                        useCustomSVMModel = false;
-
-                        addDialog.loadSVMmodel();
-                        addDialog.createOSMObject(sel);
-                        saveCombinedModel();
-                        dlg.setVisible(false);
-                    } else if (newValue instanceof Integer && (int) newValue == -1 && useModelCombinationCheckbox.isSelected()) {
-                        System.out.println("model settings button value: " + newValue);
-                        useCombinedModel = false;
-                        useCustomSVMModel = false;
-                        System.out.println("Use combined model");
-
-                        addDialog.loadSVMmodel();
-                        addDialog.createOSMObject(sel);
-                        dlg.setVisible(false);
-                    } else if (newValue instanceof Integer && (int) newValue == 0 && !useModelCombinationCheckbox.isSelected()) {
-                        System.out.println("model settings button value: " + newValue);
-                        System.out.println("Don t use combined model, use custom model");
-                        useCombinedModel = false;
-                        useCustomSVMModel = true;
-                        addDialog.loadSVMmodel();
-                        addDialog.createOSMObject(sel);
-                        dlg.setVisible(false);
-                    } else if (newValue instanceof Integer && (int) newValue == -1 && !useModelCombinationCheckbox.isSelected()) {
-                        System.out.println("model settings button value: " + newValue);
-                        System.out.println("Don t use combined model, use custom model");
-                        useCombinedModel = false;
-                        useCustomSVMModel = false;
-                        addDialog.loadSVMmodel();
-                        addDialog.createOSMObject(sel);
-                        dlg.setVisible(false);
-                    } else if (newValue == null || newValue.equals("uninitializedValue")) {
-                        System.out.println("uninitializedValue, do nothing");
-                    }
-                }
-            };
-
-            dlg = pane.createDialog(Main.parent, tr("Model Settings"));
-            dlg.setVisible(true);
-        }
-
-        public void makeVisible(boolean visible) {
-            dlg.setVisible(true);
-        }
-
-        private void modelChooserButtonActionPerformed(ActionEvent evt) {
-
-            try {
-                final File file = new File(chooseModelTextField.getText());
-                final JFileChooser fileChooser = new JFileChooser(file);
-
-                final int returnVal = fileChooser.showOpenDialog(this);
-                if (returnVal == JFileChooser.APPROVE_OPTION) {
-                    chooseModelTextField.setText(fileChooser.getSelectedFile().getAbsolutePath());
-                    useCustomSVMModel = true;
-                    customSVMModelPath = fileChooser.getSelectedFile().getAbsolutePath();
-                }
-
-                if (useModelCombinationCheckbox.isSelected()) {
-                    String svmModelPath = fileChooser.getSelectedFile().getAbsolutePath();
-                    String svmModelText;
-                    if (System.getProperty("os.name").contains("ux")) {
-                        if (svmModelPath.contains("/")) {
-                            svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("/"));
-                        } else {
-                            svmModelText = svmModelPath;
-                        }
-                    } else {
-                        if (svmModelPath.contains("\\")) {
-                            svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("\\"));
-                        } else {
-                            svmModelText = svmModelPath;
-                        }
-                    }
-                    combinationDefaultListModel.addElement(svmModelText);
-                    JTextField weightTextField = new JTextField("0.00");
-                    weightFieldsAndPaths.put(weightTextField, svmModelPath);
-                    System.out.println("weights size: " + weightFieldsAndPaths.size());
-
-                    weightTextField.setMaximumSize(new Dimension(80, 20));
-                    weightsPanel.add(weightTextField);
-                    //add additional textbox
-                }
-            } catch (RuntimeException ex) {
-                Main.warn(ex);
-            }
-        }
-
-        private void userCombinationCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
-
-            if (useModelCombinationCheckbox.isSelected()) {
-                useCombinedModel = true;
-                useCustomSVMModel = false; //reseting the selected custom SVM model only here
-                removeSelectedModelButton.setEnabled(true);
-                acceptWeightsButton.setEnabled(true);
-                resetWeightsButton.setEnabled(true);
-
-                chooseModelTextField.setEnabled(false);
-                modelCombinationList.setEnabled(true);
-                weightsPanel.setEnabled(true);
-                Component[] weightPanelComponents = weightsPanel.getComponents();
-                for (Component weightPanelComponent : weightPanelComponents) {
-                    weightPanelComponent.setEnabled(true);
-                }
-            } else {
-                useCombinedModel = false;
-                useCustomSVMModel = true;
-                removeSelectedModelButton.setEnabled(false);
-                acceptWeightsButton.setEnabled(false);
-                resetWeightsButton.setEnabled(false);
-
-                chooseModelTextField.setEnabled(true);
-                modelCombinationList.setEnabled(false);
-                weightsPanel.setEnabled(false);
-                Component[] weightPanelComponents = weightsPanel.getComponents();
-                for (Component weightPanelComponent : weightPanelComponents) {
-                    weightPanelComponent.setEnabled(false);
-                }
-            }
-        }
-
-        private void acceptWeightsButtonActionPerformed(ActionEvent evt) {
-            int weightsCount = 0;
-            removeSelectedModelButton.setEnabled(false);
-            double weightSum = 0;
-            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
-                if (weightField.getText().equals("")) {
-                    weightField.setText("0.00");
-                }
-
-                try {
-                    //TODO replace "," with "." to parse doubles with commas
-                    Double weightValue = Double.parseDouble(weightField.getText());
-
-                    weightValue = Math.abs(weightValue);
-                    weightSum += weightValue;
-                } catch (NumberFormatException ex) {
-                    Main.warn(ex);
-                }
-                weightsCount++;
-            }
-
-            if (!filesAndWeights.isEmpty()) {
-                filesAndWeights.clear();
-            }
-
-            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
-                try {
-                    Double weightValue = Double.parseDouble(weightField.getText());
-
-                    weightValue = Math.abs(weightValue)/weightSum; //normalize
-
-                    if (weightSum == 0) {
-                        weightValue = 1.0/weightsCount;
-                    }
-
-                    weightField.setText(new DecimalFormat("#.##").format(weightValue));
-                    normalizedPathsAndWeights.put(weightFieldsAndPaths.get(weightField), weightValue);
-                    filesAndWeights.put(new File(weightFieldsAndPaths.get(weightField)), weightValue);
-                    System.out.println("normalized: " + weightFieldsAndPaths.get(weightField) + "->" + weightValue);
-                    weightField.setEnabled(false);
-
-                } catch (NumberFormatException ex) {
-                    Main.warn(ex);
-                }
-            }
-
-            useCombinedModel = true;
-            useCustomSVMModel = false;
-        }
-
-        private void resetWeightsButtonActionPerformed(ActionEvent evt) {
-            removeSelectedModelButton.setEnabled(true);
-            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
-                weightField.setEnabled(true);
-            }
-        }
-
-        private void removeSelectedModelButtonActionPerformed(ActionEvent evt) {
-            int index = modelCombinationList.getSelectedIndex();
-            String modelToBeRemoved = combinationDefaultListModel.get(index);
-            combinationDefaultListModel.remove(index);
-            System.out.println("model to be removed: " + modelToBeRemoved);
-
-            Iterator<Entry<JTextField, String>> it = weightFieldsAndPaths.entrySet().iterator();
-            while (it.hasNext()) {
-                Entry<JTextField, String> en = it.next();
-                if (en.getValue().equals(modelToBeRemoved)) {
-                    it.remove();
-                }
-            }
-            System.out.println("model to be removed: " + modelToBeRemoved);
-
-            weightsPanel.remove(index);
-            weightsPanel.revalidate();
-            weightsPanel.repaint();
-        }
-
-        @SuppressWarnings("unchecked")
-        private void loadPreviousCombinedSVMModel() {
-            File combinedModelClassesFile = new File(combinedModelClasses);
-
-            if (combinedModelClassesFile.exists()) {
-                FileInputStream fileIn = null;
-                ObjectInputStream in = null;
-                try {
-                    fileIn = new FileInputStream(combinedModelClassesFile);
-                    in = new ObjectInputStream(fileIn);
-                    weightFieldsAndPaths = (Map<JTextField, String>) in.readObject();
-                } catch (FileNotFoundException ex) {
-                    Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                } catch (IOException | ClassNotFoundException ex) {
-                    Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                } finally {
-                    try {
-                        if (in != null) {
-                            in.close();
-                        }
-                        if (fileIn != null) {
-                            fileIn.close();
-                        }
-
-                    } catch (IOException ex) {
-                        Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                    }
-                }
-            } else {
-                try {
-                    combinedModelClassesFile.createNewFile();
-                } catch (IOException ex) {
-                    Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                }
-            }
-        }
-
-        private void saveCombinedModel() {
-            try (FileOutputStream fileOut = new FileOutputStream(combinedModelClasses);
-                    ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
-                out.writeObject(weightFieldsAndPaths);
-            } catch (IOException e) {
-                System.out.println("serialize error" + e);
-            }
-        }
-    }
-
-    class AddTagsDialog extends AbstractTagsDialog {
-        List<JosmAction> recentTagsActions = new ArrayList<>();
-
-        // Counter of added commands for possible undo
-        private int commandCount;
-        private final JLabel recommendedClassesLabel;
-        private final JButton modelSettingsButton;
-        private final JButton addAndContinueButton;
-        private final DefaultListModel<String> model;
-        private final JList<String> categoryList;
-        private Model modelSVM;
-        private int modelSVMLabelSize;
-        private int[] modelSVMLabels;
-        private Map<String, String> mappings;
-        private Map<String, Integer> mapperWithIDs;
-        private Map<Integer, String> idsWithMappings;
-        private List<String> textualList = new ArrayList<>();
-        private final JCheckBox useTagsCheckBox;
-        private ModelSettingsDialog modelSettingsDialog;
-        private static final int RECOMMENDATIONS_SIZE = 10;
-
-        AddTagsDialog() {
-            super(Main.parent, tr("Add value?"), new String[] {tr("OK"), tr("Cancel")});
-            setButtonIcons(new String[] {"ok", "cancel"});
-            setCancelButton(2);
-            configureContextsensitiveHelp("/Dialog/AddValue", true /* show help button */);
-            final AddTagsDialog addTagsDialog = this;
-
-            loadOntology();
-            //if the user did not train a model by running the training process
-            //the list does not exist in a file and so we load the default list from the jar.
-
-            System.out.println("path for textual: " + TEXTUAL_LIST_PATH);
-            File textualListFile = new File(TEXTUAL_LIST_PATH);
-            if (textualListFile.exists()) {
-                loadTextualList(textualListFile);
-            } else {
-                loadDefaultTextualList();
-            }
-
-            //if training process has not been performed, we use two sample SVM models, extracted from the jar
-
-            JPanel splitPanel = new JPanel(new BorderLayout(10, 10));
-            JPanel mainPanel = new JPanel(new GridBagLayout()); //original panel, will be wrapped by the splitPanel
-            JPanel recommendPanel = new JPanel(new BorderLayout(10, 10));   //will contain listPanel, action panel
-            JPanel listPanel = new JPanel(new BorderLayout(10, 10)); //class recommend label, recommendation list
-            JPanel actionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); //model selection buttons or configuration
-
-            addAndContinueButton = new JButton("Add and continue");
-            modelSettingsButton = new JButton("Model Settings");
-            useTagsCheckBox = new JCheckBox("Predict using tags");
-            recommendedClassesLabel = new JLabel("Recommended Classes:");
-
-            addAndContinueButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    String selectedClass = categoryList.getSelectedValue();
-                    addAndContinueButtonActionPerformed(evt, selectedClass);
-
-                    //reconstruct vector for instance and use the model that was trained with classes here
-
-                    List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
-                    OsmPrimitive s;
-
-                    //get a simple selection
-                    if (!osmPrimitiveSelection.isEmpty()) {
-                        s = osmPrimitiveSelection.get(0);
-                        if (s.getInterestingTags().isEmpty()) {
-                            //load original model
-                            modelWithClasses = false;
-                            loadSVMmodel();
-                            createOSMObject(sel); //create object without class features
-                        } else {
-                            //recommend using tags: set the checkbox selected to avoid confusing the user
-                            useTagsCheckBox.setSelected(true);
-
-                            if (useTagsCheckBox.isSelected()) {
-                                //load model with classes
-                                modelWithClasses = true;
-                                loadSVMmodel();
-                                createOSMObject(sel); //create object including class features
-                            } else {
-                                modelWithClasses = false;
-                                loadSVMmodel();
-                                createOSMObject(sel); //create object including class features
-                            }
-                        }
-                    }
-                }
-            });
-
-            modelSettingsButton.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if (modelSettingsDialog == null) {
-                        System.out.println("new modelSettingsDialog");
-                        modelSettingsDialog = new ModelSettingsDialog(sel, addTagsDialog);
-                    } else {
-                        System.out.println("set modelSettingsDialog visible");
-                        modelSettingsDialog.makeVisible(true);
-                    }
-                }
-            });
-
-            useTagsCheckBox.addActionListener(new java.awt.event.ActionListener() {
-                @Override
-                public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
-                    OsmPrimitive s;
-                    if (!osmPrimitiveSelection.isEmpty()) {
-                        s = osmPrimitiveSelection.get(0);
-                        if (s.getInterestingTags().isEmpty()) {
-                            //load original model
-                            modelWithClasses = false;
-                            loadSVMmodel();
-                            createOSMObject(sel); //create object without class features
-                        } else {
-                            //useTagsCheckBox
-                            if (useTagsCheckBox.isSelected()) {
-                                //load model with classes
-                                modelWithClasses = true;
-                                loadSVMmodel();
-                                createOSMObject(sel); //create object including class features
-                            } else {
-                                modelWithClasses = false;
-                                loadSVMmodel();
-                                createOSMObject(sel); //create object including class features
-                            }
-                        }
-                    }
-                }
-            });
-
-            keys = new AutoCompletingComboBox();
-            values = new AutoCompletingComboBox();
-
-            mainPanel.add(new JLabel("<html>"+trn("This will change up to {0} object.",
-                    "This will change up to {0} objects.", sel.size(), sel.size())
-            +"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL));
-
-            AutoCompletionManager autocomplete = Main.getLayerManager().getEditLayer().data.getAutoCompletionManager();
-            List<AutoCompletionListItem> keyList = autocomplete.getKeys();
-
-            AutoCompletionListItem itemToSelect = null;
-            // remove the object's tag keys from the list
-            Iterator<AutoCompletionListItem> iter = keyList.iterator();
-            while (iter.hasNext()) {
-                AutoCompletionListItem item = iter.next();
-                if (item.getValue().equals(lastAddKey)) {
-                    itemToSelect = item;
-                }
-                for (int i = 0; i < tagData.getRowCount(); ++i) {
-                    if (item.getValue().equals(tagData.getValueAt(i, 0))) {
-                        if (itemToSelect == item) {
-                            itemToSelect = null;
-                        }
-                        iter.remove();
-                        break;
-                    }
-                }
-            }
-
-            Collections.sort(keyList, defaultACItemComparator);
-            keys.setPossibleACItems(keyList);
-            keys.setEditable(true);
-
-            mainPanel.add(keys, GBC.eop().fill());
-            mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol());
-
-            model = new DefaultListModel<>();
-
-            parseTagsMappedToClasses();
-
-            List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
-            OsmPrimitive s;
-            //get a simple selection
-            if (!osmPrimitiveSelection.isEmpty()) {
-                s = osmPrimitiveSelection.get(0);
-                File modelDirectory = new File(MODEL_PATH);
-                String modelWithClassesPath = modelDirectory.getAbsolutePath() + "/model_with_classes";
-                File modelWithClassesFile = new File(modelWithClassesPath);
-                if (s.getInterestingTags().isEmpty() || !modelWithClassesFile.exists()) {
-                    modelWithClasses = false;
-                    loadSVMmodel(); //load original model
-                    createOSMObject(sel); //create object without class features
-                } else {
-                    //recommend using tags: set the checkbox selected to avoid confusing the user
-                    useTagsCheckBox.setSelected(true);
-                    modelWithClasses = true;
-                    loadSVMmodel(); //load model with classes
-                    createOSMObject(sel); //create object including class features
-                }
-            }
-
-            categoryList = new JList<>(model);
-
-            ListSelectionListener listSelectionListener = new ListSelectionListener() {
-                @Override
-                public void valueChanged(ListSelectionEvent listSelectionEvent) {
-                    if (!listSelectionEvent.getValueIsAdjusting()) { //This prevents double events
-
-                        String selectedClass = categoryList.getSelectedValue();
-
-                        if (selectedClass != null) { //null check, because the model is cleared after a new recommendation
-                            //tags become unselected
-                            if ((selectedClass.indexOf(" ")+1) > 0) {
-                                //add both key + value in tags
-                                String keyTag = selectedClass.substring(0, selectedClass.indexOf(" "));
-                                String valueTag = selectedClass.substring(selectedClass.indexOf(" ")+1, selectedClass.length());
-                                keys.setSelectedItem(keyTag); //adding selected tags to textBoxes
-                                values.setSelectedItem(valueTag);
-                            } else {
-                                //value does not have a value, add the key tag only
-                                String keyTag = selectedClass; //test it
-                                keys.setSelectedItem(keyTag);
-                                values.setSelectedItem("");
-                            }
-                        }
-                    }
-                }
-            };
-
-            categoryList.addListSelectionListener(listSelectionListener);
-            categoryList.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            categoryList.setModel(model);
-
-            values.setEditable(true);
-            mainPanel.add(values, GBC.eop().fill());
-            if (itemToSelect != null) {
-                keys.setSelectedItem(itemToSelect);
-                if (lastAddValue != null) {
-                    values.setSelectedItem(lastAddValue);
-                }
-            }
-
-            FocusAdapter focus = addFocusAdapter(autocomplete, defaultACItemComparator);
-            // fire focus event in advance or otherwise the popup list will be too small at first
-            focus.focusGained(null);
-
-            int recentTagsToShow = PROPERTY_RECENT_TAGS_NUMBER.get();
-            if (recentTagsToShow > MAX_LRU_TAGS_NUMBER) {
-                recentTagsToShow = MAX_LRU_TAGS_NUMBER;
-            }
-
-            suggestRecentlyAddedTags(mainPanel, recentTagsToShow, focus);
-
-            mainPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            listPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            splitPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-
-            listPanel.add(recommendedClassesLabel, BorderLayout.NORTH);
-            listPanel.add(categoryList, BorderLayout.SOUTH);
-            actionsPanel.add(addAndContinueButton);
-            actionsPanel.add(modelSettingsButton);
-            actionsPanel.add(useTagsCheckBox);
-
-            recommendPanel.add(actionsPanel, BorderLayout.WEST);
-            recommendPanel.add(listPanel, BorderLayout.NORTH);
-
-            splitPanel.add(mainPanel, BorderLayout.WEST);
-            splitPanel.add(recommendPanel, BorderLayout.EAST);
-
-            setContent(splitPanel, false);
-
-            popupMenu.add(new AbstractAction(tr("Set number of recently added tags")) {
-                @Override
-                public void actionPerformed(ActionEvent e) {
-                    selectNumberOfTags();
-                }
-            });
-            JCheckBoxMenuItem rememberLastTags = new JCheckBoxMenuItem(
-                    new AbstractAction(tr("Remember last used tags after a restart")) {
-                        @Override
-                        public void actionPerformed(ActionEvent e) {
-                            boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
-                            PROPERTY_REMEMBER_TAGS.put(sel);
-                            if (sel) saveTagsIfNeeded();
-                        }
-                    });
-            rememberLastTags.setState(PROPERTY_REMEMBER_TAGS.get());
-            popupMenu.add(rememberLastTags);
-        }
-
-        private void addAndContinueButtonActionPerformed(ActionEvent evt, String selectedClass) {
-            performTagAdding();
-        }
-
-        private void selectNumberOfTags() {
-            String s = JOptionPane.showInputDialog(this, tr("Please enter the number of recently added tags to display"));
-            if (s != null) try {
-                int v = Integer.parseInt(s);
-                if (v >= 0 && v <= MAX_LRU_TAGS_NUMBER) {
-                    PROPERTY_RECENT_TAGS_NUMBER.put(v);
-                    return;
-                }
-            } catch (NumberFormatException ex) {
-                Main.warn(ex);
-            }
-            JOptionPane.showMessageDialog(this, tr("Please enter integer number between 0 and {0}", MAX_LRU_TAGS_NUMBER));
-        }
-
-        private void suggestRecentlyAddedTags(JPanel mainPanel, int tagsToShow, final FocusAdapter focus) {
-            if (!(tagsToShow > 0 && !recentTags.isEmpty()))
-                return;
-
-            mainPanel.add(new JLabel(tr("Recently added tags")), GBC.eol());
-
-            int count = 1;
-            // We store the maximum number (9) of recent tags to allow dynamic change of number of tags shown in the preferences.
-            // This implies to iterate in descending order,
-            // as the oldest elements will only be removed after we reach the maximum numbern and not the number of tags to show.
-            // However, as Set does not allow to iterate in descending order,
-            // we need to copy its elements into a List we can access in reverse order.
-            List<Tag> tags = new LinkedList<>(recentTags.keySet());
-            for (int i = tags.size()-1; i >= 0 && count <= tagsToShow; i--, count++) {
-                final Tag t = tags.get(i);
-                // Create action for reusing the tag, with keyboard shortcut Ctrl+(1-5)
-                String scKey = "properties:recent:"+count;
-                String scsKey = "properties:recent:shift:"+count;
-                Shortcut sc = Shortcut.registerShortcut(scKey, tr("Choose recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL);
-                final JosmAction action = new JosmAction(scKey, null, tr("Use this tag again"), sc, false) {
-                    @Override
-                    public void actionPerformed(ActionEvent e) {
-                        keys.setSelectedItem(t.getKey());
-                        // fix #7951, #8298 - update list of values before setting value (?)
-                        focus.focusGained(null);
-                        values.setSelectedItem(t.getValue());
-                    }
-                };
-                Shortcut scs = Shortcut.registerShortcut(scsKey, tr("Apply recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL_SHIFT);
-                final JosmAction actionShift = new JosmAction(scsKey, null, tr("Use this tag again"), scs, false) {
-                    @Override
-                    public void actionPerformed(ActionEvent e) {
-                        action.actionPerformed(null);
-                        performTagAdding();
-                    }
-                };
-                recentTagsActions.add(action);
-                recentTagsActions.add(actionShift);
-                disableTagIfNeeded(t, action);
-                // Find and display icon
-                ImageIcon icon = MapPaintStyles.getNodeIcon(t, false); // Filters deprecated icon
-                if (icon == null) {
-                    // If no icon found in map style look at presets
-                    Map<String, String> map = new HashMap<>();
-                    map.put(t.getKey(), t.getValue());
-                    // If still nothing display an empty icon
-                    if (icon == null) {
-                        icon = new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB));
-                    }
-                }
-                GridBagConstraints gbc = new GridBagConstraints();
-                gbc.ipadx = 5;
-                mainPanel.add(new JLabel(action.isEnabled() ? icon : GuiHelper.getDisabledIcon(icon)), gbc);
-                // Create tag label
-                final String color = action.isEnabled() ? "" : "; color:gray";
-                final JLabel tagLabel = new JLabel("<html>"
-                        + "<style>td{border:1px solid gray; font-weight:normal"+color+"}</style>"
-                        + "<table><tr><td>" + XmlWriter.encode(t.toString(), true) + "</td></tr></table></html>");
-                if (action.isEnabled()) {
-                    // Register action
-                    mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), scKey);
-                    mainPanel.getActionMap().put(scKey, action);
-                    mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(scs.getKeyStroke(), scsKey);
-                    mainPanel.getActionMap().put(scsKey, actionShift);
-                    // Make the tag label clickable and set tooltip to the action description (this displays also the keyboard shortcut)
-                    tagLabel.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
-                    tagLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
-                    tagLabel.addMouseListener(new MouseAdapter() {
-                        @Override
-                        public void mouseClicked(MouseEvent e) {
-                            action.actionPerformed(null);
-                            // add tags and close window on double-click
-
-                            if (e.getClickCount() > 1) {
-                                buttonAction(0, null); // emulate OK click and close the dialog
-                            }
-                            // add tags on Shift-Click
-                            if (e.isShiftDown()) {
-                                performTagAdding();
-                            }
-                        }
-                    });
-                } else {
-                    // Disable tag label
-                    tagLabel.setEnabled(false);
-                    // Explain in the tooltip why
-                    tagLabel.setToolTipText(tr("The key ''{0}'' is already used", t.getKey()));
-                }
-                // Finally add label to the resulting panel
-                JPanel tagPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
-                tagPanel.add(tagLabel);
-                mainPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));
-            }
-        }
-
-        public void destroyActions() {
-            for (JosmAction action : recentTagsActions) {
-                action.destroy();
-            }
-        }
-
-        /**
-         * Read tags from comboboxes and add it to all selected objects
-         */
-        public final void performTagAdding() {
-            String key = Tag.removeWhiteSpaces(keys.getEditor().getItem().toString());
-            String value = Tag.removeWhiteSpaces(values.getEditor().getItem().toString());
-            if (key.isEmpty() || value.isEmpty()) return;
-            for (OsmPrimitive osm: sel) {
-                String val = osm.get(key);
-                if (val != null && !val.equals(value)) {
-                    if (!warnOverwriteKey(tr("You changed the value of ''{0}'' from ''{1}'' to ''{2}''.", key, val, value),
-                            "overwriteAddKey"))
-                        return;
-                    break;
-                }
-            }
-            lastAddKey = key;
-            lastAddValue = value;
-            recentTags.put(new Tag(key, value), null);
-            AutoCompletionManager.rememberUserInput(key, value, false);
-            commandCount++;
-            Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, value));
-            changedKey = key;
-        }
-
-        public void undoAllTagsAdding() {
-            Main.main.undoRedo.undo(commandCount);
-        }
-
-        private void disableTagIfNeeded(final Tag t, final JosmAction action) {
-            // Disable action if its key is already set on the object (the key being absent from the keys list for this reason
-            // performing this action leads to autocomplete to the next key (see #7671 comments)
-            for (int j = 0; j < tagData.getRowCount(); ++j) {
-                if (t.getKey().equals(tagData.getValueAt(j, 0))) {
-                    action.setEnabled(false);
-                    break;
-                }
-            }
-        }
-
-        private void loadSVMmodel() {
-            File modelDirectory = new File(MODEL_PATH);
-            File modelFile;
-            if (useCombinedModel) {
-                if (filesAndWeights.isEmpty()) {
-                    System.out.println("No models selected! Loading defaults..");
-                    if (modelWithClasses) {
-                        System.out.println("Using default/last model with classes: " + modelDirectory.getAbsolutePath() + "/model_with_classes");
-                        modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
-                        try {
-                            System.out.println("try to load model: " + modelFile.getAbsolutePath());
-                            modelSVM = Model.load(modelFile);
-                            System.out.println("model loaded!");
-
-                        } catch (IOException ex) {
-                            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-                        modelSVMLabelSize = modelSVM.getLabels().length;
-                        modelSVMLabels = modelSVM.getLabels();
-                    } else {
-                        System.out.println("Using default/last model without classes: " + modelDirectory.getAbsolutePath() + "/best_model");
-                        modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
-                        try {
-                            System.out.println("try to load model: " + modelFile.getAbsolutePath());
-                            modelSVM = Model.load(modelFile);
-                            System.out.println("model loaded!");
-
-                        } catch (IOException ex) {
-                            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-                        modelSVMLabelSize = modelSVM.getLabels().length;
-                        modelSVMLabels = modelSVM.getLabels();
-                    }
-                }
-                if (modelWithClasses) { //check filenames to define if model with classes is selected
-                    System.out.println("Using combined model with classes");
-                    useCombinedSVMmodels(sel, true);
-                } else {
-                    System.out.println("Using combined model without classes");
-                    useCombinedSVMmodels(sel, false);
-                }
-            } else if (useCustomSVMModel) {
-                System.out.println("custom path: " + customSVMModelPath);
-                File checkExistance = new File(customSVMModelPath);
-                if (checkExistance.exists() && checkExistance.isFile()) {
-                    if (modelWithClasses) {
-                        System.out.println("Using custom model with classes: ");
-                        if (customSVMModelPath.endsWith(".0")) {
-                            String customSVMModelPathWithClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".1";
-
-                            modelFile = new File(customSVMModelPathWithClasses);
-                            System.out.println(customSVMModelPathWithClasses);
-                        } else {
-                            modelFile = new File(customSVMModelPath);
-                        }
-                    } else {
-                        System.out.println("Using custom model without classes");
-                        if (customSVMModelPath.endsWith(".1")) {
-                            String customSVMModelPathWithoutClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".0";
-                            modelFile = new File(customSVMModelPathWithoutClasses);
-                            System.out.println(customSVMModelPathWithoutClasses);
-                        } else {
-                            modelFile = new File(customSVMModelPath);
-                        }
-                    }
-                    try {
-                        System.out.println("try to load model: " + modelFile.getAbsolutePath());
-                        modelSVM = Model.load(modelFile);
-                        System.out.println("model loaded!");
-
-                    } catch (IOException ex) {
-                        Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
-                    }
-                    modelSVMLabelSize = modelSVM.getLabels().length;
-                    modelSVMLabels = modelSVM.getLabels();
-
-                } else {
-                    //user chose to use a custom model, but did not provide a path to a model:
-                    if (modelWithClasses) {
-                        System.out.println("Using default/last model with classes");
-                        modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
-                    } else {
-                        System.out.println("Using default/last model without classes");
-                        modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
-                    }
-
-                    try {
-                        System.out.println("try to load model: " + modelFile.getAbsolutePath());
-                        modelSVM = Model.load(modelFile);
-                        System.out.println("model loaded!");
-
-                    } catch (IOException ex) {
-                        Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
-                    }
-                    modelSVMLabelSize = modelSVM.getLabels().length;
-                    modelSVMLabels = modelSVM.getLabels();
-
-                }
-            } else {
-                if (modelWithClasses) {
-                    System.out.println("Using default/last model with classes");
-                    modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
-                } else {
-                    System.out.println("Using default/last model without classes");
-                    modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
-                }
-
-                try {
-                    System.out.println("try to load model: " + modelFile.getAbsolutePath());
-                    modelSVM = Model.load(modelFile);
-                    System.out.println("model loaded!");
-
-                } catch (IOException ex) {
-                    Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
-                }
-                modelSVMLabelSize = modelSVM.getLabels().length;
-                modelSVMLabels = modelSVM.getLabels();
-            }
-        }
-
-        private void useCombinedSVMmodels(Collection<OsmPrimitive> sel, boolean useClassFeatures) {
-            System.out.println("The system will combine " + filesAndWeights.size() + " SVM models.");
-
-            MathTransform transform = null;
-            GeometryFactory geometryFactory = new GeometryFactory();
-            CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
-            CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
-            try {
-                transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
-
-            } catch (FactoryException ex) {
-                Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-            }
-
-            OSMWay selectedInstance;
-            List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
-            OsmPrimitive s;
-
-            //get a simple selection
-            if (!osmPrimitiveSelection.isEmpty()) {
-                s = osmPrimitiveSelection.get(0);
-            } else {
-                return;
-            }
-
-            selectedInstance = new OSMWay();
-            for (Way selectedWay : s.getDataSet().getSelectedWays()) {
-                List<Node> selectedWayNodes = selectedWay.getNodes();
-                for (Node node : selectedWayNodes) {
-                    node.getCoor();
-                    if (node.isLatLonKnown()) {
-                        double lat = node.getCoor().lat();
-                        double lon = node.getCoor().lon();
-
-                        Coordinate sourceCoordinate = new Coordinate(lon, lat);
-                        Coordinate targetGeometry = null;
-                        try {
-                            targetGeometry = JTS.transform(sourceCoordinate, null, transform);
-                        } catch (MismatchedDimensionException | TransformException ex) {
-                            Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-
-                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-                        selectedInstance.addNodeGeometry(geom);
-                    }
-                }
-            }
-            Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
-            if ((selectedInstance.getNodeGeometries().size() > 3) &&
-                    selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
-                            .get(selectedInstance.getNodeGeometries().size()-1))) {
-                //checks if the beginning and ending node are the same and the number of nodes are more than 3.
-                //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
-                LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
-                Polygon poly = new Polygon(linear, null, geometryFactory);
-                selectedInstance.setGeometry(poly);
-
-                System.out.println("\n\npolygon");
-            } else if (selectedInstance.getNodeGeometries().size() > 1) {
-                //it is an open geometry with more than one nodes, make it linestring
-                System.out.println("\n\nlinestring");
-                LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
-                selectedInstance.setGeometry(lineString);
-            } else { //we assume all the rest geometries are points
-                System.out.println("\n\npoint");
-                Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
-                selectedInstance.setGeometry(point);
-            }
-
-            Map<String, String> selectedTags = s.getInterestingTags();
-            selectedInstance.setAllTags(selectedTags);
-
-            //construct vector
-            if (selectedInstance != null) {
-                int id;
-
-                OSMClassification classifier = new OSMClassification();
-                classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-
-                if (useClassFeatures) {
-                    ClassFeatures classFeatures = new ClassFeatures();
-                    classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-                    id = 1422;
-                } else {
-                    id = 1;
-                }
-
-                GeometryFeatures geometryFeatures = new GeometryFeatures(id);
-                geometryFeatures.createGeometryFeatures(selectedInstance);
-                id = geometryFeatures.getLastID();
-                TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
-                textualFeatures.createTextualFeatures(selectedInstance);
-
-                List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
-
-                FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
-
-                int i = 0;
-                for (FeatureNode featureNode : featureNodeList) {
-                    featureNodeArray[i] = featureNode;
-                    i++;
-                }
-                FeatureNode[] testInstance2 = featureNodeArray;
-
-                //compute prediction list for every model
-                int[] ranks = new int[10];
-
-                for (int l = 0; l < 10; l++) {
-                    ranks[l] = 10-l; //init from 10 to 1
-                }
-
-                Map<String, Double> scoreMap = new HashMap<>();
-
-                Map<File, Double> alignedFilesAndWeights = getAlignedModels(filesAndWeights);
-
-                for (File modelFile : alignedFilesAndWeights.keySet()) {
-
-                    try {
-                        modelSVM = Model.load(modelFile);
-                    } catch (IOException ex) {
-                        Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
-                    }
-                    modelSVMLabelSize = modelSVM.getLabels().length;
-                    modelSVMLabels = modelSVM.getLabels();
-
-                    Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
-                    for (int h = 0; h < modelSVMLabelSize; h++) {
-                        mapLabelsToIDs.put(modelSVMLabels[h], h);
-                    }
-                    double[] scores = new double[modelSVMLabelSize];
-                    Linear.predictValues(modelSVM, testInstance2, scores);
-
-                    Map<Double, Integer> scoresValues = new HashMap<>();
-                    for (int h = 0; h < scores.length; h++) {
-                        scoresValues.put(scores[h], h);
-                    }
-
-                    Arrays.sort(scores);
-                    int predicted1 = modelSVMLabels[scoresValues.get(scores[scores.length-1])];
-                    int predicted2 = modelSVMLabels[scoresValues.get(scores[scores.length-2])];
-                    int predicted3 = modelSVMLabels[scoresValues.get(scores[scores.length-3])];
-                    int predicted4 = modelSVMLabels[scoresValues.get(scores[scores.length-4])];
-                    int predicted5 = modelSVMLabels[scoresValues.get(scores[scores.length-5])];
-                    int predicted6 = modelSVMLabels[scoresValues.get(scores[scores.length-6])];
-                    int predicted7 = modelSVMLabels[scoresValues.get(scores[scores.length-7])];
-                    int predicted8 = modelSVMLabels[scoresValues.get(scores[scores.length-8])];
-                    int predicted9 = modelSVMLabels[scoresValues.get(scores[scores.length-9])];
-                    int predicted10 = modelSVMLabels[scoresValues.get(scores[scores.length-10])];
-
-                    String[] predictedTags = new String[10];
-                    for (Map.Entry<String, Integer> entry : mapperWithIDs.entrySet()) {
-
-                        if (entry.getValue().equals(predicted1)) {
-                            predictedTags[0] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted2)) {
-                            predictedTags[1] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted3)) {
-                            predictedTags[2] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted4)) {
-                            predictedTags[3] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted5)) {
-                            predictedTags[4] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted6)) {
-                            predictedTags[5] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted7)) {
-                            predictedTags[6] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted8)) {
-                            predictedTags[7] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted9)) {
-                            predictedTags[8] = entry.getKey();
-                        } else if (entry.getValue().equals(predicted10)) {
-                            predictedTags[9] = entry.getKey();
-                        }
-                    }
-                    //clearing model, to add the new computed classes in jlist
-                    model.clear();
-                    for (Map.Entry<String, String> tag : mappings.entrySet()) {
-
-                        for (int k = 0; k < 10; k++) {
-                            if (tag.getValue().equals(predictedTags[k])) {
-                                predictedTags[k] = tag.getKey();
-                                model.addElement(tag.getKey());
-                            }
-                        }
-                    }
-                    System.out.println("combined, predicted classes: " + Arrays.toString(predictedTags));
-
-                    for (int r = 0; r < ranks.length; r++) {
-                        String predictedTag = predictedTags[r];
-                        Double currentWeight = alignedFilesAndWeights.get(modelFile);
-                        double finalRank = ranks[r]*currentWeight;
-
-                        if (scoreMap.containsKey(predictedTag)) {
-                            Double scoreToAdd = scoreMap.get(predictedTag);
-                            scoreMap.put(predictedTag, finalRank+scoreToAdd);
-                        } else {
-                            scoreMap.put(predictedTag, finalRank);
-                        }
-                        //add final weight - predicted tag
-                    }
-                } //files iter
-                model.clear();
-                List<Double> scoresList = new ArrayList<>(scoreMap.values());
-                Collections.sort(scoresList, Collections.reverseOrder());
-
-                for (Double sco : scoresList) {
-                    if (model.size() > 9) {
-                        break;
-                    }
-                    for (Map.Entry<String, Double> scoreEntry : scoreMap.entrySet()) {
-                        if (scoreEntry.getValue().equals(sco)) {
-                            model.addElement(scoreEntry.getKey());
-                        }
-                    }
-                }
-            }
-        }
-
-        private void createOSMObject(Collection<OsmPrimitive> sel) {
-
-            MathTransform transform = null;
-            GeometryFactory geometryFactory = new GeometryFactory();
-            CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
-            CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
-            try {
-                transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
-
-            } catch (FactoryException ex) {
-                Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-            }
-
-            //fire an error to the user if he has multiple selection from map
-
-            //we consider simple (one instance) selection, so we get the first of the sel list
-
-            OSMWay selectedInstance;
-            List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
-            OsmPrimitive s;
-
-            //get a simple selection
-            if (!osmPrimitiveSelection.isEmpty()) {
-                s = osmPrimitiveSelection.get(0);
-            } else {
-                return;
-            }
-
-            selectedInstance = new OSMWay();
-            for (Way selectedWay : s.getDataSet().getSelectedWays()) {
-                List<Node> selectedWayNodes = selectedWay.getNodes();
-                for (Node node : selectedWayNodes) {
-                    node.getCoor();
-                    if (node.isLatLonKnown()) {
-                        double lat = node.getCoor().lat();
-                        double lon = node.getCoor().lon();
-
-                        Coordinate sourceCoordinate = new Coordinate(lon, lat);
-                        Coordinate targetGeometry = null;
-                        try {
-                            targetGeometry = JTS.transform(sourceCoordinate, null, transform);
-                        } catch (MismatchedDimensionException | TransformException ex) {
-                            Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-
-                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-                        selectedInstance.addNodeGeometry(geom);
-                    }
-                }
-            }
-            Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
-
-            System.out.println("number of nodes: " + selectedInstance.getNodeGeometries().size());
-
-            if ((selectedInstance.getNodeGeometries().size() > 3) &&
-                    selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
-                            .get(selectedInstance.getNodeGeometries().size()-1))) {
-                //checks if the beginning and ending node are the same and the number of nodes are more than 3.
-                //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
-                LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
-                Polygon poly = new Polygon(linear, null, geometryFactory);
-                selectedInstance.setGeometry(poly);
-
-                System.out.println("\n\npolygon");
-            } else if (selectedInstance.getNodeGeometries().size() > 1) {
-                //it is an open geometry with more than one nodes, make it linestring
-                System.out.println("\n\nlinestring");
-                LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
-                selectedInstance.setGeometry(lineString);
-            } else { //we assume all the rest geometries are points
-                System.out.println("\n\npoint");
-                Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
-                selectedInstance.setGeometry(point);
-            }
-
-            Map<String, String> selectedTags = s.getInterestingTags();
-            selectedInstance.setAllTags(selectedTags);
-
-            //construct vector here
-            if (selectedInstance != null) {
-                int id;
-                if (mappings == null) {
-                    System.out.println("null mappings ERROR");
-                }
-
-                OSMClassification classifier = new OSMClassification();
-                classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-
-                if (modelWithClasses) {
-                    ClassFeatures classFeatures = new ClassFeatures();
-                    classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-                    id = 1422;
-                } else {
-                    id = 1;
-                }
-
-                GeometryFeatures geometryFeatures = new GeometryFeatures(id);
-                geometryFeatures.createGeometryFeatures(selectedInstance);
-                id = geometryFeatures.getLastID();
-                TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
-                textualFeatures.createTextualFeatures(selectedInstance);
-
-                List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
-                System.out.println(featureNodeList);
-
-                FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
-
-                int i = 0;
-                for (FeatureNode featureNode : featureNodeList) {
-                    featureNodeArray[i] = featureNode;
-                    i++;
-                }
-                FeatureNode[] testInstance2 = featureNodeArray;
-
-                Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
-                for (int h = 0; h < modelSVMLabelSize; h++) {
-                    mapLabelsToIDs.put(modelSVMLabels[h], h);
-                }
-
-                double[] scores = new double[modelSVMLabelSize];
-                Linear.predictValues(modelSVM, testInstance2, scores);
-
-                Map<Double, Integer> scoresValues = new HashMap<>();
-                for (int h = 0; h < scores.length; h++) {
-                    scoresValues.put(scores[h], h);
-                }
-
-                Arrays.sort(scores);
-
-                int[] preds = new int[RECOMMENDATIONS_SIZE];
-                for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
-                    preds[p] = modelSVMLabels[scoresValues.get(scores[scores.length-(p+1)])];
-                }
-                String[] predictedTags2 = new String[RECOMMENDATIONS_SIZE];
-
-                for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
-                    if (idsWithMappings.containsKey(preds[p])) {
-                        predictedTags2[p] = idsWithMappings.get(preds[p]);
-                    }
-                }
-
-                //clearing model, to add the new computed classes in jlist
-                model.clear();
-                for (Map.Entry<String, String> tag : mappings.entrySet()) {
-                    for (int k = 0; k < 10; k++) {
-                        if (tag.getValue().equals(predictedTags2[k])) {
-                            predictedTags2[k] = tag.getKey();
-                            model.addElement(tag.getKey());
-                        }
-                    }
-                }
-                System.out.println("Optimized - create OSMObject, predicted classes: " + Arrays.toString(predictedTags2));
-            }
-        }
-
-        private void parseTagsMappedToClasses() {
-
-            InputStream tagsToClassesMapping = TrainWorker.class.getResourceAsStream("/resources/files/Map");
-            Mapper mapper = new Mapper();
-            try {
-                mapper.parseFile(tagsToClassesMapping);
-
-            } catch (FileNotFoundException ex) {
-                Logger.getLogger(Mapper.class.getName()).log(Level.SEVERE, null, ex);
-            }
-            mappings = mapper.getMappings();
-            mapperWithIDs = mapper.getMappingsWithIDs();
-            idsWithMappings = mapper.getIDsWithMappings();
-        }
-
-        private void loadTextualList(File textualListFile) {
-
-            Scanner input = null;
-
-            try {
-                input = new Scanner(textualListFile);
-            } catch (FileNotFoundException ex) {
-                Main.warn(ex);
-            }
-            while (input.hasNext()) {
-                String nextLine = input.nextLine();
-                textualList.add(nextLine);
-            }
-            System.out.println("Textual List parsed from file successfully." + textualList);
-        }
-
-        private void loadDefaultTextualList() {
-
-            InputStream textualListStream = TrainWorker.class.getResourceAsStream("/resources/files/textualList.txt");
-            TextualStatistics textualStatistics = new TextualStatistics();
-            textualStatistics.parseTextualList(textualListStream);
-            textualList = textualStatistics.getTextualList();
-            System.out.println("Default Textual List parsed from file successfully." + textualList);
-        }
-
-        private void loadOntology() {
-            InputStream ontologyStream = TrainWorker.class.getResourceAsStream("/resources/files/owl.xml");
-            Ontology ontology = new Ontology(ontologyStream);
-            indirectClasses = ontology.getIndirectClasses();
-            indirectClassesWithIDs = ontology.getIndirectClassesIDs();
-        }
-
-        private Map<File, Double> getAlignedModels(Map<File, Double> filesAndWeights) {
-            Map<File, Double> alignedFilesAndWeights = new HashMap<>();
-            if (modelWithClasses) {
-                for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
-                    String absolutePath = entry.getKey().getAbsolutePath();
-                    if (absolutePath.endsWith(".0")) {
-                        String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".1";
-                        File alignedFile = new File(newPath);
-                        if (alignedFile.exists()) {
-                            alignedFilesAndWeights.put(alignedFile, entry.getValue());
-                        }
-                    } else {
-                        alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
-                    }
-                }
-            } else {
-                for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
-                    String absolutePath = entry.getKey().getAbsolutePath();
-                    if (absolutePath.endsWith(".1")) {
-                        String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".0";
-                        File alignedFile = new File(newPath);
-                        if (alignedFile.exists()) {
-                            alignedFilesAndWeights.put(alignedFile, entry.getValue());
-                        }
-                    } else {
-                        alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
-                    }
-                }
-            }
-            return alignedFilesAndWeights;
-        }
-    }
+			 */
+			buildUserHistoryPanelGroupLayout();
+
+			configPanel.add(inputPanel, BorderLayout.NORTH);
+			configPanel.add(userHistoryPanel, BorderLayout.EAST);
+			configPanel.add(paramPanel, BorderLayout.WEST);
+			configPanel.add(southPanel, BorderLayout.SOUTH);
+
+			userHistoryPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
+					.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "Train by user History"));
+			paramPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
+					.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "SVM Configuration"));
+			inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+			configPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+
+			mainPanel.add(configPanel, BorderLayout.NORTH);
+			mainPanel.add(startTrainingButton, BorderLayout.CENTER);
+			mainPanel.add(trainingProgressBar, BorderLayout.SOUTH);
+
+			AutoCompletionManager autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
+			List<AutoCompletionListItem> keyList = autocomplete.getKeys();
+			Collections.sort(keyList, defaultACItemComparator);
+
+			setContent(mainPanel, false);
+		}
+
+		private void buildInputPanelGroupLayout(JPanel inputPanel) {
+			GroupLayout inputGroupLayout = new GroupLayout(inputPanel);
+			inputPanel.setLayout(inputGroupLayout);
+			inputGroupLayout.setAutoCreateGaps(true);
+			inputGroupLayout.setAutoCreateContainerGaps(true);
+
+			GroupLayout.SequentialGroup inputHorGroup = inputGroupLayout.createSequentialGroup();
+			inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileLabel).
+					addComponent(inputFileErrorMessageLabel));
+			inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileField));
+			inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(fileBrowseButton));
+			inputGroupLayout.setHorizontalGroup(inputHorGroup);
+
+			GroupLayout.SequentialGroup inputVerGroup = inputGroupLayout.createSequentialGroup();
+			inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).addComponent(inputFileLabel).
+					addComponent(inputFileField).addComponent(fileBrowseButton));
+			inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).
+					addComponent(inputFileErrorMessageLabel));
+			inputGroupLayout.setVerticalGroup(inputVerGroup);
+		}
+
+		private void buildParamPanelGroupLayout(JPanel paramPanel) {
+			GroupLayout paramGroupLayout = new GroupLayout(paramPanel);
+			paramPanel.setLayout(paramGroupLayout);
+			paramGroupLayout.setAutoCreateGaps(true);
+			paramGroupLayout.setAutoCreateContainerGaps(true);
+
+			GroupLayout.SequentialGroup paramHorGroup = paramGroupLayout.createSequentialGroup();
+			paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(topKButton).
+					addComponent(frequencyButton).addComponent(cParameterCheckBox));
+			paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cParameterField).
+					addComponent(topKField).addComponent(frequencyField));
+			paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cErrorMessageLabel).
+					addComponent(topKErrorMessageLabel).addComponent(frequencyErrorMessageLabel));
+			paramGroupLayout.setHorizontalGroup(paramHorGroup);
+
+			GroupLayout.SequentialGroup paramVerGroup = paramGroupLayout.createSequentialGroup();
+			paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
+					addComponent(cParameterCheckBox).addComponent(cParameterField).addComponent(cErrorMessageLabel));
+			paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).addComponent(topKButton).
+					addComponent(topKField).addComponent(topKErrorMessageLabel));
+			paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
+					addComponent(frequencyButton).addComponent(frequencyField).addComponent(frequencyErrorMessageLabel));
+			paramGroupLayout.setVerticalGroup(paramVerGroup);
+		}
+
+		private void buildUserHistoryPanelGroupLayout() {
+			GroupLayout userHistoryGroupLayout = new GroupLayout(userHistoryPanel);
+			userHistoryPanel.setLayout(userHistoryGroupLayout);
+			userHistoryGroupLayout.setAutoCreateGaps(true);
+			userHistoryGroupLayout.setAutoCreateContainerGaps(true);
+			userHistoryGroupLayout.linkSize(SwingConstants.HORIZONTAL, userNameField, daysLabel, daysField);
+
+			GroupLayout.SequentialGroup userHistoryHorGroup = userHistoryGroupLayout.createSequentialGroup();
+
+			userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameLabel)
+					.addComponent(byAreaRadioButton).addComponent(byTimeRadioButton));
+			userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameField)
+					.addComponent(daysLabel));
+			userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(daysField));
+			userHistoryGroupLayout.setHorizontalGroup(userHistoryHorGroup);
+
+			GroupLayout.SequentialGroup userHistoryVerGroup = userHistoryGroupLayout.createSequentialGroup();
+			userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
+					addComponent(userNameLabel).addComponent(userNameField));
+			userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
+					addComponent(byAreaRadioButton));
+			userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
+					addComponent(byTimeRadioButton).addComponent(daysLabel).addComponent(daysField));
+			userHistoryGroupLayout.setVerticalGroup(userHistoryVerGroup);
+		}
+
+		private void inputFileChooserButtonActionPerformed(ActionEvent evt) {
+			try {
+				final File file = new File(inputFileField.getText());
+				final JFileChooser fileChooser = new JFileChooser(file);
+
+				final int returnVal = fileChooser.showOpenDialog(this);
+				if (returnVal == JFileChooser.APPROVE_OPTION) {
+					inputFileField.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}
+			} catch (RuntimeException ex) {
+				Logging.warn(ex);
+			}
+		}
+
+		private void acceptConfigButtonActionPerformed(ActionEvent evt) {
+			//parse values
+			inputFileValue = inputFileField.getText();
+
+			if (!new File(inputFileValue).exists()) {
+				inputFileErrorMessageLabel.setText("OSM file does not exist");
+				resetConfigButtonActionPerformed();
+				return;
+			}
+
+			if (cParameterCheckBox.isSelected()) {
+				String c = cParameterField.getText();
+				try {
+					cParameterValue = Double.parseDouble(c.replace(",", "."));
+					cErrorMessageLabel.setText("");
+				} catch (NumberFormatException ex) {
+					cErrorMessageLabel.setText("Must be a number!");
+					System.out.println("c must be a number!" + ex); //make empty textLabel beside c param to notify errors
+					resetConfigButtonActionPerformed();
+					return;
+				}
+				crossValidateFlag = false;
+			} else {
+				crossValidateFlag = true;
+			}
+
+			if (topKButton.isSelected()) {
+				String k = topKField.getText();
+				try {
+					topKvalue = Integer.parseInt(k);
+					topKErrorMessageLabel.setText("");
+				} catch (NumberFormatException ex) {
+					topKErrorMessageLabel.setText("Must be an Integer!");
+					resetConfigButtonActionPerformed();
+					return;
+				}
+			} else {
+				String f = frequencyField.getText();
+				try {
+					frequencyValue = Integer.parseInt(f);
+					frequencyErrorMessageLabel.setText("");
+				} catch (NumberFormatException ex) {
+					frequencyErrorMessageLabel.setText("Must be an Integer!");
+					resetConfigButtonActionPerformed();
+					return;
+				}
+			}
+
+			if (trainFromUserCheckBox.isSelected()) {
+				usernameValue = userNameField.getText();
+				if (byTimeRadioButton.isSelected()) {
+					try {
+						daysValue = Integer.parseInt(daysField.getText());
+					} catch (NumberFormatException ex) {
+						daysField.setText("Integer!");
+						Logging.warn(ex);
+					}
+				}
+
+				userHistoryPanel.setEnabled(false);
+				byAreaRadioButton.setEnabled(false);
+				byTimeRadioButton.setEnabled(false);
+				userNameLabel.setEnabled(false);
+				userNameField.setEnabled(false);
+				daysLabel.setEnabled(false);
+				daysField.setEnabled(false);
+			}
+
+			System.out.println("Running configuration:" + "\nC parameter: " + cParameterValue +" \ntopK: " + topKvalue
+					+ "\nMax Frequency: " + frequencyValue + "\nCross Validate?: " + crossValidateFlag);
+
+			trainFromUserCheckBox.setEnabled(false);
+			inputFileField.setEditable(false);
+			cParameterField.setEditable(false);
+			topKField.setEditable(false);
+			frequencyField.setEditable(false);
+			cParameterCheckBox.setEnabled(false);
+			topKButton.setEnabled(false);
+			frequencyButton.setEnabled(false);
+			acceptConfigButton.setEnabled(false);
+			fileBrowseButton.setEnabled(false);
+		}
+
+		private void resetConfigButtonActionPerformed() {
+			if (trainWorker != null) {
+				try {
+					trainWorker.cancel(true);
+				} catch (CancellationException ex) {
+					startTrainingButton.setEnabled(true);
+					System.out.println(ex);
+				}
+			}
+			if (userDataExtractAndTrainWorker != null) {
+				try {
+					userDataExtractAndTrainWorker.cancel(true);
+				} catch (CancellationException ex) {
+					startTrainingButton.setEnabled(true);
+					System.out.println(ex);
+				}
+			}
+			inputFileField.setEditable(true);
+			cParameterField.setEditable(true);
+			topKField.setEditable(true);
+			frequencyField.setEditable(true);
+			cParameterCheckBox.setEnabled(true);
+			topKButton.setEnabled(true);
+			frequencyButton.setEnabled(true);
+			acceptConfigButton.setEnabled(true);
+			fileBrowseButton.setEnabled(true);
+			trainFromUserCheckBox.setEnabled(true);
+
+			if (trainFromUserCheckBox.isSelected()) {
+				userHistoryPanel.setEnabled(true);
+				byAreaRadioButton.setEnabled(true);
+				byTimeRadioButton.setEnabled(true);
+				userNameLabel.setEnabled(true);
+				userNameField.setEnabled(true);
+				daysLabel.setEnabled(true);
+				daysField.setEnabled(true);
+			}
+		}
+
+		private void startTraining() {
+			startTrainingButton.setEnabled(false);
+
+			if (trainFromUserCheckBox.isSelected()) { //if user training. train by area or days
+				EventQueue.invokeLater(new Runnable() {
+					@Override
+					public void run() {
+
+						userDataExtractAndTrainWorker = new UserDataExtractAndTrainWorker(inputFileValue, usernameValue, daysValue,
+								byAreaRadioButton.isSelected(), crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
+								topKButton.isSelected(), languageDetector);
+
+						userDataExtractAndTrainWorker.addPropertyChangeListener(new PropertyChangeListener() {
+							@Override
+							public void propertyChange(PropertyChangeEvent evt) {
+								if ("progress".equals(evt.getPropertyName())) {
+									int progress = (Integer) evt.getNewValue();
+									trainingProgressBar.setValue(progress);
+									if (progress == 100) {
+										startTrainingButton.setEnabled(true);
+									}
+								}
+							}
+						});
+
+						try {
+							System.out.println("executing userDataExtractAndTrainWorker Thread..");
+							userDataExtractAndTrainWorker.execute();
+						} catch (Exception ex) {
+							Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+						}
+					}
+				});
+			} else {
+				EventQueue.invokeLater(new Runnable() {
+					@Override
+					public void run() {
+						trainWorker = new TrainWorker(inputFileValue, crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
+								topKButton.isSelected(), languageDetector);
+
+						trainWorker.addPropertyChangeListener(new PropertyChangeListener() {
+							@Override
+							public void propertyChange(PropertyChangeEvent evt) {
+								if ("progress".equals(evt.getPropertyName())) {
+									int progress = (Integer) evt.getNewValue();
+									trainingProgressBar.setValue(progress);
+									if (progress == 100) {
+										startTrainingButton.setEnabled(true);
+									}
+								}
+							}
+						});
+
+						try {
+							trainWorker.execute();
+						} catch (Exception ex) {
+							Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+						}
+					}
+				});
+			}
+		}
+	}
+
+	public static final BooleanProperty PROPERTY_FIX_TAG_LOCALE =
+			new BooleanProperty("properties.fix-tag-combobox-locale", false);
+	public static final BooleanProperty PROPERTY_REMEMBER_TAGS =
+			new BooleanProperty("properties.remember-recently-added-tags", true);
+	public static final IntegerProperty PROPERTY_RECENT_TAGS_NUMBER =
+			new IntegerProperty("properties.recently-added-tags", DEFAULT_LRU_TAGS_NUMBER);
+
+	abstract static class AbstractTagsDialog extends ExtendedDialog {
+		AutoCompletingComboBox keys;
+		AutoCompletingComboBox values;
+
+		AbstractTagsDialog(Component parent, String title, String[] buttonTexts) {
+			super(parent, title, buttonTexts);
+			addMouseListener(new PopupMenuLauncher(popupMenu));
+		}
+
+		@Override
+		public void setupDialog() {
+			super.setupDialog();
+			final Dimension size = getSize();
+			// Set resizable only in width
+			setMinimumSize(size);
+			setPreferredSize(size);
+			// setMaximumSize does not work, and never worked, but still it seems not to bother Oracle to fix this 10-year-old bug
+			// https://bugs.openjdk.java.net/browse/JDK-6200438
+			// https://bugs.openjdk.java.net/browse/JDK-6464548
+
+			setRememberWindowGeometry(getClass().getName() + ".geometry",
+					WindowGeometry.centerInWindow(Main.parent, size));
+		}
+
+		@Override
+		public void setVisible(boolean visible) {
+			// Do not want dialog to be resizable in height, as its size may increase each time because of the recently added tags
+			// So need to modify the stored geometry (size part only) in order to use the automatic positioning mechanism
+			if (visible) {
+				WindowGeometry geometry = initWindowGeometry();
+				Dimension storedSize = geometry.getSize();
+				Dimension size = getSize();
+				if (!storedSize.equals(size)) {
+					if (storedSize.width < size.width) {
+						storedSize.width = size.width;
+					}
+					if (storedSize.height != size.height) {
+						storedSize.height = size.height;
+					}
+					rememberWindowGeometry(geometry);
+				}
+				if (keys != null) {
+					keys.setFixedLocale(PROPERTY_FIX_TAG_LOCALE.get());
+				}
+			}
+			super.setVisible(visible);
+		}
+
+		/**
+		 * Create a focus handling adapter and apply in to the editor component of value
+		 * autocompletion box.
+		 * @param autocomplete Manager handling the autocompletion
+		 * @param comparator Class to decide what values are offered on autocompletion
+		 * @return The created adapter
+		 */
+		protected FocusAdapter addFocusAdapter(final AutoCompletionManager autocomplete, final Comparator<AutoCompletionListItem> comparator) {
+			// get the combo box' editor component
+			JTextComponent editor = (JTextComponent) values.getEditor().getEditorComponent();
+			// Refresh the values model when focus is gained
+			FocusAdapter focus = new FocusAdapter() {
+				@Override
+				public void focusGained(FocusEvent e) {
+					String key = keys.getEditor().getItem().toString();
+
+					List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key));
+					Collections.sort(valueList, comparator);
+
+					values.setPossibleACItems(valueList);
+					values.getEditor().selectAll();
+				}
+			};
+			editor.addFocusListener(focus);
+			return focus;
+		}
+
+		protected JPopupMenu popupMenu = new JPopupMenu() {
+			JCheckBoxMenuItem fixTagLanguageCb = new JCheckBoxMenuItem(
+					new AbstractAction(tr("Use English language for tag by default")) {
+						@Override
+						public void actionPerformed(ActionEvent e) {
+							boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
+							PROPERTY_FIX_TAG_LOCALE.put(sel);
+						}
+					});
+			{
+				add(fixTagLanguageCb);
+				fixTagLanguageCb.setState(PROPERTY_FIX_TAG_LOCALE.get());
+			}
+		};
+	}
+
+	class ModelSettingsDialog extends JPanel {
+
+		private final JLabel chooseModelLabel;
+		private final JButton chooseModelButton;
+		private final JTextField chooseModelTextField;
+
+		private final DefaultListModel<String> combinationDefaultListModel = new DefaultListModel<>();
+		private final JList<String> modelCombinationList = new JList<>(combinationDefaultListModel);
+		private final JPanel modelCombinationPanel;
+		private final JPanel weightsPanel;
+		private final JCheckBox useModelCombinationCheckbox;
+		private final JButton acceptWeightsButton;
+		private final JButton resetWeightsButton;
+		private final JButton removeSelectedModelButton;
+		private Map<JTextField, String> weightFieldsAndPaths = new HashMap<>();
+		private final Map<String, Double> normalizedPathsAndWeights = new HashMap<>();
+		private final JOptionPane pane;
+		private final JDialog dlg;
+		private final JPanel mainPanel;
+		private final JPanel singleSelectionPanel;
+		private final JPanel setResetWeightsPanel;
+		private final JScrollPane combinationScrollPane;
+		private final JScrollPane singleSelectionScrollPane;
+		private final TitledBorder modelTitle;
+		private final TitledBorder weightTitle;
+		private final TitledBorder combineTitle;
+		private final Dimension singleSelectionDimension;
+		private final Dimension modelCombinationDimension;
+		private final Dimension mainPanelDimension;
+
+		ModelSettingsDialog(Collection<OsmPrimitive> sel1, final AddTagsDialog addDialog) {
+
+			loadPreviousCombinedSVMModel();
+			singleSelectionDimension = new Dimension(470, 70);
+			modelCombinationDimension = new Dimension(450, 250);
+			mainPanelDimension = new Dimension(600, 350);
+
+			//------- <NORTH of main> ---------//
+			mainPanel = new JPanel(new BorderLayout(10, 10));
+			singleSelectionPanel = new JPanel(new BorderLayout(10, 10));
+			setResetWeightsPanel = new JPanel();
+
+			chooseModelLabel = new JLabel("Choose a Model:");
+			chooseModelTextField = new JTextField();
+			chooseModelButton = new JButton("...");
+			chooseModelTextField.setText(MODEL_PATH);
+
+			singleSelectionPanel.add(chooseModelLabel, BorderLayout.NORTH);
+			singleSelectionPanel.add(chooseModelTextField, BorderLayout.WEST);
+			singleSelectionPanel.add(chooseModelButton, BorderLayout.EAST);
+
+			singleSelectionScrollPane = new JScrollPane(singleSelectionPanel);
+			singleSelectionScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+			singleSelectionScrollPane.setPreferredSize(singleSelectionDimension);
+
+			//------- </NORTH of main> ---------//
+
+			//------- <WEST of main> ---------//
+			modelCombinationList.setFixedCellHeight(20);
+			modelCombinationList.setEnabled(false);
+			modelCombinationPanel = new JPanel(new BorderLayout(10, 10));
+
+			weightsPanel = new JPanel();
+			weightsPanel.setLayout(new BoxLayout(weightsPanel, BoxLayout.Y_AXIS));
+			weightsPanel.setEnabled(false);
+
+
+			acceptWeightsButton = new JButton("Set Weights/Normalize");
+			resetWeightsButton = new JButton("Reset Weights");
+			removeSelectedModelButton = new JButton("Remove Selected");
+			setResetWeightsPanel.add(acceptWeightsButton);
+			setResetWeightsPanel.add(resetWeightsButton);
+			setResetWeightsPanel.add(removeSelectedModelButton);
+			removeSelectedModelButton.setEnabled(false);
+			acceptWeightsButton.setEnabled(false);
+			resetWeightsButton.setEnabled(false);
+
+			modelCombinationPanel.add(modelCombinationList, BorderLayout.CENTER);
+			modelCombinationPanel.add(weightsPanel, BorderLayout.EAST);
+			modelCombinationPanel.add(setResetWeightsPanel, BorderLayout.SOUTH);
+
+			combinationScrollPane = new JScrollPane(modelCombinationPanel);
+
+			combinationScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+			combinationScrollPane.setPreferredSize(modelCombinationDimension);   //new Dimension(450, 250) // w/h
+
+			//------- </WEST of main> ---------//
+
+			//------- <SOUTH of main> ---------//
+			useModelCombinationCheckbox = new JCheckBox("Combine different models?");
+
+			//------- </SOUTH of main> ---------//
+
+			//------- <Borders> ---------//
+			modelTitle = BorderFactory.createTitledBorder("Models");
+			weightTitle = BorderFactory.createTitledBorder("W");
+			combineTitle = BorderFactory.createTitledBorder("Combine Models");
+			modelCombinationList.setBorder(modelTitle);
+			weightsPanel.setBorder(weightTitle);
+
+			for (Entry<JTextField, String> entry : weightFieldsAndPaths.entrySet()) {
+				combinationDefaultListModel.addElement(entry.getValue());
+
+				JTextField weightTextField = new JTextField("0.00");
+				weightTextField.setMaximumSize(new Dimension(80, 20));
+				weightsPanel.add(entry.getKey());
+			}
+
+			//modelCombinationPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+			modelCombinationPanel.setBorder(combineTitle);
+			singleSelectionPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+			//------- </Borders> ---------//
+
+			chooseModelButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					modelChooserButtonActionPerformed(evt);
+				}
+			});
+
+			useModelCombinationCheckbox.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					userCombinationCheckboxActionPerformed(evt);
+				}
+			});
+
+			acceptWeightsButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					acceptWeightsButtonActionPerformed(evt);
+				}
+			});
+
+			resetWeightsButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					resetWeightsButtonActionPerformed(evt);
+				}
+			});
+
+			removeSelectedModelButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					removeSelectedModelButtonActionPerformed(evt);
+				}
+			});
+			mainPanel.add(singleSelectionScrollPane, BorderLayout.NORTH);
+			mainPanel.add(combinationScrollPane, BorderLayout.CENTER);
+			mainPanel.add(useModelCombinationCheckbox, BorderLayout.SOUTH);
+
+			mainPanel.setPreferredSize(mainPanelDimension);
+
+			this.add(mainPanel);
+
+			pane = new JOptionPane(this, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
+				@Override
+				public void setValue(Object newValue) {
+					super.setValue(newValue);
+					if (newValue instanceof Integer && (int) newValue == 0 && useModelCombinationCheckbox.isSelected()) {
+						System.out.println("model settings button value: " + newValue);
+						System.out.println("\nUSE COMBINED MODEL\n");
+						useCombinedModel = true;
+						useCustomSVMModel = false;
+
+						addDialog.loadSVMmodel();
+						addDialog.createOSMObject(sel);
+						saveCombinedModel();
+						dlg.setVisible(false);
+					} else if (newValue instanceof Integer && (int) newValue == -1 && useModelCombinationCheckbox.isSelected()) {
+						System.out.println("model settings button value: " + newValue);
+						useCombinedModel = false;
+						useCustomSVMModel = false;
+						System.out.println("Use combined model");
+
+						addDialog.loadSVMmodel();
+						addDialog.createOSMObject(sel);
+						dlg.setVisible(false);
+					} else if (newValue instanceof Integer && (int) newValue == 0 && !useModelCombinationCheckbox.isSelected()) {
+						System.out.println("model settings button value: " + newValue);
+						System.out.println("Don t use combined model, use custom model");
+						useCombinedModel = false;
+						useCustomSVMModel = true;
+						addDialog.loadSVMmodel();
+						addDialog.createOSMObject(sel);
+						dlg.setVisible(false);
+					} else if (newValue instanceof Integer && (int) newValue == -1 && !useModelCombinationCheckbox.isSelected()) {
+						System.out.println("model settings button value: " + newValue);
+						System.out.println("Don t use combined model, use custom model");
+						useCombinedModel = false;
+						useCustomSVMModel = false;
+						addDialog.loadSVMmodel();
+						addDialog.createOSMObject(sel);
+						dlg.setVisible(false);
+					} else if (newValue == null || newValue.equals("uninitializedValue")) {
+						System.out.println("uninitializedValue, do nothing");
+					}
+				}
+			};
+
+			dlg = pane.createDialog(Main.parent, tr("Model Settings"));
+			dlg.setVisible(true);
+		}
+
+		public void makeVisible(boolean visible) {
+			dlg.setVisible(true);
+		}
+
+		private void modelChooserButtonActionPerformed(ActionEvent evt) {
+
+			try {
+				final File file = new File(chooseModelTextField.getText());
+				final JFileChooser fileChooser = new JFileChooser(file);
+
+				final int returnVal = fileChooser.showOpenDialog(this);
+				if (returnVal == JFileChooser.APPROVE_OPTION) {
+					chooseModelTextField.setText(fileChooser.getSelectedFile().getAbsolutePath());
+					useCustomSVMModel = true;
+					customSVMModelPath = fileChooser.getSelectedFile().getAbsolutePath();
+				}
+
+				if (useModelCombinationCheckbox.isSelected()) {
+					String svmModelPath = fileChooser.getSelectedFile().getAbsolutePath();
+					String svmModelText;
+					if (System.getProperty("os.name").contains("ux")) {
+						if (svmModelPath.contains("/")) {
+							svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("/"));
+						} else {
+							svmModelText = svmModelPath;
+						}
+					} else {
+						if (svmModelPath.contains("\\")) {
+							svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("\\"));
+						} else {
+							svmModelText = svmModelPath;
+						}
+					}
+					combinationDefaultListModel.addElement(svmModelText);
+					JTextField weightTextField = new JTextField("0.00");
+					weightFieldsAndPaths.put(weightTextField, svmModelPath);
+					System.out.println("weights size: " + weightFieldsAndPaths.size());
+
+					weightTextField.setMaximumSize(new Dimension(80, 20));
+					weightsPanel.add(weightTextField);
+					//add additional textbox
+				}
+			} catch (RuntimeException ex) {
+				Logging.warn(ex);
+			}
+		}
+
+		private void userCombinationCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
+
+			if (useModelCombinationCheckbox.isSelected()) {
+				useCombinedModel = true;
+				useCustomSVMModel = false; //reseting the selected custom SVM model only here
+				removeSelectedModelButton.setEnabled(true);
+				acceptWeightsButton.setEnabled(true);
+				resetWeightsButton.setEnabled(true);
+
+				chooseModelTextField.setEnabled(false);
+				modelCombinationList.setEnabled(true);
+				weightsPanel.setEnabled(true);
+				Component[] weightPanelComponents = weightsPanel.getComponents();
+				for (Component weightPanelComponent : weightPanelComponents) {
+					weightPanelComponent.setEnabled(true);
+				}
+			} else {
+				useCombinedModel = false;
+				useCustomSVMModel = true;
+				removeSelectedModelButton.setEnabled(false);
+				acceptWeightsButton.setEnabled(false);
+				resetWeightsButton.setEnabled(false);
+
+				chooseModelTextField.setEnabled(true);
+				modelCombinationList.setEnabled(false);
+				weightsPanel.setEnabled(false);
+				Component[] weightPanelComponents = weightsPanel.getComponents();
+				for (Component weightPanelComponent : weightPanelComponents) {
+					weightPanelComponent.setEnabled(false);
+				}
+			}
+		}
+
+		private void acceptWeightsButtonActionPerformed(ActionEvent evt) {
+			int weightsCount = 0;
+			removeSelectedModelButton.setEnabled(false);
+			double weightSum = 0;
+			for (JTextField weightField : weightFieldsAndPaths.keySet()) {
+				if (weightField.getText().equals("")) {
+					weightField.setText("0.00");
+				}
+
+				try {
+					//TODO replace "," with "." to parse doubles with commas
+					Double weightValue = Double.parseDouble(weightField.getText());
+
+					weightValue = Math.abs(weightValue);
+					weightSum += weightValue;
+				} catch (NumberFormatException ex) {
+					Logging.warn(ex);
+				}
+				weightsCount++;
+			}
+
+			if (!filesAndWeights.isEmpty()) {
+				filesAndWeights.clear();
+			}
+
+			for (JTextField weightField : weightFieldsAndPaths.keySet()) {
+				try {
+					Double weightValue = Double.parseDouble(weightField.getText());
+
+					weightValue = Math.abs(weightValue)/weightSum; //normalize
+
+					if (weightSum == 0) {
+						weightValue = 1.0/weightsCount;
+					}
+
+					weightField.setText(new DecimalFormat("#.##").format(weightValue));
+					normalizedPathsAndWeights.put(weightFieldsAndPaths.get(weightField), weightValue);
+					filesAndWeights.put(new File(weightFieldsAndPaths.get(weightField)), weightValue);
+					System.out.println("normalized: " + weightFieldsAndPaths.get(weightField) + "->" + weightValue);
+					weightField.setEnabled(false);
+
+				} catch (NumberFormatException ex) {
+					Logging.warn(ex);
+				}
+			}
+
+			useCombinedModel = true;
+			useCustomSVMModel = false;
+		}
+
+		private void resetWeightsButtonActionPerformed(ActionEvent evt) {
+			removeSelectedModelButton.setEnabled(true);
+			for (JTextField weightField : weightFieldsAndPaths.keySet()) {
+				weightField.setEnabled(true);
+			}
+		}
+
+		private void removeSelectedModelButtonActionPerformed(ActionEvent evt) {
+			int index = modelCombinationList.getSelectedIndex();
+			String modelToBeRemoved = combinationDefaultListModel.get(index);
+			combinationDefaultListModel.remove(index);
+			System.out.println("model to be removed: " + modelToBeRemoved);
+
+			Iterator<Entry<JTextField, String>> it = weightFieldsAndPaths.entrySet().iterator();
+			while (it.hasNext()) {
+				Entry<JTextField, String> en = it.next();
+				if (en.getValue().equals(modelToBeRemoved)) {
+					it.remove();
+				}
+			}
+			System.out.println("model to be removed: " + modelToBeRemoved);
+
+			weightsPanel.remove(index);
+			weightsPanel.revalidate();
+			weightsPanel.repaint();
+		}
+
+		@SuppressWarnings("unchecked")
+		private void loadPreviousCombinedSVMModel() {
+			File combinedModelClassesFile = new File(combinedModelClasses);
+
+			if (combinedModelClassesFile.exists()) {
+				FileInputStream fileIn = null;
+				ObjectInputStream in = null;
+				try {
+					fileIn = new FileInputStream(combinedModelClassesFile);
+					in = new ObjectInputStream(fileIn);
+					weightFieldsAndPaths = (Map<JTextField, String>) in.readObject();
+				} catch (FileNotFoundException ex) {
+					Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+				} catch (IOException | ClassNotFoundException ex) {
+					Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+				} finally {
+					try {
+						if (in != null) {
+							in.close();
+						}
+						if (fileIn != null) {
+							fileIn.close();
+						}
+
+					} catch (IOException ex) {
+						Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+					}
+				}
+			} else {
+				try {
+					combinedModelClassesFile.createNewFile();
+				} catch (IOException ex) {
+					Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+				}
+			}
+		}
+
+		private void saveCombinedModel() {
+			try (FileOutputStream fileOut = new FileOutputStream(combinedModelClasses);
+					ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
+				out.writeObject(weightFieldsAndPaths);
+			} catch (IOException e) {
+				System.out.println("serialize error" + e);
+			}
+		}
+	}
+
+	class AddTagsDialog extends AbstractTagsDialog {
+		List<JosmAction> recentTagsActions = new ArrayList<>();
+
+		// Counter of added commands for possible undo
+		private int commandCount;
+		private final JLabel recommendedClassesLabel;
+		private final JButton modelSettingsButton;
+		private final JButton addAndContinueButton;
+		private final DefaultListModel<String> model;
+		private final JList<String> categoryList;
+		private Model modelSVM;
+		private int modelSVMLabelSize;
+		private int[] modelSVMLabels;
+		private Map<String, String> mappings;
+		private Map<String, Integer> mapperWithIDs;
+		private Map<Integer, String> idsWithMappings;
+		private List<String> textualList = new ArrayList<>();
+		private final JCheckBox useTagsCheckBox;
+		private ModelSettingsDialog modelSettingsDialog;
+		private static final int RECOMMENDATIONS_SIZE = 10;
+
+		AddTagsDialog() {
+			super(Main.parent, tr("Add value?"), new String[] {tr("OK"), tr("Cancel")});
+			setButtonIcons(new String[] {"ok", "cancel"});
+			setCancelButton(2);
+			configureContextsensitiveHelp("/Dialog/AddValue", true /* show help button */);
+			final AddTagsDialog addTagsDialog = this;
+
+			loadOntology();
+			//if the user did not train a model by running the training process
+			//the list does not exist in a file and so we load the default list from the jar.
+
+			System.out.println("path for textual: " + TEXTUAL_LIST_PATH);
+			File textualListFile = new File(TEXTUAL_LIST_PATH);
+			if (textualListFile.exists()) {
+				loadTextualList(textualListFile);
+			} else {
+				loadDefaultTextualList();
+			}
+
+			//if training process has not been performed, we use two sample SVM models, extracted from the jar
+
+			JPanel splitPanel = new JPanel(new BorderLayout(10, 10));
+			JPanel mainPanel = new JPanel(new GridBagLayout()); //original panel, will be wrapped by the splitPanel
+			JPanel recommendPanel = new JPanel(new BorderLayout(10, 10));   //will contain listPanel, action panel
+			JPanel listPanel = new JPanel(new BorderLayout(10, 10)); //class recommend label, recommendation list
+			JPanel actionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); //model selection buttons or configuration
+
+			addAndContinueButton = new JButton("Add and continue");
+			modelSettingsButton = new JButton("Model Settings");
+			useTagsCheckBox = new JCheckBox("Predict using tags");
+			recommendedClassesLabel = new JLabel("Recommended Classes:");
+
+			addAndContinueButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					String selectedClass = categoryList.getSelectedValue();
+					addAndContinueButtonActionPerformed(evt, selectedClass);
+
+					//reconstruct vector for instance and use the model that was trained with classes here
+
+					List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
+					OsmPrimitive s;
+
+					//get a simple selection
+					if (!osmPrimitiveSelection.isEmpty()) {
+						s = osmPrimitiveSelection.get(0);
+						if (s.getInterestingTags().isEmpty()) {
+							//load original model
+							modelWithClasses = false;
+							loadSVMmodel();
+							createOSMObject(sel); //create object without class features
+						} else {
+							//recommend using tags: set the checkbox selected to avoid confusing the user
+							useTagsCheckBox.setSelected(true);
+
+							if (useTagsCheckBox.isSelected()) {
+								//load model with classes
+								modelWithClasses = true;
+								loadSVMmodel();
+								createOSMObject(sel); //create object including class features
+							} else {
+								modelWithClasses = false;
+								loadSVMmodel();
+								createOSMObject(sel); //create object including class features
+							}
+						}
+					}
+				}
+			});
+
+			modelSettingsButton.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					if (modelSettingsDialog == null) {
+						System.out.println("new modelSettingsDialog");
+						modelSettingsDialog = new ModelSettingsDialog(sel, addTagsDialog);
+					} else {
+						System.out.println("set modelSettingsDialog visible");
+						modelSettingsDialog.makeVisible(true);
+					}
+				}
+			});
+
+			useTagsCheckBox.addActionListener(new java.awt.event.ActionListener() {
+				@Override
+				public void actionPerformed(java.awt.event.ActionEvent evt) {
+					List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
+					OsmPrimitive s;
+					if (!osmPrimitiveSelection.isEmpty()) {
+						s = osmPrimitiveSelection.get(0);
+						if (s.getInterestingTags().isEmpty()) {
+							//load original model
+							modelWithClasses = false;
+							loadSVMmodel();
+							createOSMObject(sel); //create object without class features
+						} else {
+							//useTagsCheckBox
+							if (useTagsCheckBox.isSelected()) {
+								//load model with classes
+								modelWithClasses = true;
+								loadSVMmodel();
+								createOSMObject(sel); //create object including class features
+							} else {
+								modelWithClasses = false;
+								loadSVMmodel();
+								createOSMObject(sel); //create object including class features
+							}
+						}
+					}
+				}
+			});
+
+			keys = new AutoCompletingComboBox();
+			values = new AutoCompletingComboBox();
+
+			mainPanel.add(new JLabel("<html>"+trn("This will change up to {0} object.",
+					"This will change up to {0} objects.", sel.size(), sel.size())
+			+"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL));
+
+			AutoCompletionManager autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
+			List<AutoCompletionListItem> keyList = autocomplete.getKeys();
+
+			AutoCompletionListItem itemToSelect = null;
+			// remove the object's tag keys from the list
+			Iterator<AutoCompletionListItem> iter = keyList.iterator();
+			while (iter.hasNext()) {
+				AutoCompletionListItem item = iter.next();
+				if (item.getValue().equals(lastAddKey)) {
+					itemToSelect = item;
+				}
+				for (int i = 0; i < tagData.getRowCount(); ++i) {
+					if (item.getValue().equals(tagData.getValueAt(i, 0))) {
+						if (itemToSelect == item) {
+							itemToSelect = null;
+						}
+						iter.remove();
+						break;
+					}
+				}
+			}
+
+			Collections.sort(keyList, defaultACItemComparator);
+			keys.setPossibleACItems(keyList);
+			keys.setEditable(true);
+
+			mainPanel.add(keys, GBC.eop().fill());
+			mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol());
+
+			model = new DefaultListModel<>();
+
+			parseTagsMappedToClasses();
+
+			List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
+			OsmPrimitive s;
+			//get a simple selection
+			if (!osmPrimitiveSelection.isEmpty()) {
+				s = osmPrimitiveSelection.get(0);
+				File modelDirectory = new File(MODEL_PATH);
+				String modelWithClassesPath = modelDirectory.getAbsolutePath() + "/model_with_classes";
+				File modelWithClassesFile = new File(modelWithClassesPath);
+				if (s.getInterestingTags().isEmpty() || !modelWithClassesFile.exists()) {
+					modelWithClasses = false;
+					loadSVMmodel(); //load original model
+					createOSMObject(sel); //create object without class features
+				} else {
+					//recommend using tags: set the checkbox selected to avoid confusing the user
+					useTagsCheckBox.setSelected(true);
+					modelWithClasses = true;
+					loadSVMmodel(); //load model with classes
+					createOSMObject(sel); //create object including class features
+				}
+			}
+
+			categoryList = new JList<>(model);
+
+			ListSelectionListener listSelectionListener = new ListSelectionListener() {
+				@Override
+				public void valueChanged(ListSelectionEvent listSelectionEvent) {
+					if (!listSelectionEvent.getValueIsAdjusting()) { //This prevents double events
+
+						String selectedClass = categoryList.getSelectedValue();
+
+						if (selectedClass != null) { //null check, because the model is cleared after a new recommendation
+							//tags become unselected
+							if ((selectedClass.indexOf(" ")+1) > 0) {
+								//add both key + value in tags
+								String keyTag = selectedClass.substring(0, selectedClass.indexOf(" "));
+								String valueTag = selectedClass.substring(selectedClass.indexOf(" ")+1, selectedClass.length());
+								keys.setSelectedItem(keyTag); //adding selected tags to textBoxes
+								values.setSelectedItem(valueTag);
+							} else {
+								//value does not have a value, add the key tag only
+								String keyTag = selectedClass; //test it
+								keys.setSelectedItem(keyTag);
+								values.setSelectedItem("");
+							}
+						}
+					}
+				}
+			};
+
+			categoryList.addListSelectionListener(listSelectionListener);
+			categoryList.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+			categoryList.setModel(model);
+
+			values.setEditable(true);
+			mainPanel.add(values, GBC.eop().fill());
+			if (itemToSelect != null) {
+				keys.setSelectedItem(itemToSelect);
+				if (lastAddValue != null) {
+					values.setSelectedItem(lastAddValue);
+				}
+			}
+
+			FocusAdapter focus = addFocusAdapter(autocomplete, defaultACItemComparator);
+			// fire focus event in advance or otherwise the popup list will be too small at first
+			focus.focusGained(null);
+
+			int recentTagsToShow = PROPERTY_RECENT_TAGS_NUMBER.get();
+			if (recentTagsToShow > MAX_LRU_TAGS_NUMBER) {
+				recentTagsToShow = MAX_LRU_TAGS_NUMBER;
+			}
+
+			suggestRecentlyAddedTags(mainPanel, recentTagsToShow, focus);
+
+			mainPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+			listPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+			splitPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+
+			listPanel.add(recommendedClassesLabel, BorderLayout.NORTH);
+			listPanel.add(categoryList, BorderLayout.SOUTH);
+			actionsPanel.add(addAndContinueButton);
+			actionsPanel.add(modelSettingsButton);
+			actionsPanel.add(useTagsCheckBox);
+
+			recommendPanel.add(actionsPanel, BorderLayout.WEST);
+			recommendPanel.add(listPanel, BorderLayout.NORTH);
+
+			splitPanel.add(mainPanel, BorderLayout.WEST);
+			splitPanel.add(recommendPanel, BorderLayout.EAST);
+
+			setContent(splitPanel, false);
+
+			popupMenu.add(new AbstractAction(tr("Set number of recently added tags")) {
+				@Override
+				public void actionPerformed(ActionEvent e) {
+					selectNumberOfTags();
+				}
+			});
+			JCheckBoxMenuItem rememberLastTags = new JCheckBoxMenuItem(
+					new AbstractAction(tr("Remember last used tags after a restart")) {
+						@Override
+						public void actionPerformed(ActionEvent e) {
+							boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
+							PROPERTY_REMEMBER_TAGS.put(sel);
+							if (sel) saveTagsIfNeeded();
+						}
+					});
+			rememberLastTags.setState(PROPERTY_REMEMBER_TAGS.get());
+			popupMenu.add(rememberLastTags);
+		}
+
+		private void addAndContinueButtonActionPerformed(ActionEvent evt, String selectedClass) {
+			performTagAdding();
+		}
+
+		private void selectNumberOfTags() {
+			String s = JOptionPane.showInputDialog(this, tr("Please enter the number of recently added tags to display"));
+			if (s != null) try {
+				int v = Integer.parseInt(s);
+				if (v >= 0 && v <= MAX_LRU_TAGS_NUMBER) {
+					PROPERTY_RECENT_TAGS_NUMBER.put(v);
+					return;
+				}
+			} catch (NumberFormatException ex) {
+				Logging.warn(ex);
+			}
+			JOptionPane.showMessageDialog(this, tr("Please enter integer number between 0 and {0}", MAX_LRU_TAGS_NUMBER));
+		}
+
+		private void suggestRecentlyAddedTags(JPanel mainPanel, int tagsToShow, final FocusAdapter focus) {
+			if (!(tagsToShow > 0 && !recentTags.isEmpty()))
+				return;
+
+			mainPanel.add(new JLabel(tr("Recently added tags")), GBC.eol());
+
+			int count = 1;
+			// We store the maximum number (9) of recent tags to allow dynamic change of number of tags shown in the preferences.
+			// This implies to iterate in descending order,
+			// as the oldest elements will only be removed after we reach the maximum numbern and not the number of tags to show.
+			// However, as Set does not allow to iterate in descending order,
+			// we need to copy its elements into a List we can access in reverse order.
+			List<Tag> tags = new LinkedList<>(recentTags.keySet());
+			for (int i = tags.size()-1; i >= 0 && count <= tagsToShow; i--, count++) {
+				final Tag t = tags.get(i);
+				// Create action for reusing the tag, with keyboard shortcut Ctrl+(1-5)
+				String scKey = "properties:recent:"+count;
+				String scsKey = "properties:recent:shift:"+count;
+				Shortcut sc = Shortcut.registerShortcut(scKey, tr("Choose recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL);
+				final JosmAction action = new JosmAction(scKey, null, tr("Use this tag again"), sc, false) {
+					@Override
+					public void actionPerformed(ActionEvent e) {
+						keys.setSelectedItem(t.getKey());
+						// fix #7951, #8298 - update list of values before setting value (?)
+						focus.focusGained(null);
+						values.setSelectedItem(t.getValue());
+					}
+				};
+				Shortcut scs = Shortcut.registerShortcut(scsKey, tr("Apply recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL_SHIFT);
+				final JosmAction actionShift = new JosmAction(scsKey, null, tr("Use this tag again"), scs, false) {
+					@Override
+					public void actionPerformed(ActionEvent e) {
+						action.actionPerformed(null);
+						performTagAdding();
+					}
+				};
+				recentTagsActions.add(action);
+				recentTagsActions.add(actionShift);
+				disableTagIfNeeded(t, action);
+				// Find and display icon
+				ImageIcon icon = MapPaintStyles.getNodeIcon(t, false); // Filters deprecated icon
+				if (icon == null) {
+					// If no icon found in map style look at presets
+					Map<String, String> map = new HashMap<>();
+					map.put(t.getKey(), t.getValue());
+					// If still nothing display an empty icon
+					if (icon == null) {
+						icon = new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB));
+					}
+				}
+				GridBagConstraints gbc = new GridBagConstraints();
+				gbc.ipadx = 5;
+				mainPanel.add(new JLabel(action.isEnabled() ? icon : GuiHelper.getDisabledIcon(icon)), gbc);
+				// Create tag label
+				final String color = action.isEnabled() ? "" : "; color:gray";
+				final JLabel tagLabel = new JLabel("<html>"
+						+ "<style>td{border:1px solid gray; font-weight:normal"+color+"}</style>"
+						+ "<table><tr><td>" + XmlWriter.encode(t.toString(), true) + "</td></tr></table></html>");
+				if (action.isEnabled()) {
+					// Register action
+					mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), scKey);
+					mainPanel.getActionMap().put(scKey, action);
+					mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(scs.getKeyStroke(), scsKey);
+					mainPanel.getActionMap().put(scsKey, actionShift);
+					// Make the tag label clickable and set tooltip to the action description (this displays also the keyboard shortcut)
+					tagLabel.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
+					tagLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+					tagLabel.addMouseListener(new MouseAdapter() {
+						@Override
+						public void mouseClicked(MouseEvent e) {
+							action.actionPerformed(null);
+							// add tags and close window on double-click
+
+							if (e.getClickCount() > 1) {
+								buttonAction(0, null); // emulate OK click and close the dialog
+							}
+							// add tags on Shift-Click
+							if (e.isShiftDown()) {
+								performTagAdding();
+							}
+						}
+					});
+				} else {
+					// Disable tag label
+					tagLabel.setEnabled(false);
+					// Explain in the tooltip why
+					tagLabel.setToolTipText(tr("The key ''{0}'' is already used", t.getKey()));
+				}
+				// Finally add label to the resulting panel
+				JPanel tagPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
+				tagPanel.add(tagLabel);
+				mainPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));
+			}
+		}
+
+		public void destroyActions() {
+			for (JosmAction action : recentTagsActions) {
+				action.destroy();
+			}
+		}
+
+		/**
+		 * Read tags from comboboxes and add it to all selected objects
+		 */
+		public final void performTagAdding() {
+			String key = Tag.removeWhiteSpaces(keys.getEditor().getItem().toString());
+			String value = Tag.removeWhiteSpaces(values.getEditor().getItem().toString());
+			if (key.isEmpty() || value.isEmpty()) return;
+			for (OsmPrimitive osm: sel) {
+				String val = osm.get(key);
+				if (val != null && !val.equals(value)) {
+					if (!warnOverwriteKey(tr("You changed the value of ''{0}'' from ''{1}'' to ''{2}''.", key, val, value),
+							"overwriteAddKey"))
+						return;
+					break;
+				}
+			}
+			lastAddKey = key;
+			lastAddValue = value;
+			recentTags.put(new Tag(key, value), null);
+			AutoCompletionManager.rememberUserInput(key, value, false);
+			commandCount++;
+			MainApplication.undoRedo.add(new ChangePropertyCommand(sel, key, value));
+			changedKey = key;
+		}
+
+		public void undoAllTagsAdding() {
+			MainApplication.undoRedo.undo(commandCount);
+		}
+
+		private void disableTagIfNeeded(final Tag t, final JosmAction action) {
+			// Disable action if its key is already set on the object (the key being absent from the keys list for this reason
+			// performing this action leads to autocomplete to the next key (see #7671 comments)
+			for (int j = 0; j < tagData.getRowCount(); ++j) {
+				if (t.getKey().equals(tagData.getValueAt(j, 0))) {
+					action.setEnabled(false);
+					break;
+				}
+			}
+		}
+
+		private void loadSVMmodel() {
+			File modelDirectory = new File(MODEL_PATH);
+			File modelFile;
+			if (useCombinedModel) {
+				if (filesAndWeights.isEmpty()) {
+					System.out.println("No models selected! Loading defaults..");
+					if (modelWithClasses) {
+						System.out.println("Using default/last model with classes: " + modelDirectory.getAbsolutePath() + "/model_with_classes");
+						modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
+						try {
+							System.out.println("try to load model: " + modelFile.getAbsolutePath());
+							modelSVM = Model.load(modelFile);
+							System.out.println("model loaded!");
+
+						} catch (IOException ex) {
+							Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+						}
+						modelSVMLabelSize = modelSVM.getLabels().length;
+						modelSVMLabels = modelSVM.getLabels();
+					} else {
+						System.out.println("Using default/last model without classes: " + modelDirectory.getAbsolutePath() + "/best_model");
+						modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
+						try {
+							System.out.println("try to load model: " + modelFile.getAbsolutePath());
+							modelSVM = Model.load(modelFile);
+							System.out.println("model loaded!");
+
+						} catch (IOException ex) {
+							Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+						}
+						modelSVMLabelSize = modelSVM.getLabels().length;
+						modelSVMLabels = modelSVM.getLabels();
+					}
+				}
+				if (modelWithClasses) { //check filenames to define if model with classes is selected
+					System.out.println("Using combined model with classes");
+					useCombinedSVMmodels(sel, true);
+				} else {
+					System.out.println("Using combined model without classes");
+					useCombinedSVMmodels(sel, false);
+				}
+			} else if (useCustomSVMModel) {
+				System.out.println("custom path: " + customSVMModelPath);
+				File checkExistance = new File(customSVMModelPath);
+				if (checkExistance.exists() && checkExistance.isFile()) {
+					if (modelWithClasses) {
+						System.out.println("Using custom model with classes: ");
+						if (customSVMModelPath.endsWith(".0")) {
+							String customSVMModelPathWithClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".1";
+
+							modelFile = new File(customSVMModelPathWithClasses);
+							System.out.println(customSVMModelPathWithClasses);
+						} else {
+							modelFile = new File(customSVMModelPath);
+						}
+					} else {
+						System.out.println("Using custom model without classes");
+						if (customSVMModelPath.endsWith(".1")) {
+							String customSVMModelPathWithoutClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".0";
+							modelFile = new File(customSVMModelPathWithoutClasses);
+							System.out.println(customSVMModelPathWithoutClasses);
+						} else {
+							modelFile = new File(customSVMModelPath);
+						}
+					}
+					try {
+						System.out.println("try to load model: " + modelFile.getAbsolutePath());
+						modelSVM = Model.load(modelFile);
+						System.out.println("model loaded!");
+
+					} catch (IOException ex) {
+						Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+					}
+					modelSVMLabelSize = modelSVM.getLabels().length;
+					modelSVMLabels = modelSVM.getLabels();
+
+				} else {
+					//user chose to use a custom model, but did not provide a path to a model:
+					if (modelWithClasses) {
+						System.out.println("Using default/last model with classes");
+						modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
+					} else {
+						System.out.println("Using default/last model without classes");
+						modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
+					}
+
+					try {
+						System.out.println("try to load model: " + modelFile.getAbsolutePath());
+						modelSVM = Model.load(modelFile);
+						System.out.println("model loaded!");
+
+					} catch (IOException ex) {
+						Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+					}
+					modelSVMLabelSize = modelSVM.getLabels().length;
+					modelSVMLabels = modelSVM.getLabels();
+
+				}
+			} else {
+				if (modelWithClasses) {
+					System.out.println("Using default/last model with classes");
+					modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
+				} else {
+					System.out.println("Using default/last model without classes");
+					modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
+				}
+
+				try {
+					System.out.println("try to load model: " + modelFile.getAbsolutePath());
+					modelSVM = Model.load(modelFile);
+					System.out.println("model loaded!");
+
+				} catch (IOException ex) {
+					Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+				}
+				modelSVMLabelSize = modelSVM.getLabels().length;
+				modelSVMLabels = modelSVM.getLabels();
+			}
+		}
+
+		private void useCombinedSVMmodels(Collection<OsmPrimitive> sel, boolean useClassFeatures) {
+			System.out.println("The system will combine " + filesAndWeights.size() + " SVM models.");
+
+			MathTransform transform = null;
+			GeometryFactory geometryFactory = new GeometryFactory();
+			CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
+			CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
+			try {
+				transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+
+			} catch (FactoryException ex) {
+				Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+			}
+
+			OSMWay selectedInstance;
+			List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
+			OsmPrimitive s;
+
+			//get a simple selection
+			if (!osmPrimitiveSelection.isEmpty()) {
+				s = osmPrimitiveSelection.get(0);
+			} else {
+				return;
+			}
+
+			selectedInstance = new OSMWay();
+			for (Way selectedWay : s.getDataSet().getSelectedWays()) {
+				List<Node> selectedWayNodes = selectedWay.getNodes();
+				for (Node node : selectedWayNodes) {
+					node.getCoor();
+					if (node.isLatLonKnown()) {
+						double lat = node.getCoor().lat();
+						double lon = node.getCoor().lon();
+
+						Coordinate sourceCoordinate = new Coordinate(lon, lat);
+						Coordinate targetGeometry = null;
+						try {
+							targetGeometry = JTS.transform(sourceCoordinate, null, transform);
+						} catch (MismatchedDimensionException | TransformException ex) {
+							Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
+						}
+
+						Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
+						selectedInstance.addNodeGeometry(geom);
+					}
+				}
+			}
+			Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
+			if ((selectedInstance.getNodeGeometries().size() > 3) &&
+					selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
+							.get(selectedInstance.getNodeGeometries().size()-1))) {
+				//checks if the beginning and ending node are the same and the number of nodes are more than 3.
+				//the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
+				LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
+				Polygon poly = new Polygon(linear, null, geometryFactory);
+				selectedInstance.setGeometry(poly);
+
+				System.out.println("\n\npolygon");
+			} else if (selectedInstance.getNodeGeometries().size() > 1) {
+				//it is an open geometry with more than one nodes, make it linestring
+				System.out.println("\n\nlinestring");
+				LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
+				selectedInstance.setGeometry(lineString);
+			} else { //we assume all the rest geometries are points
+				System.out.println("\n\npoint");
+				Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
+				selectedInstance.setGeometry(point);
+			}
+
+			Map<String, String> selectedTags = s.getInterestingTags();
+			selectedInstance.setAllTags(selectedTags);
+
+			//construct vector
+			if (selectedInstance != null) {
+				int id;
+
+				OSMClassification classifier = new OSMClassification();
+				classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+
+				if (useClassFeatures) {
+					ClassFeatures classFeatures = new ClassFeatures();
+					classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+					id = 1422;
+				} else {
+					id = 1;
+				}
+
+				GeometryFeatures geometryFeatures = new GeometryFeatures(id);
+				geometryFeatures.createGeometryFeatures(selectedInstance);
+				id = geometryFeatures.getLastID();
+				TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
+				textualFeatures.createTextualFeatures(selectedInstance);
+
+				List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
+
+				FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
+
+				int i = 0;
+				for (FeatureNode featureNode : featureNodeList) {
+					featureNodeArray[i] = featureNode;
+					i++;
+				}
+				FeatureNode[] testInstance2 = featureNodeArray;
+
+				//compute prediction list for every model
+				int[] ranks = new int[10];
+
+				for (int l = 0; l < 10; l++) {
+					ranks[l] = 10-l; //init from 10 to 1
+				}
+
+				Map<String, Double> scoreMap = new HashMap<>();
+
+				Map<File, Double> alignedFilesAndWeights = getAlignedModels(filesAndWeights);
+
+				for (File modelFile : alignedFilesAndWeights.keySet()) {
+
+					try {
+						modelSVM = Model.load(modelFile);
+					} catch (IOException ex) {
+						Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+					}
+					modelSVMLabelSize = modelSVM.getLabels().length;
+					modelSVMLabels = modelSVM.getLabels();
+
+					Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
+					for (int h = 0; h < modelSVMLabelSize; h++) {
+						mapLabelsToIDs.put(modelSVMLabels[h], h);
+					}
+					double[] scores = new double[modelSVMLabelSize];
+					Linear.predictValues(modelSVM, testInstance2, scores);
+
+					Map<Double, Integer> scoresValues = new HashMap<>();
+					for (int h = 0; h < scores.length; h++) {
+						scoresValues.put(scores[h], h);
+					}
+
+					Arrays.sort(scores);
+					int predicted1 = modelSVMLabels[scoresValues.get(scores[scores.length-1])];
+					int predicted2 = modelSVMLabels[scoresValues.get(scores[scores.length-2])];
+					int predicted3 = modelSVMLabels[scoresValues.get(scores[scores.length-3])];
+					int predicted4 = modelSVMLabels[scoresValues.get(scores[scores.length-4])];
+					int predicted5 = modelSVMLabels[scoresValues.get(scores[scores.length-5])];
+					int predicted6 = modelSVMLabels[scoresValues.get(scores[scores.length-6])];
+					int predicted7 = modelSVMLabels[scoresValues.get(scores[scores.length-7])];
+					int predicted8 = modelSVMLabels[scoresValues.get(scores[scores.length-8])];
+					int predicted9 = modelSVMLabels[scoresValues.get(scores[scores.length-9])];
+					int predicted10 = modelSVMLabels[scoresValues.get(scores[scores.length-10])];
+
+					String[] predictedTags = new String[10];
+					for (Map.Entry<String, Integer> entry : mapperWithIDs.entrySet()) {
+
+						if (entry.getValue().equals(predicted1)) {
+							predictedTags[0] = entry.getKey();
+						} else if (entry.getValue().equals(predicted2)) {
+							predictedTags[1] = entry.getKey();
+						} else if (entry.getValue().equals(predicted3)) {
+							predictedTags[2] = entry.getKey();
+						} else if (entry.getValue().equals(predicted4)) {
+							predictedTags[3] = entry.getKey();
+						} else if (entry.getValue().equals(predicted5)) {
+							predictedTags[4] = entry.getKey();
+						} else if (entry.getValue().equals(predicted6)) {
+							predictedTags[5] = entry.getKey();
+						} else if (entry.getValue().equals(predicted7)) {
+							predictedTags[6] = entry.getKey();
+						} else if (entry.getValue().equals(predicted8)) {
+							predictedTags[7] = entry.getKey();
+						} else if (entry.getValue().equals(predicted9)) {
+							predictedTags[8] = entry.getKey();
+						} else if (entry.getValue().equals(predicted10)) {
+							predictedTags[9] = entry.getKey();
+						}
+					}
+					//clearing model, to add the new computed classes in jlist
+					model.clear();
+					for (Map.Entry<String, String> tag : mappings.entrySet()) {
+
+						for (int k = 0; k < 10; k++) {
+							if (tag.getValue().equals(predictedTags[k])) {
+								predictedTags[k] = tag.getKey();
+								model.addElement(tag.getKey());
+							}
+						}
+					}
+					System.out.println("combined, predicted classes: " + Arrays.toString(predictedTags));
+
+					for (int r = 0; r < ranks.length; r++) {
+						String predictedTag = predictedTags[r];
+						Double currentWeight = alignedFilesAndWeights.get(modelFile);
+						double finalRank = ranks[r]*currentWeight;
+
+						if (scoreMap.containsKey(predictedTag)) {
+							Double scoreToAdd = scoreMap.get(predictedTag);
+							scoreMap.put(predictedTag, finalRank+scoreToAdd);
+						} else {
+							scoreMap.put(predictedTag, finalRank);
+						}
+						//add final weight - predicted tag
+					}
+				} //files iter
+				model.clear();
+				List<Double> scoresList = new ArrayList<>(scoreMap.values());
+				Collections.sort(scoresList, Collections.reverseOrder());
+
+				for (Double sco : scoresList) {
+					if (model.size() > 9) {
+						break;
+					}
+					for (Map.Entry<String, Double> scoreEntry : scoreMap.entrySet()) {
+						if (scoreEntry.getValue().equals(sco)) {
+							model.addElement(scoreEntry.getKey());
+						}
+					}
+				}
+			}
+		}
+
+		private void createOSMObject(Collection<OsmPrimitive> sel) {
+
+			MathTransform transform = null;
+			GeometryFactory geometryFactory = new GeometryFactory();
+			CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
+			CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
+			try {
+				transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+
+			} catch (FactoryException ex) {
+				Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
+			}
+
+			//fire an error to the user if he has multiple selection from map
+
+			//we consider simple (one instance) selection, so we get the first of the sel list
+
+			OSMWay selectedInstance;
+			List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
+			OsmPrimitive s;
+
+			//get a simple selection
+			if (!osmPrimitiveSelection.isEmpty()) {
+				s = osmPrimitiveSelection.get(0);
+			} else {
+				return;
+			}
+
+			selectedInstance = new OSMWay();
+			for (Way selectedWay : s.getDataSet().getSelectedWays()) {
+				List<Node> selectedWayNodes = selectedWay.getNodes();
+				for (Node node : selectedWayNodes) {
+					node.getCoor();
+					if (node.isLatLonKnown()) {
+						double lat = node.getCoor().lat();
+						double lon = node.getCoor().lon();
+
+						Coordinate sourceCoordinate = new Coordinate(lon, lat);
+						Coordinate targetGeometry = null;
+						try {
+							targetGeometry = JTS.transform(sourceCoordinate, null, transform);
+						} catch (MismatchedDimensionException | TransformException ex) {
+							Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
+						}
+
+						Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
+						selectedInstance.addNodeGeometry(geom);
+					}
+				}
+			}
+			Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
+
+			System.out.println("number of nodes: " + selectedInstance.getNodeGeometries().size());
+
+			if ((selectedInstance.getNodeGeometries().size() > 3) &&
+					selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
+							.get(selectedInstance.getNodeGeometries().size()-1))) {
+				//checks if the beginning and ending node are the same and the number of nodes are more than 3.
+				//the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
+				LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
+				Polygon poly = new Polygon(linear, null, geometryFactory);
+				selectedInstance.setGeometry(poly);
+
+				System.out.println("\n\npolygon");
+			} else if (selectedInstance.getNodeGeometries().size() > 1) {
+				//it is an open geometry with more than one nodes, make it linestring
+				System.out.println("\n\nlinestring");
+				LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
+				selectedInstance.setGeometry(lineString);
+			} else { //we assume all the rest geometries are points
+				System.out.println("\n\npoint");
+				Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
+				selectedInstance.setGeometry(point);
+			}
+
+			Map<String, String> selectedTags = s.getInterestingTags();
+			selectedInstance.setAllTags(selectedTags);
+
+			//construct vector here
+			if (selectedInstance != null) {
+				int id;
+				if (mappings == null) {
+					System.out.println("null mappings ERROR");
+				}
+
+				OSMClassification classifier = new OSMClassification();
+				classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+
+				if (modelWithClasses) {
+					ClassFeatures classFeatures = new ClassFeatures();
+					classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+					id = 1422;
+				} else {
+					id = 1;
+				}
+
+				GeometryFeatures geometryFeatures = new GeometryFeatures(id);
+				geometryFeatures.createGeometryFeatures(selectedInstance);
+				id = geometryFeatures.getLastID();
+				TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
+				textualFeatures.createTextualFeatures(selectedInstance);
+
+				List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
+				System.out.println(featureNodeList);
+
+				FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
+
+				int i = 0;
+				for (FeatureNode featureNode : featureNodeList) {
+					featureNodeArray[i] = featureNode;
+					i++;
+				}
+				FeatureNode[] testInstance2 = featureNodeArray;
+
+				Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
+				for (int h = 0; h < modelSVMLabelSize; h++) {
+					mapLabelsToIDs.put(modelSVMLabels[h], h);
+				}
+
+				double[] scores = new double[modelSVMLabelSize];
+				Linear.predictValues(modelSVM, testInstance2, scores);
+
+				Map<Double, Integer> scoresValues = new HashMap<>();
+				for (int h = 0; h < scores.length; h++) {
+					scoresValues.put(scores[h], h);
+				}
+
+				Arrays.sort(scores);
+
+				int[] preds = new int[RECOMMENDATIONS_SIZE];
+				for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
+					preds[p] = modelSVMLabels[scoresValues.get(scores[scores.length-(p+1)])];
+				}
+				String[] predictedTags2 = new String[RECOMMENDATIONS_SIZE];
+
+				for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
+					if (idsWithMappings.containsKey(preds[p])) {
+						predictedTags2[p] = idsWithMappings.get(preds[p]);
+					}
+				}
+
+				//clearing model, to add the new computed classes in jlist
+				model.clear();
+				for (Map.Entry<String, String> tag : mappings.entrySet()) {
+					for (int k = 0; k < 10; k++) {
+						if (tag.getValue().equals(predictedTags2[k])) {
+							predictedTags2[k] = tag.getKey();
+							model.addElement(tag.getKey());
+						}
+					}
+				}
+				System.out.println("Optimized - create OSMObject, predicted classes: " + Arrays.toString(predictedTags2));
+			}
+		}
+
+		private void parseTagsMappedToClasses() {
+
+			InputStream tagsToClassesMapping = TrainWorker.class.getResourceAsStream("/resources/files/Map");
+			Mapper mapper = new Mapper();
+			try {
+				mapper.parseFile(tagsToClassesMapping);
+
+			} catch (FileNotFoundException ex) {
+				Logger.getLogger(Mapper.class.getName()).log(Level.SEVERE, null, ex);
+			}
+			mappings = mapper.getMappings();
+			mapperWithIDs = mapper.getMappingsWithIDs();
+			idsWithMappings = mapper.getIDsWithMappings();
+		}
+
+		private void loadTextualList(File textualListFile) {
+
+			Scanner input = null;
+
+			try {
+				input = new Scanner(textualListFile);
+			} catch (FileNotFoundException ex) {
+				Logging.warn(ex);
+			}
+			while (input.hasNext()) {
+				String nextLine = input.nextLine();
+				textualList.add(nextLine);
+			}
+			System.out.println("Textual List parsed from file successfully." + textualList);
+		}
+
+		private void loadDefaultTextualList() {
+
+			InputStream textualListStream = TrainWorker.class.getResourceAsStream("/resources/files/textualList.txt");
+			TextualStatistics textualStatistics = new TextualStatistics();
+			textualStatistics.parseTextualList(textualListStream);
+			textualList = textualStatistics.getTextualList();
+			System.out.println("Default Textual List parsed from file successfully." + textualList);
+		}
+
+		private void loadOntology() {
+			InputStream ontologyStream = TrainWorker.class.getResourceAsStream("/resources/files/owl.xml");
+			Ontology ontology = new Ontology(ontologyStream);
+			indirectClasses = ontology.getIndirectClasses();
+			indirectClassesWithIDs = ontology.getIndirectClassesIDs();
+		}
+
+		private Map<File, Double> getAlignedModels(Map<File, Double> filesAndWeights) {
+			Map<File, Double> alignedFilesAndWeights = new HashMap<>();
+			if (modelWithClasses) {
+				for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
+					String absolutePath = entry.getKey().getAbsolutePath();
+					if (absolutePath.endsWith(".0")) {
+						String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".1";
+						File alignedFile = new File(newPath);
+						if (alignedFile.exists()) {
+							alignedFilesAndWeights.put(alignedFile, entry.getValue());
+						}
+					} else {
+						alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
+					}
+				}
+			} else {
+				for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
+					String absolutePath = entry.getKey().getAbsolutePath();
+					if (absolutePath.endsWith(".1")) {
+						String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".0";
+						File alignedFile = new File(newPath);
+						if (alignedFile.exists()) {
+							alignedFilesAndWeights.put(alignedFile, entry.getValue());
+						}
+					} else {
+						alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
+					}
+				}
+			}
+			return alignedFilesAndWeights;
+		}
+	}
 }
Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecToggleDialog.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecToggleDialog.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecToggleDialog.java	(revision 33525)
@@ -42,4 +42,5 @@
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
 import org.openstreetmap.josm.data.osm.event.DataSetListenerAdapter;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
@@ -71,388 +72,388 @@
 implements SelectionChangedListener, DataSetListenerAdapter.Listener {
 
-    /**
-     * The tag data of selected objects.
-     */
-    private final DefaultTableModel tagData = new ReadOnlyTableModel();
-
-    /**
-     * The membership data of selected objects.
-     */
-    private final DefaultTableModel membershipData = new ReadOnlyTableModel();
-
-    /**
-     * The tags table.
-     */
-    private final JTable tagTable = new JTable(tagData);
-
-    /**
-     * The membership table.
-     */
-    private final JTable membershipTable = new JTable(membershipData);
-
-    /** JPanel containing both previous tables */
-    private final JPanel bothTables = new JPanel();
-
-    private final transient Map<String, Map<String, Integer>> valueCount = new TreeMap<>();
-    /**
-     * This sub-object is responsible for all adding and editing of tags
-     */
-    private final transient OSMRecPluginHelper editHelper = new OSMRecPluginHelper(tagData, valueCount);
-
-    private final AddAction addAction = new AddAction();
-    private final EditActionTrain editAction = new EditActionTrain();
-    //    private final DeleteAction deleteAction = new DeleteAction();
-    //    private final JosmAction[] josmActions = new JosmAction[]{addAction, editAction, deleteAction};
-
-    /**
-     * The Add button (needed to be able to disable it)
-     */
-    private final SideButton btnAdd = new SideButton(addAction);
-    /**
-     * The Edit button (needed to be able to disable it)
-     */
-    private final SideButton btnEdit = new SideButton(editAction);
-
-    /**
-     * Text to display when nothing selected.
-     */
-    private final JLabel selectSth = new JLabel("<html><p>"
-            + tr("Select objects or create new objects and get recommendation.") + "</p></html>");
-
-    // <editor-fold defaultstate="collapsed" desc="Dialog construction and helper methods">
-
-    /**
-     * Create a new OSMRecToggleDialog
-     */
-    public OSMRecToggleDialog() {
-        super(tr("Tags/Memberships"), "propertiesdialog", tr("Tags for selected objects."),
-                Shortcut.registerShortcut("subwindow:properties", tr("Toggle: {0}", tr("Tags/Memberships")), KeyEvent.VK_P,
-                        Shortcut.ALT_SHIFT), 150, true);
-
-        System.out.println("cleaning test..");
-        bothTables.setLayout(new GridBagLayout());
-        bothTables.setVisible(false); //my
-        // Let the actions know when selection in the tables change
-        tagTable.getSelectionModel().addListSelectionListener(editAction);
-        membershipTable.getSelectionModel().addListSelectionListener(editAction);
-
-        JScrollPane scrollPane = (JScrollPane) createLayout(bothTables, true,
-                Arrays.asList(this.btnAdd, this.btnEdit));
-
-        MouseClickWatch mouseClickWatch = new MouseClickWatch();
-        tagTable.addMouseListener(mouseClickWatch);
-        membershipTable.addMouseListener(mouseClickWatch);
-        scrollPane.addMouseListener(mouseClickWatch);
-        editHelper.loadTagsIfNeeded();
-
-    }
-
-    /**
-     * This simply fires up an {@link RelationEditor} for the relation shown; everything else
-     * is the editor's business.
-     *
-     * @param row position
-     */
-    private void editMembership(int row) {
-        Relation relation = (Relation) membershipData.getValueAt(row, 0);
-        Main.map.relationListDialog.selectRelation(relation);
-    }
-
-    private int findRow(TableModel model, Object value) {
-        for (int i = 0; i < model.getRowCount(); i++) {
-            if (model.getValueAt(i, 0).equals(value))
-                return i;
-        }
-        return -1;
-    }
-
-    /**
-     * Update selection status, call @{link #selectionChanged} function.
-     */
-    private void updateSelection() {
-        // Parameter is ignored in this class
-        selectionChanged(null);
-    }
-
-    // </editor-fold>
-
-    // <editor-fold defaultstate="collapsed" desc="Event listeners methods">
-
-    @Override
-    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        if (tagTable == null)
-            return; // selection changed may be received in base class constructor before init
-        if (tagTable.getCellEditor() != null) {
-            tagTable.getCellEditor().cancelCellEditing();
-        }
-
-        // Ignore parameter as we do not want to operate always on real selection here, especially in draw mode
-        Collection<OsmPrimitive> newSel = Main.main.getInProgressSelection();
-        if (newSel == null) {
-            newSel = Collections.<OsmPrimitive>emptyList();
-        }
-
-        String selectedTag;
-        Relation selectedRelation = null;
-        selectedTag = editHelper.getChangedKey(); // select last added or last edited key by default
-        if (selectedTag == null && tagTable.getSelectedRowCount() == 1) {
-            selectedTag = (String) tagData.getValueAt(tagTable.getSelectedRow(), 0);
-        }
-        if (membershipTable.getSelectedRowCount() == 1) {
-            selectedRelation = (Relation) membershipData.getValueAt(membershipTable.getSelectedRow(), 0);
-        }
-
-        // re-load tag data
-        tagData.setRowCount(0);
-
-        final Map<String, String> tags = new HashMap<>();
-        valueCount.clear();
-        for (Entry<String, Map<String, Integer>> e : valueCount.entrySet()) {
-            int count = 0;
-            for (Entry<String, Integer> e1 : e.getValue().entrySet()) {
-                count += e1.getValue();
-            }
-            if (count < newSel.size()) {
-                e.getValue().put("", newSel.size() - count);
-            }
-            tagData.addRow(new Object[]{e.getKey(), e.getValue()});
-            tags.put(e.getKey(), e.getValue().size() == 1
-                    ? e.getValue().keySet().iterator().next() : tr("<different>"));
-        }
-
-        membershipData.setRowCount(0);
-
-        Map<Relation, MemberInfo> roles = new HashMap<>();
-        for (OsmPrimitive primitive: newSel) {
-            for (OsmPrimitive ref: primitive.getReferrers(true)) {
-                if (ref instanceof Relation && !ref.isIncomplete() && !ref.isDeleted()) {
-                    Relation r = (Relation) ref;
-                    MemberInfo mi = roles.get(r);
-                    if (mi == null) {
-                        mi = new MemberInfo(newSel);
-                    }
-                    roles.put(r, mi);
-                    int i = 1;
-                    for (RelationMember m : r.getMembers()) {
-                        if (m.getMember() == primitive) {
-                            mi.add(m, i);
-                        }
-                        ++i;
-                    }
-                }
-            }
-        }
-
-        List<Relation> sortedRelations = new ArrayList<>(roles.keySet());
-        Collections.sort(sortedRelations, new Comparator<Relation>() {
-            @Override public int compare(Relation o1, Relation o2) {
-                int comp = Boolean.valueOf(o1.isDisabledAndHidden()).compareTo(o2.isDisabledAndHidden());
-                return comp != 0 ? comp : DefaultNameFormatter.getInstance().getRelationComparator().compare(o1, o2);
-            } });
-
-        for (Relation r: sortedRelations) {
-            membershipData.addRow(new Object[]{r, roles.get(r)});
-        }
-
-        membershipTable.getTableHeader().setVisible(membershipData.getRowCount() > 0);
-        membershipTable.setVisible(membershipData.getRowCount() > 0);
-
-        boolean hasSelection = !newSel.isEmpty();
-        boolean hasTags = hasSelection && tagData.getRowCount() > 0;
-        boolean hasMemberships = hasSelection && membershipData.getRowCount() > 0;
-
-        addAction.setEnabled(hasSelection);
-        //editAction.setEnabled(hasTags || hasMemberships);
-        editAction.setEnabled(true);
-        tagTable.setVisible(hasTags);
-        tagTable.getTableHeader().setVisible(hasTags);
-        selectSth.setVisible(!hasSelection);
-
-        int selectedIndex;
-        if (selectedTag != null && (selectedIndex = findRow(tagData, selectedTag)) != -1) {
-            tagTable.changeSelection(selectedIndex, 0, false, false);
-        } else if (selectedRelation != null && (selectedIndex = findRow(membershipData, selectedRelation)) != -1) {
-            membershipTable.changeSelection(selectedIndex, 0, false, false);
-        } else if (hasTags) {
-            tagTable.changeSelection(0, 0, false, false);
-        } else if (hasMemberships) {
-            membershipTable.changeSelection(0, 0, false, false);
-        }
-    }
-
-    @Override
-    public void processDatasetEvent(AbstractDatasetChangedEvent event) {
-        updateSelection();
-    }
-
-    // </editor-fold>
-
-    // <editor-fold defaultstate="collapsed" desc="Methods that are called by plugins to extend fuctionality ">
-
-
-    /**
-     * Returns the selected tag.
-     * @return The current selected tag
-     */
-    @SuppressWarnings("unchecked")
-    public Tag getSelectedProperty() {
-        int row = tagTable.getSelectedRow();
-        if (row == -1) return null;
-        Map<String, Integer> map = (TreeMap<String, Integer>) tagData.getValueAt(row, 1);
-        return new Tag(
-                tagData.getValueAt(row, 0).toString(),
-                map.size() > 1 ? "" : map.keySet().iterator().next());
-    }
-
-    /**
-     * Returns the selected relation membership.
-     * @return The current selected relation membership
-     */
-    public IRelation getSelectedMembershipRelation() {
-        int row = membershipTable.getSelectedRow();
-        return row > -1 ? (IRelation) membershipData.getValueAt(row, 0) : null;
-    }
-
-    // </editor-fold>
-
-    /**
-     * Class that watches for mouse clicks
-     * @author imi
-     */
-    public class MouseClickWatch extends MouseAdapter {
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            if (e.getClickCount() < 2) {
-                // single click, clear selection in other table not clicked in
-                if (e.getSource() == tagTable) {
-                    membershipTable.clearSelection();
-                } else if (e.getSource() == membershipTable) {
-                    tagTable.clearSelection();
-                }
-            } else if (e.getSource() == tagTable) {
-                // double click, edit or add tag
-                int row = tagTable.rowAtPoint(e.getPoint());
-                if (row > -1) {
-                    boolean focusOnKey = tagTable.columnAtPoint(e.getPoint()) == 0;
-                    editHelper.editTag(row, focusOnKey);
-                } else {
-                    editHelper.addTag();
-                }
-            } else if (e.getSource() == membershipTable) {
-                int row = membershipTable.rowAtPoint(e.getPoint());
-                if (row > -1) {
-                    editMembership(row);
-                }
-            } else {
-                editHelper.addTag();
-            }
-        }
-
-        @Override
-        public void mousePressed(MouseEvent e) {
-            if (e.getSource() == tagTable) {
-                membershipTable.clearSelection();
-            } else if (e.getSource() == membershipTable) {
-                tagTable.clearSelection();
-            }
-        }
-    }
-
-    static class MemberInfo {
-        private List<RelationMember> role = new ArrayList<>();
-        private Set<OsmPrimitive> members = new HashSet<>();
-        private List<Integer> position = new ArrayList<>();
-        private Iterable<OsmPrimitive> selection;
-        private String positionString;
-        private String roleString;
-
-        MemberInfo(Iterable<OsmPrimitive> selection) {
-            this.selection = selection;
-        }
-
-        void add(RelationMember r, Integer p) {
-            role.add(r);
-            members.add(r.getMember());
-            position.add(p);
-        }
-
-        @Override
-        public String toString() {
-            return "MemberInfo{" +
-                    "roles='" + roleString + '\'' +
-                    ", positions='" + positionString + '\'' +
-                    '}';
-        }
-    }
-
-    /**
-     * Class that allows fast creation of read-only table model with String columns
-     */
-    public static class ReadOnlyTableModel extends DefaultTableModel {
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-
-        @Override
-        public Class<?> getColumnClass(int columnIndex) {
-            return String.class;
-        }
-    }
-
-    /**
-     * Action handling add button press in properties dialog.
-     */
-    class AddAction extends JosmAction {
-        AddAction() {
-            super(tr("Add Recommendation"), /* ICON() */ "dialogs/add", tr("Add a recommended key/value pair to your object"),
-                    Shortcut.registerShortcut("properties:add", tr("Add Tag"), KeyEvent.VK_A,
-                            Shortcut.ALT), false);
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            editHelper.addTag();
-            btnAdd.requestFocusInWindow();
-        }
-    }
-
-    /**
-     * Action handling edit button press in properties dialog.
-     * training process dialog/configuration
-     */
-    class EditActionTrain extends JosmAction implements ListSelectionListener {
-        EditActionTrain() {
-            super(tr("Train a Model"), /* ICON() */ "dialogs/fix", tr("Start the training engine!"),
-                    Shortcut.registerShortcut("properties:edit", tr("Edit Tags"), KeyEvent.VK_S,
-                            Shortcut.ALT), false);
-            setEnabled(true);
-            updateEnabledState();
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            if (!isEnabled())
-                return;
-            if (tagTable.getSelectedRowCount() == 1) {
-                int row = tagTable.getSelectedRow();
-                editHelper.editTag(row, false);
-            } else if (membershipTable.getSelectedRowCount() == 1) {
-                int row = membershipTable.getSelectedRow();
-                editHelper.editTag(row, false);
-            } else {
-                editHelper.editTag(1, false);
-            }
-        }
-
-        @Override
-        protected void updateEnabledState() {
-            setEnabled(true);
-        }
-
-        @Override
-        public void valueChanged(ListSelectionEvent e) {
-            updateEnabledState();
-        }
-    }
+	/**
+	 * The tag data of selected objects.
+	 */
+	private final DefaultTableModel tagData = new ReadOnlyTableModel();
+
+	/**
+	 * The membership data of selected objects.
+	 */
+	private final DefaultTableModel membershipData = new ReadOnlyTableModel();
+
+	/**
+	 * The tags table.
+	 */
+	private final JTable tagTable = new JTable(tagData);
+
+	/**
+	 * The membership table.
+	 */
+	private final JTable membershipTable = new JTable(membershipData);
+
+	/** JPanel containing both previous tables */
+	private final JPanel bothTables = new JPanel();
+
+	private final transient Map<String, Map<String, Integer>> valueCount = new TreeMap<>();
+	/**
+	 * This sub-object is responsible for all adding and editing of tags
+	 */
+	private final transient OSMRecPluginHelper editHelper = new OSMRecPluginHelper(tagData, valueCount);
+
+	private final AddAction addAction = new AddAction();
+	private final EditActionTrain editAction = new EditActionTrain();
+	//    private final DeleteAction deleteAction = new DeleteAction();
+	//    private final JosmAction[] josmActions = new JosmAction[]{addAction, editAction, deleteAction};
+
+	/**
+	 * The Add button (needed to be able to disable it)
+	 */
+	private final SideButton btnAdd = new SideButton(addAction);
+	/**
+	 * The Edit button (needed to be able to disable it)
+	 */
+	private final SideButton btnEdit = new SideButton(editAction);
+
+	/**
+	 * Text to display when nothing selected.
+	 */
+	private final JLabel selectSth = new JLabel("<html><p>"
+			+ tr("Select objects or create new objects and get recommendation.") + "</p></html>");
+
+	// <editor-fold defaultstate="collapsed" desc="Dialog construction and helper methods">
+
+	/**
+	 * Create a new OSMRecToggleDialog
+	 */
+	public OSMRecToggleDialog() {
+		super(tr("Tags/Memberships"), "propertiesdialog", tr("Tags for selected objects."),
+				Shortcut.registerShortcut("subwindow:properties", tr("Toggle: {0}", tr("Tags/Memberships")), KeyEvent.VK_P,
+						Shortcut.ALT_SHIFT), 150, true);
+
+		System.out.println("cleaning test..");
+		bothTables.setLayout(new GridBagLayout());
+		bothTables.setVisible(false); //my
+		// Let the actions know when selection in the tables change
+		tagTable.getSelectionModel().addListSelectionListener(editAction);
+		membershipTable.getSelectionModel().addListSelectionListener(editAction);
+
+		JScrollPane scrollPane = (JScrollPane) createLayout(bothTables, true,
+				Arrays.asList(this.btnAdd, this.btnEdit));
+
+		MouseClickWatch mouseClickWatch = new MouseClickWatch();
+		tagTable.addMouseListener(mouseClickWatch);
+		membershipTable.addMouseListener(mouseClickWatch);
+		scrollPane.addMouseListener(mouseClickWatch);
+		editHelper.loadTagsIfNeeded();
+
+	}
+
+	/**
+	 * This simply fires up an {@link RelationEditor} for the relation shown; everything else
+	 * is the editor's business.
+	 *
+	 * @param row position
+	 */
+	private void editMembership(int row) {
+		Relation relation = (Relation) membershipData.getValueAt(row, 0);
+		MainApplication.getMap().relationListDialog.selectRelation(relation);
+	}
+
+	private int findRow(TableModel model, Object value) {
+		for (int i = 0; i < model.getRowCount(); i++) {
+			if (model.getValueAt(i, 0).equals(value))
+				return i;
+		}
+		return -1;
+	}
+
+	/**
+	 * Update selection status, call @{link #selectionChanged} function.
+	 */
+	private void updateSelection() {
+		// Parameter is ignored in this class
+		selectionChanged(null);
+	}
+
+	// </editor-fold>
+
+	// <editor-fold defaultstate="collapsed" desc="Event listeners methods">
+
+	@Override
+	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+		if (tagTable == null)
+			return; // selection changed may be received in base class constructor before init
+		if (tagTable.getCellEditor() != null) {
+			tagTable.getCellEditor().cancelCellEditing();
+		}
+
+		// Ignore parameter as we do not want to operate always on real selection here, especially in draw mode
+		Collection<OsmPrimitive> newSel = Main.main.getInProgressSelection();
+		if (newSel == null) {
+			newSel = Collections.<OsmPrimitive>emptyList();
+		}
+
+		String selectedTag;
+		Relation selectedRelation = null;
+		selectedTag = editHelper.getChangedKey(); // select last added or last edited key by default
+		if (selectedTag == null && tagTable.getSelectedRowCount() == 1) {
+			selectedTag = (String) tagData.getValueAt(tagTable.getSelectedRow(), 0);
+		}
+		if (membershipTable.getSelectedRowCount() == 1) {
+			selectedRelation = (Relation) membershipData.getValueAt(membershipTable.getSelectedRow(), 0);
+		}
+
+		// re-load tag data
+		tagData.setRowCount(0);
+
+		final Map<String, String> tags = new HashMap<>();
+		valueCount.clear();
+		for (Entry<String, Map<String, Integer>> e : valueCount.entrySet()) {
+			int count = 0;
+			for (Entry<String, Integer> e1 : e.getValue().entrySet()) {
+				count += e1.getValue();
+			}
+			if (count < newSel.size()) {
+				e.getValue().put("", newSel.size() - count);
+			}
+			tagData.addRow(new Object[]{e.getKey(), e.getValue()});
+			tags.put(e.getKey(), e.getValue().size() == 1
+					? e.getValue().keySet().iterator().next() : tr("<different>"));
+		}
+
+		membershipData.setRowCount(0);
+
+		Map<Relation, MemberInfo> roles = new HashMap<>();
+		for (OsmPrimitive primitive: newSel) {
+			for (OsmPrimitive ref: primitive.getReferrers(true)) {
+				if (ref instanceof Relation && !ref.isIncomplete() && !ref.isDeleted()) {
+					Relation r = (Relation) ref;
+					MemberInfo mi = roles.get(r);
+					if (mi == null) {
+						mi = new MemberInfo(newSel);
+					}
+					roles.put(r, mi);
+					int i = 1;
+					for (RelationMember m : r.getMembers()) {
+						if (m.getMember() == primitive) {
+							mi.add(m, i);
+						}
+						++i;
+					}
+				}
+			}
+		}
+
+		List<Relation> sortedRelations = new ArrayList<>(roles.keySet());
+		Collections.sort(sortedRelations, new Comparator<Relation>() {
+			@Override public int compare(Relation o1, Relation o2) {
+				int comp = Boolean.valueOf(o1.isDisabledAndHidden()).compareTo(o2.isDisabledAndHidden());
+				return comp != 0 ? comp : DefaultNameFormatter.getInstance().getRelationComparator().compare(o1, o2);
+			} });
+
+		for (Relation r: sortedRelations) {
+			membershipData.addRow(new Object[]{r, roles.get(r)});
+		}
+
+		membershipTable.getTableHeader().setVisible(membershipData.getRowCount() > 0);
+		membershipTable.setVisible(membershipData.getRowCount() > 0);
+
+		boolean hasSelection = !newSel.isEmpty();
+		boolean hasTags = hasSelection && tagData.getRowCount() > 0;
+		boolean hasMemberships = hasSelection && membershipData.getRowCount() > 0;
+
+		addAction.setEnabled(hasSelection);
+		//editAction.setEnabled(hasTags || hasMemberships);
+		editAction.setEnabled(true);
+		tagTable.setVisible(hasTags);
+		tagTable.getTableHeader().setVisible(hasTags);
+		selectSth.setVisible(!hasSelection);
+
+		int selectedIndex;
+		if (selectedTag != null && (selectedIndex = findRow(tagData, selectedTag)) != -1) {
+			tagTable.changeSelection(selectedIndex, 0, false, false);
+		} else if (selectedRelation != null && (selectedIndex = findRow(membershipData, selectedRelation)) != -1) {
+			membershipTable.changeSelection(selectedIndex, 0, false, false);
+		} else if (hasTags) {
+			tagTable.changeSelection(0, 0, false, false);
+		} else if (hasMemberships) {
+			membershipTable.changeSelection(0, 0, false, false);
+		}
+	}
+
+	@Override
+	public void processDatasetEvent(AbstractDatasetChangedEvent event) {
+		updateSelection();
+	}
+
+	// </editor-fold>
+
+	// <editor-fold defaultstate="collapsed" desc="Methods that are called by plugins to extend fuctionality ">
+
+
+	/**
+	 * Returns the selected tag.
+	 * @return The current selected tag
+	 */
+	@SuppressWarnings("unchecked")
+	public Tag getSelectedProperty() {
+		int row = tagTable.getSelectedRow();
+		if (row == -1) return null;
+		Map<String, Integer> map = (TreeMap<String, Integer>) tagData.getValueAt(row, 1);
+		return new Tag(
+				tagData.getValueAt(row, 0).toString(),
+				map.size() > 1 ? "" : map.keySet().iterator().next());
+	}
+
+	/**
+	 * Returns the selected relation membership.
+	 * @return The current selected relation membership
+	 */
+	public IRelation getSelectedMembershipRelation() {
+		int row = membershipTable.getSelectedRow();
+		return row > -1 ? (IRelation) membershipData.getValueAt(row, 0) : null;
+	}
+
+	// </editor-fold>
+
+	/**
+	 * Class that watches for mouse clicks
+	 * @author imi
+	 */
+	public class MouseClickWatch extends MouseAdapter {
+		@Override
+		public void mouseClicked(MouseEvent e) {
+			if (e.getClickCount() < 2) {
+				// single click, clear selection in other table not clicked in
+				if (e.getSource() == tagTable) {
+					membershipTable.clearSelection();
+				} else if (e.getSource() == membershipTable) {
+					tagTable.clearSelection();
+				}
+			} else if (e.getSource() == tagTable) {
+				// double click, edit or add tag
+				int row = tagTable.rowAtPoint(e.getPoint());
+				if (row > -1) {
+					boolean focusOnKey = tagTable.columnAtPoint(e.getPoint()) == 0;
+					editHelper.editTag(row, focusOnKey);
+				} else {
+					editHelper.addTag();
+				}
+			} else if (e.getSource() == membershipTable) {
+				int row = membershipTable.rowAtPoint(e.getPoint());
+				if (row > -1) {
+					editMembership(row);
+				}
+			} else {
+				editHelper.addTag();
+			}
+		}
+
+		@Override
+		public void mousePressed(MouseEvent e) {
+			if (e.getSource() == tagTable) {
+				membershipTable.clearSelection();
+			} else if (e.getSource() == membershipTable) {
+				tagTable.clearSelection();
+			}
+		}
+	}
+
+	static class MemberInfo {
+		private List<RelationMember> role = new ArrayList<>();
+		private Set<OsmPrimitive> members = new HashSet<>();
+		private List<Integer> position = new ArrayList<>();
+		private Iterable<OsmPrimitive> selection;
+		private String positionString;
+		private String roleString;
+
+		MemberInfo(Iterable<OsmPrimitive> selection) {
+			this.selection = selection;
+		}
+
+		void add(RelationMember r, Integer p) {
+			role.add(r);
+			members.add(r.getMember());
+			position.add(p);
+		}
+
+		@Override
+		public String toString() {
+			return "MemberInfo{" +
+					"roles='" + roleString + '\'' +
+					", positions='" + positionString + '\'' +
+					'}';
+		}
+	}
+
+	/**
+	 * Class that allows fast creation of read-only table model with String columns
+	 */
+	public static class ReadOnlyTableModel extends DefaultTableModel {
+		@Override
+		public boolean isCellEditable(int row, int column) {
+			return false;
+		}
+
+		@Override
+		public Class<?> getColumnClass(int columnIndex) {
+			return String.class;
+		}
+	}
+
+	/**
+	 * Action handling add button press in properties dialog.
+	 */
+	class AddAction extends JosmAction {
+		AddAction() {
+			super(tr("Add Recommendation"), /* ICON() */ "dialogs/add", tr("Add a recommended key/value pair to your object"),
+					Shortcut.registerShortcut("properties:add", tr("Add Tag"), KeyEvent.VK_A,
+							Shortcut.ALT), false);
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			editHelper.addTag();
+			btnAdd.requestFocusInWindow();
+		}
+	}
+
+	/**
+	 * Action handling edit button press in properties dialog.
+	 * training process dialog/configuration
+	 */
+	class EditActionTrain extends JosmAction implements ListSelectionListener {
+		EditActionTrain() {
+			super(tr("Train a Model"), /* ICON() */ "dialogs/fix", tr("Start the training engine!"),
+					Shortcut.registerShortcut("properties:edit", tr("Edit Tags"), KeyEvent.VK_S,
+							Shortcut.ALT), false);
+			setEnabled(true);
+			updateEnabledState();
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (!isEnabled())
+				return;
+			if (tagTable.getSelectedRowCount() == 1) {
+				int row = tagTable.getSelectedRow();
+				editHelper.editTag(row, false);
+			} else if (membershipTable.getSelectedRowCount() == 1) {
+				int row = membershipTable.getSelectedRow();
+				editHelper.editTag(row, false);
+			} else {
+				editHelper.editTag(1, false);
+			}
+		}
+
+		@Override
+		protected void updateEnabledState() {
+			setEnabled(true);
+		}
+
+		@Override
+		public void valueChanged(ListSelectionEvent e) {
+			updateEnabledState();
+		}
+	}
 }
Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/FrequenceExtractor.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/FrequenceExtractor.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/FrequenceExtractor.java	(revision 33525)
@@ -10,8 +10,8 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMNode;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
@@ -27,176 +27,176 @@
 public class FrequenceExtractor extends DefaultHandler {
 
-    private final List<OSMNode> nodeList; //will be populated with nodes
-    private final List<OSMRelation> relationList;
-    private final Map<String, OSMNode> nodesWithIDs; //map containing IDs as Strings and the corresponding OSMNode objects
-    private final List<OSMWay> wayList;  //populated with ways of the OSM file
-    private final String osmXmlFileName;
-    private OSMNode nodeTmp;
-    private OSMWay wayTmp;
-    private OSMRelation relationTmp;
-    private boolean inWay = false; //when parser is in a way node becomes true in order to track the parser position
-    private boolean inNode = false; //becomes true when the parser is in a simple node
-    private boolean inRelation = false; //becomes true when the parser is in a relarion node
-    private Map<String, Integer> frequency;
-
-    public FrequenceExtractor(String osmXmlFileName) {
-        this.osmXmlFileName = osmXmlFileName;
-        nodeList = new ArrayList<>();
-        wayList = new ArrayList<>();
-        relationList = new ArrayList<>();
-        nodesWithIDs = new HashMap<>();
-        frequency = new HashMap<>();
-        for (int i = 0; i < 100; i++) {
-            frequency.put("", 0);
-        }
-    }
-
-    public void parseDocument() {
-        Main.info("extracting frequencies...");
-        try {
-            Utils.newSafeSAXParser().parse(osmXmlFileName, this);
-        } catch (ParserConfigurationException | IOException | SAXException e) {
-            Main.error(e);
-        }
-    }
-
-    @Override
-    public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
-
-        // if current element is an OSMNode , create new node and populate with the appropriate values
-        if (elementName.equalsIgnoreCase("node")) {
-            nodeTmp = new OSMNode();
-            inNode = true;
-            inWay = false;
-            inRelation = false;
-
-        } else if (elementName.equalsIgnoreCase("way")) {
-            wayTmp = new OSMWay();
-            //wayTmp.setID(attributes.getValue("id"));
-            inWay = true;
-            inNode = false;
-            inRelation = false;
-        } else if (elementName.equalsIgnoreCase("relation")) {
-            relationTmp = new OSMRelation();
-            //relationTmp.setID(attributes.getValue("id"));
-            inRelation = true;
-            inWay = false;
-            inNode = false;
-        } else if (elementName.equalsIgnoreCase("nd")) {
-            //wayTmp.addNodeReference(attributes.getValue("ref"));
-
-        } else if (elementName.equalsIgnoreCase("tag")) {
-
-            if (inNode) {
-                //if the path is in an OSMNode set tagKey and value to the corresponding node
-                nodeTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
-            } else if (inWay) {
-                //else if the path is in an OSM way set tagKey and value to the corresponding way
-                wayTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
-            } else if (inRelation) {
-                //set the key-value pairs of relation tags
-                relationTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
-            }
-
-        } else if (elementName.equalsIgnoreCase("member")) {
-            //relationTmp.addMemberReference(attributes.getValue("ref"));
-        }
-    }
-
-    @Override
-    public void endElement(String s, String s1, String element) throws SAXException {
-        // if end of node element, add to appropriate list
-        if (element.equalsIgnoreCase("node")) {
-            Map<String, String> tags = nodeTmp.getTagKeyValue();
-            if (tags.keySet().contains("name")) {
-                for (Map.Entry<String, String> tag : tags.entrySet()) {
-                    if (tag.getKey().equals("name")) {
-                        //split name value in each white space and store the values separetely. Count each occurance
-                        String name = tag.getValue();
-                        String[] SplitName = name.split("\\s+");
-
-                        for (String split : SplitName) {
-                            //put all splits with zero, at the constructor. put here the incremented values. for tomoro
-                            if (frequency.get(split) != null) {
-                                int k = frequency.get(split) +1;
-                                frequency.put(split, k);
-                            } else {
-                                frequency.put(split, 1);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (element.equalsIgnoreCase("way")) {
-            //name frequency
-            Map<String, String> tags = wayTmp.getTagKeyValue();
-
-            if (tags.keySet().contains("name")) {
-                for (Map.Entry<String, String> tag : tags.entrySet()) {
-                    if (tag.getKey().equals("name")) {
-                        //split name value in each white space and store the values separetely. Count each occurance
-                        String name = tag.getValue();
-                        String[] SplitName = name.split("\\s+");
-                        for (String split : SplitName) {
-                            //put all splits with zero, at the constructor. put here the incremented values. for tomoro
-                            if (frequency.get(split) != null) {
-                                int k = frequency.get(split) +1;
-                                frequency.put(split, k);
-                            } else {
-                                frequency.put(split, 1);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        if (element.equalsIgnoreCase("relation")) {
-            //name frequency
-            Map<String, String> tags = relationTmp.getTagKeyValue();
-
-            if (tags.keySet().contains("name")) {
-                for (Map.Entry<String, String> tag : tags.entrySet()) {
-                    if (tag.getKey().equals("name")) {
-                        //split name value in each white space and store the values separetely. Count each occurance
-                        String name = tag.getValue();
-                        String[] SplitName = name.split("\\s+");
-
-                        for (String split : SplitName) {
-                            //put all splits with zero, at the constructor. put here the incremented values. for tomoro
-                            if (frequency.get(split) != null) {
-                                int k = frequency.get(split) +1;
-                                frequency.put(split, k);
-                            } else {
-                                frequency.put(split, 1);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public List<OSMNode> getNodeList() {
-        return nodeList;
-    }
-
-    public List<OSMWay> getWayList() {
-        return wayList;
-    }
-
-    public List<OSMRelation> getRelationList() {
-        return relationList;
-    }
-
-    public Map<String, OSMNode> getNodesWithIDs() {
-        return nodesWithIDs;
-    }
-
-    //frequency temp
-    public Map<String, Integer> getFrequency() {
-        return frequency;
-    }
+	private final List<OSMNode> nodeList; //will be populated with nodes
+	private final List<OSMRelation> relationList;
+	private final Map<String, OSMNode> nodesWithIDs; //map containing IDs as Strings and the corresponding OSMNode objects
+	private final List<OSMWay> wayList;  //populated with ways of the OSM file
+	private final String osmXmlFileName;
+	private OSMNode nodeTmp;
+	private OSMWay wayTmp;
+	private OSMRelation relationTmp;
+	private boolean inWay = false; //when parser is in a way node becomes true in order to track the parser position
+	private boolean inNode = false; //becomes true when the parser is in a simple node
+	private boolean inRelation = false; //becomes true when the parser is in a relarion node
+	private Map<String, Integer> frequency;
+
+	public FrequenceExtractor(String osmXmlFileName) {
+		this.osmXmlFileName = osmXmlFileName;
+		nodeList = new ArrayList<>();
+		wayList = new ArrayList<>();
+		relationList = new ArrayList<>();
+		nodesWithIDs = new HashMap<>();
+		frequency = new HashMap<>();
+		for (int i = 0; i < 100; i++) {
+			frequency.put("", 0);
+		}
+	}
+
+	public void parseDocument() {
+		Logging.info("extracting frequencies...");
+		try {
+			Utils.newSafeSAXParser().parse(osmXmlFileName, this);
+		} catch (ParserConfigurationException | IOException | SAXException e) {
+			Logging.error(e);
+		}
+	}
+
+	@Override
+	public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
+
+		// if current element is an OSMNode , create new node and populate with the appropriate values
+		if (elementName.equalsIgnoreCase("node")) {
+			nodeTmp = new OSMNode();
+			inNode = true;
+			inWay = false;
+			inRelation = false;
+
+		} else if (elementName.equalsIgnoreCase("way")) {
+			wayTmp = new OSMWay();
+			//wayTmp.setID(attributes.getValue("id"));
+			inWay = true;
+			inNode = false;
+			inRelation = false;
+		} else if (elementName.equalsIgnoreCase("relation")) {
+			relationTmp = new OSMRelation();
+			//relationTmp.setID(attributes.getValue("id"));
+			inRelation = true;
+			inWay = false;
+			inNode = false;
+		} else if (elementName.equalsIgnoreCase("nd")) {
+			//wayTmp.addNodeReference(attributes.getValue("ref"));
+
+		} else if (elementName.equalsIgnoreCase("tag")) {
+
+			if (inNode) {
+				//if the path is in an OSMNode set tagKey and value to the corresponding node
+				nodeTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+			} else if (inWay) {
+				//else if the path is in an OSM way set tagKey and value to the corresponding way
+				wayTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+			} else if (inRelation) {
+				//set the key-value pairs of relation tags
+				relationTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+			}
+
+		} else if (elementName.equalsIgnoreCase("member")) {
+			//relationTmp.addMemberReference(attributes.getValue("ref"));
+		}
+	}
+
+	@Override
+	public void endElement(String s, String s1, String element) throws SAXException {
+		// if end of node element, add to appropriate list
+		if (element.equalsIgnoreCase("node")) {
+			Map<String, String> tags = nodeTmp.getTagKeyValue();
+			if (tags.keySet().contains("name")) {
+				for (Map.Entry<String, String> tag : tags.entrySet()) {
+					if (tag.getKey().equals("name")) {
+						//split name value in each white space and store the values separetely. Count each occurance
+						String name = tag.getValue();
+						String[] SplitName = name.split("\\s+");
+
+						for (String split : SplitName) {
+							//put all splits with zero, at the constructor. put here the incremented values. for tomoro
+							if (frequency.get(split) != null) {
+								int k = frequency.get(split) +1;
+								frequency.put(split, k);
+							} else {
+								frequency.put(split, 1);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		if (element.equalsIgnoreCase("way")) {
+			//name frequency
+			Map<String, String> tags = wayTmp.getTagKeyValue();
+
+			if (tags.keySet().contains("name")) {
+				for (Map.Entry<String, String> tag : tags.entrySet()) {
+					if (tag.getKey().equals("name")) {
+						//split name value in each white space and store the values separetely. Count each occurance
+						String name = tag.getValue();
+						String[] SplitName = name.split("\\s+");
+						for (String split : SplitName) {
+							//put all splits with zero, at the constructor. put here the incremented values. for tomoro
+							if (frequency.get(split) != null) {
+								int k = frequency.get(split) +1;
+								frequency.put(split, k);
+							} else {
+								frequency.put(split, 1);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		if (element.equalsIgnoreCase("relation")) {
+			//name frequency
+			Map<String, String> tags = relationTmp.getTagKeyValue();
+
+			if (tags.keySet().contains("name")) {
+				for (Map.Entry<String, String> tag : tags.entrySet()) {
+					if (tag.getKey().equals("name")) {
+						//split name value in each white space and store the values separetely. Count each occurance
+						String name = tag.getValue();
+						String[] SplitName = name.split("\\s+");
+
+						for (String split : SplitName) {
+							//put all splits with zero, at the constructor. put here the incremented values. for tomoro
+							if (frequency.get(split) != null) {
+								int k = frequency.get(split) +1;
+								frequency.put(split, k);
+							} else {
+								frequency.put(split, 1);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	public List<OSMNode> getNodeList() {
+		return nodeList;
+	}
+
+	public List<OSMWay> getWayList() {
+		return wayList;
+	}
+
+	public List<OSMRelation> getRelationList() {
+		return relationList;
+	}
+
+	public Map<String, OSMNode> getNodesWithIDs() {
+		return nodesWithIDs;
+	}
+
+	//frequency temp
+	public Map<String, Integer> getFrequency() {
+		return frequency;
+	}
 }
Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/LanguageDetector.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/LanguageDetector.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/LanguageDetector.java	(revision 33525)
@@ -9,5 +9,5 @@
 import java.util.logging.Logger;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -23,97 +23,97 @@
 public final class LanguageDetector {
 
-    private static LanguageDetector languageDetector = null;
+	private static LanguageDetector languageDetector = null;
 
-    private LanguageDetector() {
-        //prevent instatiation
-    }
+	private LanguageDetector() {
+		//prevent instatiation
+	}
 
-    public static LanguageDetector getInstance(String languageProfilesPath) {
-        if (languageDetector == null) {
-            languageDetector = new LanguageDetector();
-            loadProfilesFromStream(languageProfilesPath);
-            //profilesLoaded = true;
-        }
-        return languageDetector;
-    }
+	public static LanguageDetector getInstance(String languageProfilesPath) {
+		if (languageDetector == null) {
+			languageDetector = new LanguageDetector();
+			loadProfilesFromStream(languageProfilesPath);
+			//profilesLoaded = true;
+		}
+		return languageDetector;
+	}
 
-    public static void loadProfilesFromStream(String languageProfilesPath) { //create profiles directory in system from stream and load them
+	public static void loadProfilesFromStream(String languageProfilesPath) { //create profiles directory in system from stream and load them
 
-        /*  supported languages
+		/*  supported languages
             el:greek, en:english, de:german, fr:french, es:spanish, ru:russian, tr:turkish, zh-cn:chinese, hi:hindi
-         */
-        InputStream languageProfilesInputStreamEl = LanguageDetector.class.getResourceAsStream("/profiles/el");
-        InputStream languageProfilesInputStreamEn = LanguageDetector.class.getResourceAsStream("/profiles/en");
-        InputStream languageProfilesInputStreamDe = LanguageDetector.class.getResourceAsStream("/profiles/de");
-        InputStream languageProfilesInputStreamFr = LanguageDetector.class.getResourceAsStream("/profiles/fr");
-        InputStream languageProfilesInputStreamEs = LanguageDetector.class.getResourceAsStream("/profiles/es");
-        InputStream languageProfilesInputStreamRu = LanguageDetector.class.getResourceAsStream("/profiles/ru");
-        InputStream languageProfilesInputStreamTr = LanguageDetector.class.getResourceAsStream("/profiles/tr");
-        InputStream languageProfilesInputStreamZh = LanguageDetector.class.getResourceAsStream("/profiles/zh-cn");
-        InputStream languageProfilesInputStreamHi = LanguageDetector.class.getResourceAsStream("/profiles/hi");
-        //InputStream languageProfilesInputStream2 = LanguageDetector.class.getResourceAsStream("/resources/profiles/en");
+		 */
+		InputStream languageProfilesInputStreamEl = LanguageDetector.class.getResourceAsStream("/profiles/el");
+		InputStream languageProfilesInputStreamEn = LanguageDetector.class.getResourceAsStream("/profiles/en");
+		InputStream languageProfilesInputStreamDe = LanguageDetector.class.getResourceAsStream("/profiles/de");
+		InputStream languageProfilesInputStreamFr = LanguageDetector.class.getResourceAsStream("/profiles/fr");
+		InputStream languageProfilesInputStreamEs = LanguageDetector.class.getResourceAsStream("/profiles/es");
+		InputStream languageProfilesInputStreamRu = LanguageDetector.class.getResourceAsStream("/profiles/ru");
+		InputStream languageProfilesInputStreamTr = LanguageDetector.class.getResourceAsStream("/profiles/tr");
+		InputStream languageProfilesInputStreamZh = LanguageDetector.class.getResourceAsStream("/profiles/zh-cn");
+		InputStream languageProfilesInputStreamHi = LanguageDetector.class.getResourceAsStream("/profiles/hi");
+		//InputStream languageProfilesInputStream2 = LanguageDetector.class.getResourceAsStream("/resources/profiles/en");
 
-        if (!new File(languageProfilesPath).exists()) {
-            Utils.mkDirs(new File(languageProfilesPath));
-        }
+		if (!new File(languageProfilesPath).exists()) {
+			Utils.mkDirs(new File(languageProfilesPath));
+		}
 
-        File languageProfilesOutputFileEl = new File(languageProfilesPath + "/el");
-        File languageProfilesOutputFileEn = new File(languageProfilesPath + "/en");
-        File languageProfilesOutputFileDe = new File(languageProfilesPath + "/de");
-        File languageProfilesOutputFileFr = new File(languageProfilesPath + "/fr");
-        File languageProfilesOutputFileEs = new File(languageProfilesPath + "/es");
-        File languageProfilesOutputFileRu = new File(languageProfilesPath + "/ru");
-        File languageProfilesOutputFileTr = new File(languageProfilesPath + "/tr");
-        File languageProfilesOutputFileZh = new File(languageProfilesPath + "/zh-cn");
-        File languageProfilesOutputFileHi = new File(languageProfilesPath + "/hi");
+		File languageProfilesOutputFileEl = new File(languageProfilesPath + "/el");
+		File languageProfilesOutputFileEn = new File(languageProfilesPath + "/en");
+		File languageProfilesOutputFileDe = new File(languageProfilesPath + "/de");
+		File languageProfilesOutputFileFr = new File(languageProfilesPath + "/fr");
+		File languageProfilesOutputFileEs = new File(languageProfilesPath + "/es");
+		File languageProfilesOutputFileRu = new File(languageProfilesPath + "/ru");
+		File languageProfilesOutputFileTr = new File(languageProfilesPath + "/tr");
+		File languageProfilesOutputFileZh = new File(languageProfilesPath + "/zh-cn");
+		File languageProfilesOutputFileHi = new File(languageProfilesPath + "/hi");
 
-        try {
-            languageProfilesOutputFileEl.createNewFile();
-            languageProfilesOutputFileEn.createNewFile();
-            languageProfilesOutputFileDe.createNewFile();
-            languageProfilesOutputFileFr.createNewFile();
-            languageProfilesOutputFileEs.createNewFile();
-            languageProfilesOutputFileRu.createNewFile();
-            languageProfilesOutputFileTr.createNewFile();
-            languageProfilesOutputFileZh.createNewFile();
-            languageProfilesOutputFileHi.createNewFile();
-        } catch (IOException ex) {
-            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
-            Main.error(ex);
-        }
+		try {
+			languageProfilesOutputFileEl.createNewFile();
+			languageProfilesOutputFileEn.createNewFile();
+			languageProfilesOutputFileDe.createNewFile();
+			languageProfilesOutputFileFr.createNewFile();
+			languageProfilesOutputFileEs.createNewFile();
+			languageProfilesOutputFileRu.createNewFile();
+			languageProfilesOutputFileTr.createNewFile();
+			languageProfilesOutputFileZh.createNewFile();
+			languageProfilesOutputFileHi.createNewFile();
+		} catch (IOException ex) {
+			Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+			Logging.error(ex);
+		}
 
-        try {
-            Files.copy(languageProfilesInputStreamEl, languageProfilesOutputFileEl.toPath());
-            Files.copy(languageProfilesInputStreamEn, languageProfilesOutputFileEn.toPath());
-            Files.copy(languageProfilesInputStreamDe, languageProfilesOutputFileDe.toPath());
-            Files.copy(languageProfilesInputStreamFr, languageProfilesOutputFileFr.toPath());
-            Files.copy(languageProfilesInputStreamEs, languageProfilesOutputFileEs.toPath());
-            Files.copy(languageProfilesInputStreamRu, languageProfilesOutputFileRu.toPath());
-            Files.copy(languageProfilesInputStreamTr, languageProfilesOutputFileTr.toPath());
-            Files.copy(languageProfilesInputStreamZh, languageProfilesOutputFileZh.toPath());
-            Files.copy(languageProfilesInputStreamHi, languageProfilesOutputFileHi.toPath());
-        } catch (IOException ex) {
-            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
-            Main.error(ex);
-        }
+		try {
+			Files.copy(languageProfilesInputStreamEl, languageProfilesOutputFileEl.toPath());
+			Files.copy(languageProfilesInputStreamEn, languageProfilesOutputFileEn.toPath());
+			Files.copy(languageProfilesInputStreamDe, languageProfilesOutputFileDe.toPath());
+			Files.copy(languageProfilesInputStreamFr, languageProfilesOutputFileFr.toPath());
+			Files.copy(languageProfilesInputStreamEs, languageProfilesOutputFileEs.toPath());
+			Files.copy(languageProfilesInputStreamRu, languageProfilesOutputFileRu.toPath());
+			Files.copy(languageProfilesInputStreamTr, languageProfilesOutputFileTr.toPath());
+			Files.copy(languageProfilesInputStreamZh, languageProfilesOutputFileZh.toPath());
+			Files.copy(languageProfilesInputStreamHi, languageProfilesOutputFileHi.toPath());
+		} catch (IOException ex) {
+			Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+			Logging.error(ex);
+		}
 
-        try {
-            DetectorFactory.loadProfile(languageProfilesPath);
-        } catch (LangDetectException ex) {
-            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
-            Main.error(ex);
-        }
-    }
+		try {
+			DetectorFactory.loadProfile(languageProfilesPath);
+		} catch (LangDetectException ex) {
+			Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+			Logging.error(ex);
+		}
+	}
 
-    public String detect(String text) {
-        try {
-            Detector detector = DetectorFactory.create();
-            detector.append(text);
-            return detector.detect();
-        } catch (LangDetectException ex) {
-            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
-            Main.error(ex);
-            return "en"; //default lang to return if anything goes wrong at detection
-        }
-    }
+	public String detect(String text) {
+		try {
+			Detector detector = DetectorFactory.create();
+			detector.append(text);
+			return detector.detect();
+		} catch (LangDetectException ex) {
+			Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+			Logging.error(ex);
+			return "en"; //default lang to return if anything goes wrong at detection
+		}
+	}
 }
Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/OSMParser.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/OSMParser.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/OSMParser.java	(revision 33525)
@@ -21,8 +21,8 @@
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMNode;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
@@ -45,179 +45,179 @@
 public class OSMParser extends DefaultHandler {
 
-    //private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OSMParser.class);
-
-    //change from wgs84 to cartesian for later processing of the geometry
-    private static final CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
-    private static final CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
-    private final GeometryFactory geometryFactory = new GeometryFactory();
-    private static MathTransform transform = null;
-    private final List<OSMNode> nodeList; //will be populated with nodes
-    private final List<OSMRelation> relationList;
-    private final Map<String, OSMNode> nodesWithIDs; //map containing IDs as Strings and the corresponding OSMNode objects
-    private final List<OSMWay> wayList;  //populated with ways of the OSM file
-    private final String osmXmlFileName;
-    private OSMNode nodeTmp; //variable to hold the node object
-    private OSMWay wayTmp;   //variable to hold the way object
-    private OSMRelation relationTmp;
-    private boolean inWay = false; //when parser is in a way node becomes true in order to track the parser position
-    private boolean inNode = false; //becomes true when the parser is in a simple node
-    private boolean inRelation = false; //becomes true when the parser is in a relarion node
-
-    public OSMParser(String osmXmlFileName) {
-        this.osmXmlFileName = osmXmlFileName;
-        nodeList = new ArrayList<>();
-        wayList = new ArrayList<>();
-        relationList = new ArrayList<>();
-        nodesWithIDs = new HashMap<>();
-        try {
-            transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
-        } catch (FactoryException ex) {
-            Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
-        }
-    }
-
-    public void parseDocument() {
-        try {
-            Utils.newSafeSAXParser().parse(osmXmlFileName, this);
-        } catch (ParserConfigurationException | SAXException | IOException e) {
-            Main.error(e);
-        }
-    }
-
-    @Override
-    public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
-
-        // if current element is an OSMNode , create new node and populate with the appropriate values
-        if (elementName.equalsIgnoreCase("node")) {
-            nodeTmp = new OSMNode();
-            nodeTmp.setID(attributes.getValue("id"));
-            nodeTmp.setUser(attributes.getValue("user"));
-            //parse geometry
-            double longitude = Double.parseDouble(attributes.getValue("lon"));
-            double latitude = Double.parseDouble(attributes.getValue("lat"));
-
-            Coordinate targetGeometry = null;
-            Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
-            try {
-                targetGeometry = JTS.transform(sourceCoordinate, null, transform);
-            } catch (MismatchedDimensionException | TransformException ex) {
-                Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
-            }
-
-            //create geometry object
-            Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-            nodeTmp.setGeometry(geom);
-            inNode = true;
-            inWay = false;
-            inRelation = false;
-
-        } else if (elementName.equalsIgnoreCase("way")) {
-            wayTmp = new OSMWay();
-            wayTmp.setID(attributes.getValue("id"));
-
-            if (attributes.getValue("user") != null) {
-                wayTmp.setUser(attributes.getValue("user"));
-            } else {
-                wayTmp.setUser("undefined");
-            }
-
-            inWay = true;
-            inNode = false;
-            inRelation = false;
-        } else if (elementName.equalsIgnoreCase("relation")) {
-            relationTmp = new OSMRelation();
-            relationTmp.setID(attributes.getValue("id"));
-            inRelation = true;
-            inWay = false;
-            inNode = false;
-        } else if (elementName.equalsIgnoreCase("nd")) {
-            wayTmp.addNodeReference(attributes.getValue("ref"));
-
-        } else if (elementName.equalsIgnoreCase("tag")) {
-
-            if (inNode) {
-                //if the path is in an OSMNode set tagKey and value to the corresponding node
-                nodeTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
-            } else if (inWay) {
-                //else if the path is in an OSM way set tagKey and value to the corresponding way
-                wayTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
-            } else if (inRelation) {
-                //set the key-value pairs of relation tags
-                relationTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
-            }
-        } else if (elementName.equalsIgnoreCase("member")) {
-            relationTmp.addMemberReference(attributes.getValue("ref"));
-        }
-    }
-
-    @Override
-    public void endElement(String s, String s1, String element) throws SAXException {
-        // if end of node element, add to appropriate list
-        if (element.equalsIgnoreCase("node")) {
-            nodeList.add(nodeTmp);
-            nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
-        }
-
-        if (element.equalsIgnoreCase("way")) {
-
-            //construct the Way geometry from each node of the node references
-            List<String> references = wayTmp.getNodeReferences();
-
-            for (String entry: references) {
-                Geometry geometry = nodesWithIDs.get(entry).getGeometry(); //get the geometry of the node with ID=entry
-                wayTmp.addNodeGeometry(geometry); //add the node geometry in this way
-
-            }
-            Geometry geom = geometryFactory.buildGeometry(wayTmp.getNodeGeometries());
-
-            if ((wayTmp.getNumberOfNodes() > 3) &&
-                    wayTmp.getNodeGeometries().get(0).equals(wayTmp.getNodeGeometries()
-                            .get(wayTmp.getNodeGeometries().size()-1))) {
-                //checks if the beginning and ending node are the same and the number of nodes are more than 3.
-                //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
-
-                if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))) {
-                    //this is not a barrier nor a road, so construct a polygon geometry
-
-                    LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
-                    Polygon poly = new Polygon(linear, null, geometryFactory);
-                    wayTmp.setGeometry(poly);
-                } else {
-                    //it is either a barrier or a road, so construct a linear ring geometry
-                    LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
-                    wayTmp.setGeometry(linear);
-                }
-            } else if (wayTmp.getNumberOfNodes() > 1) {
-                //it is an open geometry with more than one nodes, make it linestring
-
-                LineString lineString = geometryFactory.createLineString(geom.getCoordinates());
-                wayTmp.setGeometry(lineString);
-            } else { //we assume all the rest geometries are points
-                //some ways happen to have only one point. Construct a  Point.
-                Point point = geometryFactory.createPoint(geom.getCoordinate());
-                wayTmp.setGeometry(point);
-            }
-            wayList.add(wayTmp);
-        }
-
-        if (element.equalsIgnoreCase("relation")) {
-            relationList.add(relationTmp);
-        }
-    }
-
-    public List<OSMNode> getNodeList() {
-        return nodeList;
-    }
-
-    public List<OSMWay> getWayList() {
-        return wayList;
-    }
-
-    public List<OSMRelation> getRelationList() {
-        return relationList;
-    }
-
-    public Map<String, OSMNode> getNodesWithIDs() {
-        return nodesWithIDs;
-    }
+	//private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OSMParser.class);
+
+	//change from wgs84 to cartesian for later processing of the geometry
+	private static final CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
+	private static final CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
+	private final GeometryFactory geometryFactory = new GeometryFactory();
+	private static MathTransform transform = null;
+	private final List<OSMNode> nodeList; //will be populated with nodes
+	private final List<OSMRelation> relationList;
+	private final Map<String, OSMNode> nodesWithIDs; //map containing IDs as Strings and the corresponding OSMNode objects
+	private final List<OSMWay> wayList;  //populated with ways of the OSM file
+	private final String osmXmlFileName;
+	private OSMNode nodeTmp; //variable to hold the node object
+	private OSMWay wayTmp;   //variable to hold the way object
+	private OSMRelation relationTmp;
+	private boolean inWay = false; //when parser is in a way node becomes true in order to track the parser position
+	private boolean inNode = false; //becomes true when the parser is in a simple node
+	private boolean inRelation = false; //becomes true when the parser is in a relarion node
+
+	public OSMParser(String osmXmlFileName) {
+		this.osmXmlFileName = osmXmlFileName;
+		nodeList = new ArrayList<>();
+		wayList = new ArrayList<>();
+		relationList = new ArrayList<>();
+		nodesWithIDs = new HashMap<>();
+		try {
+			transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+		} catch (FactoryException ex) {
+			Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
+		}
+	}
+
+	public void parseDocument() {
+		try {
+			Utils.newSafeSAXParser().parse(osmXmlFileName, this);
+		} catch (ParserConfigurationException | SAXException | IOException e) {
+			Logging.error(e);
+		}
+	}
+
+	@Override
+	public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
+
+		// if current element is an OSMNode , create new node and populate with the appropriate values
+		if (elementName.equalsIgnoreCase("node")) {
+			nodeTmp = new OSMNode();
+			nodeTmp.setID(attributes.getValue("id"));
+			nodeTmp.setUser(attributes.getValue("user"));
+			//parse geometry
+			double longitude = Double.parseDouble(attributes.getValue("lon"));
+			double latitude = Double.parseDouble(attributes.getValue("lat"));
+
+			Coordinate targetGeometry = null;
+			Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
+			try {
+				targetGeometry = JTS.transform(sourceCoordinate, null, transform);
+			} catch (MismatchedDimensionException | TransformException ex) {
+				Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
+			}
+
+			//create geometry object
+			Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
+			nodeTmp.setGeometry(geom);
+			inNode = true;
+			inWay = false;
+			inRelation = false;
+
+		} else if (elementName.equalsIgnoreCase("way")) {
+			wayTmp = new OSMWay();
+			wayTmp.setID(attributes.getValue("id"));
+
+			if (attributes.getValue("user") != null) {
+				wayTmp.setUser(attributes.getValue("user"));
+			} else {
+				wayTmp.setUser("undefined");
+			}
+
+			inWay = true;
+			inNode = false;
+			inRelation = false;
+		} else if (elementName.equalsIgnoreCase("relation")) {
+			relationTmp = new OSMRelation();
+			relationTmp.setID(attributes.getValue("id"));
+			inRelation = true;
+			inWay = false;
+			inNode = false;
+		} else if (elementName.equalsIgnoreCase("nd")) {
+			wayTmp.addNodeReference(attributes.getValue("ref"));
+
+		} else if (elementName.equalsIgnoreCase("tag")) {
+
+			if (inNode) {
+				//if the path is in an OSMNode set tagKey and value to the corresponding node
+				nodeTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+			} else if (inWay) {
+				//else if the path is in an OSM way set tagKey and value to the corresponding way
+				wayTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+			} else if (inRelation) {
+				//set the key-value pairs of relation tags
+				relationTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+			}
+		} else if (elementName.equalsIgnoreCase("member")) {
+			relationTmp.addMemberReference(attributes.getValue("ref"));
+		}
+	}
+
+	@Override
+	public void endElement(String s, String s1, String element) throws SAXException {
+		// if end of node element, add to appropriate list
+		if (element.equalsIgnoreCase("node")) {
+			nodeList.add(nodeTmp);
+			nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
+		}
+
+		if (element.equalsIgnoreCase("way")) {
+
+			//construct the Way geometry from each node of the node references
+			List<String> references = wayTmp.getNodeReferences();
+
+			for (String entry: references) {
+				Geometry geometry = nodesWithIDs.get(entry).getGeometry(); //get the geometry of the node with ID=entry
+				wayTmp.addNodeGeometry(geometry); //add the node geometry in this way
+
+			}
+			Geometry geom = geometryFactory.buildGeometry(wayTmp.getNodeGeometries());
+
+			if ((wayTmp.getNumberOfNodes() > 3) &&
+					wayTmp.getNodeGeometries().get(0).equals(wayTmp.getNodeGeometries()
+							.get(wayTmp.getNodeGeometries().size()-1))) {
+				//checks if the beginning and ending node are the same and the number of nodes are more than 3.
+				//the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
+
+				if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))) {
+					//this is not a barrier nor a road, so construct a polygon geometry
+
+					LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+					Polygon poly = new Polygon(linear, null, geometryFactory);
+					wayTmp.setGeometry(poly);
+				} else {
+					//it is either a barrier or a road, so construct a linear ring geometry
+					LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+					wayTmp.setGeometry(linear);
+				}
+			} else if (wayTmp.getNumberOfNodes() > 1) {
+				//it is an open geometry with more than one nodes, make it linestring
+
+				LineString lineString = geometryFactory.createLineString(geom.getCoordinates());
+				wayTmp.setGeometry(lineString);
+			} else { //we assume all the rest geometries are points
+				//some ways happen to have only one point. Construct a  Point.
+				Point point = geometryFactory.createPoint(geom.getCoordinate());
+				wayTmp.setGeometry(point);
+			}
+			wayList.add(wayTmp);
+		}
+
+		if (element.equalsIgnoreCase("relation")) {
+			relationList.add(relationTmp);
+		}
+	}
+
+	public List<OSMNode> getNodeList() {
+		return nodeList;
+	}
+
+	public List<OSMWay> getWayList() {
+		return wayList;
+	}
+
+	public List<OSMRelation> getRelationList() {
+		return relationList;
+	}
+
+	public Map<String, OSMNode> getNodesWithIDs() {
+		return nodesWithIDs;
+	}
 }
Index: applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/HistoryParser.java
===================================================================
--- applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/HistoryParser.java	(revision 33524)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/HistoryParser.java	(revision 33525)
@@ -24,9 +24,9 @@
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMNode;
 import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.w3c.dom.Node;
@@ -48,217 +48,217 @@
  */
 public class HistoryParser {
-    private static final String OSM_API = OsmApi.getOsmApi().getBaseUrl();
-    private static final CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
-    private static final CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
-    private static final GeometryFactory geometryFactory = new GeometryFactory();
-    private MathTransform transform;
-    private OSMNode nodeTmp;
-
-    private final List<OSMNode> nodeList;
-    private final Map<String, OSMNode> nodesWithIDs;
-    private final List<OSMWay> wayList;
-    private OSMWay wayTmp;
-    private final String username;
-
-    /**
-     * Constructs a new {@code HistoryParser}.
-     * @param username user name
-     */
-    public HistoryParser(String username) {
-        this.username = username;
-        transform = null;
-        try {
-            transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
-        } catch (FactoryException ex) {
-            Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-        }
-        nodeList = new ArrayList<>();
-        nodesWithIDs = new HashMap<>();
-        wayList = new ArrayList<>();
-    }
-
-    public void historyParse(String timeInterval) {
-
-        HashSet<String> changesetIDsList = new HashSet<>();
-
-        try {
-            String osmUrl = OSM_API + "changesets?display_name=" + username + "&time=" + timeInterval;
-            InputStream xml = HttpClient.create(new URL(osmUrl)).connect().getContent();
-            NodeList nodes = Utils.parseSafeDOM(xml).getElementsByTagName("changeset");
-
-            Main.debug("changeset size "+ nodes.getLength());
-            for (int i = 0; i < nodes.getLength(); i++) {
-                Main.debug("attributes of " + i + "th changeset");
-                String id = nodes.item(i).getAttributes().item(3).toString();
-                Main.debug("id:" + nodes.item(i).getAttributes().item(3));
-                id = stripQuotes(id);
-                changesetIDsList.add(id);
-            }
-
-            for (String id : changesetIDsList) {
-                getChangesetByID(id);
-            }
-        } catch (IOException | ParserConfigurationException | SAXException ex) {
-            Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-        }
-    }
-
-    private void getChangesetByID(String id) {
-        try {
-            String changesetByIDURL = OSM_API+ "changeset/" + id + "/download";
-            InputStream xml = HttpClient.create(new URL(changesetByIDURL)).connect().getContent();
-            Node osmChange = Utils.parseSafeDOM(xml).getFirstChild();
-
-            //get all nodes first, in order to be able to call all nodes references and create the geometries
-            for (int i = 0; i < osmChange.getChildNodes().getLength(); i++) {
-                String changeType = osmChange.getChildNodes().item(i).getNodeName();
-                if (!(changeType.equals("#text") || changeType.equals("delete"))) {
-
-                    NodeList changeChilds = osmChange.getChildNodes().item(i).getChildNodes();
-
-                    Node osmObject = changeChilds.item(1);
-
-                    if (osmObject.getNodeName().equals("node")) {
-                        //node data
-                        nodeTmp = new OSMNode();
-                        nodeTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());
-
-                        //parse geometry
-                        double longitude = Double.parseDouble(osmObject.getAttributes().getNamedItem("lon").getNodeValue());
-                        double latitude = Double.parseDouble(osmObject.getAttributes().getNamedItem("lat").getNodeValue());
-                        Coordinate targetGeometry = null;
-                        Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
-                        try {
-                            targetGeometry = JTS.transform(sourceCoordinate, null, transform);
-                        } catch (MismatchedDimensionException | TransformException ex) {
-                            Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-                        }
-
-                        //create geometry object
-                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-                        nodeTmp.setGeometry(geom);
-
-                        nodeList.add(nodeTmp);
-                        nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
-                    }
-                }
-            }
-
-            for (int i = 0; i < osmChange.getChildNodes().getLength(); i++) {
-                String changeType = osmChange.getChildNodes().item(i).getNodeName();
-                if (!(changeType.equals("#text") || changeType.equals("delete"))) {
-                    NodeList changeChilds = osmChange.getChildNodes().item(i).getChildNodes();
-
-                    Node osmObject = changeChilds.item(1);
-                    if (osmObject.getNodeName().equals("way")) {
-
-                        //get way data
-                        wayTmp = new OSMWay();
-                        wayTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());
-                        // extract tags, then set tags to osm object
-                        Main.debug("\n\nWAY: " + wayTmp.getID());
-                        for (int l = 0; l < osmObject.getChildNodes().getLength(); l++) {
-                            String wayChild = osmObject.getChildNodes().item(l).getNodeName();
-
-                            if (wayChild.equals("tag")) {
-                                String key = osmObject.getChildNodes().item(l).getAttributes().getNamedItem("k").getNodeValue();
-                                String value = osmObject.getChildNodes().item(l).getAttributes().getNamedItem("v").getNodeValue();
-                                System.out.println("key: " + key + " value: " + value);
-                                wayTmp.setTagKeyValue(key, value);
-                            } else if (wayChild.equals("nd")) {
-                                wayTmp.addNodeReference(osmObject.getChildNodes().item(l).getAttributes().getNamedItem("ref").getNodeValue());
-                            }
-                        }
-
-                        //construct the Way geometry from each node of the node references
-                        List<String> references = wayTmp.getNodeReferences();
-
-                        for (String entry: references) {
-                            if (nodesWithIDs.containsKey(entry)) {
-                                Geometry geometry = nodesWithIDs.get(entry).getGeometry(); //get the geometry of the node with ID=entry
-                                wayTmp.addNodeGeometry(geometry); //add the node geometry in this way
-                            } else {
-                                Main.debug("nodes with ids, no entry " + entry);
-                                getNodeFromAPI(entry);
-                            }
-                        }
-
-                        Geometry geom = geometryFactory.buildGeometry(wayTmp.getNodeGeometries());
-                        if ((wayTmp.getNodeGeometries().size() > 3) &&
-                                wayTmp.getNodeGeometries().get(0).equals(wayTmp.getNodeGeometries()
-                                        .get(wayTmp.getNodeGeometries().size()-1))) {
-                            //checks if the beginning and ending node are the same and the number of nodes are more than 3.
-                            //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
-
-                            if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))) {
-                                //this is not a barrier nor a road, so construct a polygon geometry
-
-                                LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
-                                Polygon poly = new Polygon(linear, null, geometryFactory);
-                                wayTmp.setGeometry(poly);
-                            } else {
-                                //it is either a barrier or a road, so construct a linear ring geometry
-                                LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
-                                wayTmp.setGeometry(linear);
-                            }
-                        } else if (wayTmp.getNodeGeometries().size() > 1) {
-                            //it is an open geometry with more than one nodes, make it linestring
-
-                            LineString lineString = geometryFactory.createLineString(geom.getCoordinates());
-                            wayTmp.setGeometry(lineString);
-                        } else { //we assume all the rest geometries are points
-                            //some ways happen to have only one point. Construct a  Point.
-                            Point point = geometryFactory.createPoint(geom.getCoordinate());
-                            wayTmp.setGeometry(point);
-                        }
-                        wayList.add(wayTmp);
-                    }
-                }
-            }
-        } catch (IOException | ParserConfigurationException | SAXException ex) {
-            Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-        }
-    }
-
-    private String stripQuotes(String id) {
-        return id.substring(4, id.length()-1);
-    }
-
-    private void getNodeFromAPI(String nodeID) {
-        try {
-            String osmUrl = OSM_API + "node/" + nodeID;
-            InputStream xml = HttpClient.create(new URL(osmUrl)).connect().getContent();
-            NodeList nodes = Utils.parseSafeDOM(xml).getElementsByTagName("node");
-            String lat = nodes.item(0).getAttributes().getNamedItem("lat").getNodeValue();
-            String lon = nodes.item(0).getAttributes().getNamedItem("lon").getNodeValue();
-
-            nodeTmp = new OSMNode();
-            nodeTmp.setID(nodeID);
-
-            //parse geometry
-            double longitude = Double.parseDouble(lon);
-            double latitude = Double.parseDouble(lat);
-            Coordinate targetGeometry = null;
-            Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
-            try {
-                targetGeometry = JTS.transform(sourceCoordinate, null, transform);
-            } catch (MismatchedDimensionException | TransformException ex) {
-                Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-            }
-
-            //create geometry object
-            Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-            nodeTmp.setGeometry(geom);
-
-            nodeList.add(nodeTmp);
-            nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
-
-        } catch (IOException | ParserConfigurationException | SAXException ex) {
-            Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-        }
-    }
-
-    public List<OSMWay> getWayList() {
-        return wayList;
-    }
+	private static final String OSM_API = OsmApi.getOsmApi().getBaseUrl();
+	private static final CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
+	private static final CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
+	private static final GeometryFactory geometryFactory = new GeometryFactory();
+	private MathTransform transform;
+	private OSMNode nodeTmp;
+
+	private final List<OSMNode> nodeList;
+	private final Map<String, OSMNode> nodesWithIDs;
+	private final List<OSMWay> wayList;
+	private OSMWay wayTmp;
+	private final String username;
+
+	/**
+	 * Constructs a new {@code HistoryParser}.
+	 * @param username user name
+	 */
+	public HistoryParser(String username) {
+		this.username = username;
+		transform = null;
+		try {
+			transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+		} catch (FactoryException ex) {
+			Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
+		}
+		nodeList = new ArrayList<>();
+		nodesWithIDs = new HashMap<>();
+		wayList = new ArrayList<>();
+	}
+
+	public void historyParse(String timeInterval) {
+
+		HashSet<String> changesetIDsList = new HashSet<>();
+
+		try {
+			String osmUrl = OSM_API + "changesets?display_name=" + username + "&time=" + timeInterval;
+			InputStream xml = HttpClient.create(new URL(osmUrl)).connect().getContent();
+			NodeList nodes = Utils.parseSafeDOM(xml).getElementsByTagName("changeset");
+
+			Logging.debug("changeset size "+ nodes.getLength());
+			for (int i = 0; i < nodes.getLength(); i++) {
+				Logging.debug("attributes of " + i + "th changeset");
+				String id = nodes.item(i).getAttributes().item(3).toString();
+				Logging.debug("id:" + nodes.item(i).getAttributes().item(3));
+				id = stripQuotes(id);
+				changesetIDsList.add(id);
+			}
+
+			for (String id : changesetIDsList) {
+				getChangesetByID(id);
+			}
+		} catch (IOException | ParserConfigurationException | SAXException ex) {
+			Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
+		}
+	}
+
+	private void getChangesetByID(String id) {
+		try {
+			String changesetByIDURL = OSM_API+ "changeset/" + id + "/download";
+			InputStream xml = HttpClient.create(new URL(changesetByIDURL)).connect().getContent();
+			Node osmChange = Utils.parseSafeDOM(xml).getFirstChild();
+
+			//get all nodes first, in order to be able to call all nodes references and create the geometries
+			for (int i = 0; i < osmChange.getChildNodes().getLength(); i++) {
+				String changeType = osmChange.getChildNodes().item(i).getNodeName();
+				if (!(changeType.equals("#text") || changeType.equals("delete"))) {
+
+					NodeList changeChilds = osmChange.getChildNodes().item(i).getChildNodes();
+
+					Node osmObject = changeChilds.item(1);
+
+					if (osmObject.getNodeName().equals("node")) {
+						//node data
+						nodeTmp = new OSMNode();
+						nodeTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());
+
+						//parse geometry
+						double longitude = Double.parseDouble(osmObject.getAttributes().getNamedItem("lon").getNodeValue());
+						double latitude = Double.parseDouble(osmObject.getAttributes().getNamedItem("lat").getNodeValue());
+						Coordinate targetGeometry = null;
+						Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
+						try {
+							targetGeometry = JTS.transform(sourceCoordinate, null, transform);
+						} catch (MismatchedDimensionException | TransformException ex) {
+							Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
+						}
+
+						//create geometry object
+						Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
+						nodeTmp.setGeometry(geom);
+
+						nodeList.add(nodeTmp);
+						nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
+					}
+				}
+			}
+
+			for (int i = 0; i < osmChange.getChildNodes().getLength(); i++) {
+				String changeType = osmChange.getChildNodes().item(i).getNodeName();
+				if (!(changeType.equals("#text") || changeType.equals("delete"))) {
+					NodeList changeChilds = osmChange.getChildNodes().item(i).getChildNodes();
+
+					Node osmObject = changeChilds.item(1);
+					if (osmObject.getNodeName().equals("way")) {
+
+						//get way data
+						wayTmp = new OSMWay();
+						wayTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());
+						// extract tags, then set tags to osm object
+						Logging.debug("\n\nWAY: " + wayTmp.getID());
+						for (int l = 0; l < osmObject.getChildNodes().getLength(); l++) {
+							String wayChild = osmObject.getChildNodes().item(l).getNodeName();
+
+							if (wayChild.equals("tag")) {
+								String key = osmObject.getChildNodes().item(l).getAttributes().getNamedItem("k").getNodeValue();
+								String value = osmObject.getChildNodes().item(l).getAttributes().getNamedItem("v").getNodeValue();
+								System.out.println("key: " + key + " value: " + value);
+								wayTmp.setTagKeyValue(key, value);
+							} else if (wayChild.equals("nd")) {
+								wayTmp.addNodeReference(osmObject.getChildNodes().item(l).getAttributes().getNamedItem("ref").getNodeValue());
+							}
+						}
+
+						//construct the Way geometry from each node of the node references
+						List<String> references = wayTmp.getNodeReferences();
+
+						for (String entry: references) {
+							if (nodesWithIDs.containsKey(entry)) {
+								Geometry geometry = nodesWithIDs.get(entry).getGeometry(); //get the geometry of the node with ID=entry
+								wayTmp.addNodeGeometry(geometry); //add the node geometry in this way
+							} else {
+								Logging.debug("nodes with ids, no entry " + entry);
+								getNodeFromAPI(entry);
+							}
+						}
+
+						Geometry geom = geometryFactory.buildGeometry(wayTmp.getNodeGeometries());
+						if ((wayTmp.getNodeGeometries().size() > 3) &&
+								wayTmp.getNodeGeometries().get(0).equals(wayTmp.getNodeGeometries()
+										.get(wayTmp.getNodeGeometries().size()-1))) {
+							//checks if the beginning and ending node are the same and the number of nodes are more than 3.
+							//the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
+
+							if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))) {
+								//this is not a barrier nor a road, so construct a polygon geometry
+
+								LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+								Polygon poly = new Polygon(linear, null, geometryFactory);
+								wayTmp.setGeometry(poly);
+							} else {
+								//it is either a barrier or a road, so construct a linear ring geometry
+								LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+								wayTmp.setGeometry(linear);
+							}
+						} else if (wayTmp.getNodeGeometries().size() > 1) {
+							//it is an open geometry with more than one nodes, make it linestring
+
+							LineString lineString = geometryFactory.createLineString(geom.getCoordinates());
+							wayTmp.setGeometry(lineString);
+						} else { //we assume all the rest geometries are points
+							//some ways happen to have only one point. Construct a  Point.
+							Point point = geometryFactory.createPoint(geom.getCoordinate());
+							wayTmp.setGeometry(point);
+						}
+						wayList.add(wayTmp);
+					}
+				}
+			}
+		} catch (IOException | ParserConfigurationException | SAXException ex) {
+			Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
+		}
+	}
+
+	private String stripQuotes(String id) {
+		return id.substring(4, id.length()-1);
+	}
+
+	private void getNodeFromAPI(String nodeID) {
+		try {
+			String osmUrl = OSM_API + "node/" + nodeID;
+			InputStream xml = HttpClient.create(new URL(osmUrl)).connect().getContent();
+			NodeList nodes = Utils.parseSafeDOM(xml).getElementsByTagName("node");
+			String lat = nodes.item(0).getAttributes().getNamedItem("lat").getNodeValue();
+			String lon = nodes.item(0).getAttributes().getNamedItem("lon").getNodeValue();
+
+			nodeTmp = new OSMNode();
+			nodeTmp.setID(nodeID);
+
+			//parse geometry
+			double longitude = Double.parseDouble(lon);
+			double latitude = Double.parseDouble(lat);
+			Coordinate targetGeometry = null;
+			Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
+			try {
+				targetGeometry = JTS.transform(sourceCoordinate, null, transform);
+			} catch (MismatchedDimensionException | TransformException ex) {
+				Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
+			}
+
+			//create geometry object
+			Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
+			nodeTmp.setGeometry(geom);
+
+			nodeList.add(nodeTmp);
+			nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
+
+		} catch (IOException | ParserConfigurationException | SAXException ex) {
+			Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
+		}
+	}
+
+	public List<OSMWay> getWayList() {
+		return wayList;
+	}
 }
