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 33525)
+++ applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java	(revision 33579)
@@ -107,4 +107,5 @@
 //import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.gui.util.WindowGeometry;
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.io.XmlWriter;
@@ -125,5 +126,4 @@
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.openstreetmap.josm.tools.WindowGeometry;
 
 import com.vividsolutions.jts.geom.Coordinate;
@@ -146,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 = 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;
-		}
-	}
+             */
+            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;
+        }
+    }
 }
