Index: /applications/editors/josm/plugins/OSMRecPlugin/.checkstyle
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/.checkstyle	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/.checkstyle	(revision 32404)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <local-check-config name="JOSM" location="/JOSM/tools/checkstyle/josm_checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="JOSM" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+  <filter name="DerivedFiles" enabled="true"/>
+  <filter name="FilesFromPackage" enabled="true">
+    <filter-data value="data"/>
+    <filter-data value="images"/>
+    <filter-data value="styles"/>
+    <filter-data value="resources"/>
+    <filter-data value="scripts"/>
+  </filter>
+</fileset-config>
Index: /applications/editors/josm/plugins/OSMRecPlugin/.project
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/.project	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/.project	(revision 32404)
@@ -16,7 +16,13 @@
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
 	</natures>
 </projectDescription>
Index: /applications/editors/josm/plugins/OSMRecPlugin/.settings/org.sonarlint.eclipse.core.prefs
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/.settings/org.sonarlint.eclipse.core.prefs	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/.settings/org.sonarlint.eclipse.core.prefs	(revision 32404)
@@ -0,0 +1,5 @@
+autoEnabled=true
+eclipse.preferences.version=1
+extraProperties=
+moduleKey=josm-plugins
+serverId=josm
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/MenuExportAction.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/MenuExportAction.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/MenuExportAction.java	(revision 32404)
@@ -1,11 +1,14 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec;
 
 import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.event.ActionEvent;
+
 import org.openstreetmap.josm.actions.JosmAction;
 
 /**
  * Exports the OSMRec toggle dialog.
- * 
+ *
  * @author imis-nkarag
  *
@@ -16,9 +19,9 @@
      * Constructs a new {@code MenuExportAction}.
      */
-    public MenuExportAction(){
-        super(tr("OSM Recommendation"), "dialogs/logo-osmrec.png", 
-              tr("Recommend categories to your newly created instances."), null, false);
+    public MenuExportAction() {
+        super(tr("OSM Recommendation"), "dialogs/logo-osmrec.png",
+                tr("Recommend categories to your newly created instances."), null, false);
     }
-        
+
     @Override
     public void actionPerformed(ActionEvent arg0) {
@@ -26,5 +29,5 @@
             OSMRecToggleDialog pro = new OSMRecToggleDialog();
             OSMRecPlugin.getCurrentMapFrame().addToggleDialog(pro);
-        }       
+        }
     }
 }
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPlugin.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPlugin.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPlugin.java	(revision 32404)
@@ -1,3 +1,3 @@
-
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec;
 
@@ -6,58 +6,48 @@
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
-//import org.openstreetmap.josm.gui.dialogs.properties.PropertiesDialog;
 
-/** 
- * 
+/**
+ *
  * @author imis-nkarag
  */
+public class OSMRecPlugin extends Plugin {
 
-public class OSMRecPlugin extends Plugin{
-    
     private final MenuExportAction menuExportAction;
     private static MapFrame mapFrame;
     public OSMRecPlugin plugin;
-    
-    
-    public OSMRecPlugin(PluginInformation info) {       
+
+    public OSMRecPlugin(PluginInformation info) { // NO_UCD (unused code)
         super(info);
-        System.out.println(getPluginDir());
         menuExportAction = new MenuExportAction();
         Main.main.menu.toolsMenu.add(menuExportAction);
     }
-   
-    /**
-     * Called when the JOSM map frame is created or destroyed.
-     * @param oldFrame
-     * @param newFrame
-     */
+
     @Override
-    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {             
+    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
         if (oldFrame == null && newFrame != null) { // map frame added
-            System.out.println("mapFrameInitialized");
             setCurrentMapFrame(newFrame);
             setState(this);
         }
     }
-    
-    private void setCurrentMapFrame(MapFrame newFrame){
+
+    private void setCurrentMapFrame(MapFrame newFrame) {
         OSMRecPlugin.mapFrame = newFrame;
     }
-    
+
     public static MapFrame getCurrentMapFrame() {
         return mapFrame;
     }
-    
-    private void setState(OSMRecPlugin plugin){
+
+    private void setState(OSMRecPlugin plugin) {
         this.plugin = plugin;
     }
-    
-    public OSMRecPlugin getState(){
+
+    public OSMRecPlugin getState() {
         return plugin;
     }
-    
-//    @Override
-//    public PreferenceSetting getPreferenceSetting() {
-//        return new PreferenceEditor();
-//    }
+
+    //    @Override
+    //    public PreferenceSetting getPreferenceSetting() {
+    //        return new PreferenceEditor();
+    //    }
 }
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java	(revision 32404)
@@ -1,14 +1,5 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec;
 
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.LineString;
-import com.vividsolutions.jts.geom.LinearRing;
-import com.vividsolutions.jts.geom.Point;
-import com.vividsolutions.jts.geom.Polygon;
-import de.bwaldvogel.liblinear.FeatureNode;
-import de.bwaldvogel.liblinear.Linear;
-import de.bwaldvogel.liblinear.Model;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import static org.openstreetmap.josm.tools.I18n.trn;
@@ -19,11 +10,8 @@
 import java.awt.Cursor;
 import java.awt.Dimension;
+import java.awt.EventQueue;
 import java.awt.FlowLayout;
-import java.awt.Font;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.Transferable;
 import java.awt.event.ActionEvent;
 import java.awt.event.FocusAdapter;
@@ -32,6 +20,4 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
 import java.awt.image.BufferedImage;
 import java.beans.PropertyChangeEvent;
@@ -68,5 +54,4 @@
 import javax.swing.BoxLayout;
 import javax.swing.ButtonGroup;
-import javax.swing.DefaultListCellRenderer;
 import javax.swing.DefaultListModel;
 import javax.swing.GroupLayout;
@@ -88,5 +73,4 @@
 import javax.swing.JScrollPane;
 import javax.swing.JTextField;
-import javax.swing.ListCellRenderer;
 import javax.swing.SwingConstants;
 import javax.swing.border.EtchedBorder;
@@ -96,4 +80,5 @@
 import javax.swing.table.DefaultTableModel;
 import javax.swing.text.JTextComponent;
+
 import org.geotools.geometry.jts.JTS;
 import org.geotools.referencing.CRS;
@@ -105,5 +90,4 @@
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.TransformException;
-
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
@@ -124,39 +108,48 @@
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.io.XmlWriter;
-import org.openstreetmap.josm.plugins.container.OSMWay;
-import org.openstreetmap.josm.plugins.core.TrainWorker;
-import org.openstreetmap.josm.plugins.extractor.LanguageDetector;
-import org.openstreetmap.josm.plugins.extractor.SampleModelsExtractor;
-import org.openstreetmap.josm.plugins.features.ClassFeatures;
-import org.openstreetmap.josm.plugins.features.GeometryFeatures;
-import org.openstreetmap.josm.plugins.features.OSMClassification;
-import org.openstreetmap.josm.plugins.features.TextualFeatures;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.plugins.osmrec.core.TrainWorker;
+import org.openstreetmap.josm.plugins.osmrec.extractor.LanguageDetector;
+import org.openstreetmap.josm.plugins.osmrec.extractor.SampleModelsExtractor;
+import org.openstreetmap.josm.plugins.osmrec.features.ClassFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.GeometryFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.OSMClassification;
+import org.openstreetmap.josm.plugins.osmrec.features.TextualFeatures;
+import org.openstreetmap.josm.plugins.osmrec.parsers.Mapper;
+import org.openstreetmap.josm.plugins.osmrec.parsers.OSMParser;
+import org.openstreetmap.josm.plugins.osmrec.parsers.Ontology;
+import org.openstreetmap.josm.plugins.osmrec.parsers.TextualStatistics;
 import org.openstreetmap.josm.plugins.osmrec.personalization.UserDataExtractAndTrainWorker;
-import org.openstreetmap.josm.plugins.parsers.Mapper;
-import org.openstreetmap.josm.plugins.parsers.OSMParser;
-import org.openstreetmap.josm.plugins.parsers.Ontology;
-import org.openstreetmap.josm.plugins.parsers.TextualStatistics;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+import de.bwaldvogel.liblinear.Linear;
+import de.bwaldvogel.liblinear.Model;
+
 /**
  * Modified PropertiesDialog(since 5633) to serve the plugin functionality.
- * 
+ *
  * @author imis-nkarag
  */
-
 class OSMRecPluginHelper {
-    
+
     private final DefaultTableModel tagData;
-    private final Map<String, Map<String, Integer>> valueCount;
     private static Collection<String> fileHistory;
     private Map<File, Double> filesAndWeights = new HashMap<>();
-    private boolean useCombinedModel = false;
-    
-    //the most recent file from history. 
+    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 final String MODEL_PATH = MAIN_PATH.substring(0, MAIN_PATH.lastIndexOf("/")) + "OSMRec_models/";
     private static String MODEL_PATH;
     private static String TEXTUAL_LIST_PATH;
@@ -165,5 +158,5 @@
     private static LanguageDetector languageDetector;
     private static String bestModelPath;
-    private boolean modelWithClasses;// = false;
+    private boolean modelWithClasses;
     private final String modelWithClassesPath;
     private boolean useCustomSVMModel = false;
@@ -171,10 +164,9 @@
     private final String combinedModelClasses;
     private final String combinedModel;
-       
+
     // Selection that we are editing by using both dialogs
     Collection<OsmPrimitive> sel;
 
     private String changedKey;
-    private String objKey;
 
     Comparator<AutoCompletionListItem> defaultACItemComparator = new Comparator<AutoCompletionListItem>() {
@@ -199,13 +191,10 @@
     };
 
-    
     OSMRecPluginHelper(DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
         this.tagData = propertyData;
-        this.valueCount = valueCount;
         fileHistory = Main.pref.getCollection("file-open.history");
-        if(!fileHistory.isEmpty()){            
-            MAIN_PATH = (String) fileHistory.toArray()[0]; 
-        }
-        else{
+        if (!fileHistory.isEmpty()) {
+            MAIN_PATH = (String) fileHistory.toArray()[0];
+        } else {
             MAIN_PATH = System.getProperty("user.home");
         }
@@ -220,13 +209,11 @@
 
         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).
+     * Open the add selection dialog and add a new key/value to the table (and to the dataset, of course).
      */
     public void addTag() {
@@ -236,5 +223,5 @@
 
         final AddTagsDialog addDialog = new AddTagsDialog();
-        
+
         addDialog.showDialog();
 
@@ -247,16 +234,13 @@
 
     /**
-    * 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
-    */
+     * 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();
-        //if (sel == null || sel.isEmpty()) return;
-//        String key = tagData.getValueAt(row, 0).toString();
         String key = "";
-//        objKey=key;
 
         @SuppressWarnings("unchecked")
@@ -264,8 +248,6 @@
         dumPar.put(" ", -1);
         final TrainingDialog editDialog = new TrainingDialog(key, row,
-                dumPar, focusOnKey);                
+                dumPar, focusOnKey);
         editDialog.showDialog();
-        //if (editDialog.getValue() !=1 ) return;
-        //editDialog.performTagEdit();
     }
 
@@ -277,8 +259,4 @@
     public String getChangedKey() {
         return changedKey;
-    }
-
-    public void resetChangedKey() {
-        changedKey = null;
     }
 
@@ -318,5 +296,5 @@
     public void saveTagsIfNeeded() {
         if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) {
-            List<String> c = new ArrayList<>( recentTags.size()*2 );
+            List<String> c = new ArrayList<>(recentTags.size()*2);
             for (Tag t: recentTags.keySet()) {
                 c.add(t.getKey());
@@ -349,24 +327,4 @@
     public final class TrainingDialog extends AbstractTagsDialog {
 
-        ListCellRenderer<AutoCompletionListItem> cellRenderer = new ListCellRenderer<AutoCompletionListItem>() {
-            final DefaultListCellRenderer def = new DefaultListCellRenderer();
-            @Override
-            public Component getListCellRendererComponent(JList<? extends AutoCompletionListItem> list,
-                    AutoCompletionListItem value, int index, boolean isSelected,  boolean cellHasFocus){
-                Component c = def.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
-                if (c instanceof JLabel) {
-                    String str = value.getValue();
-                    if (valueCount.containsKey(objKey)) {
-                        Map<String, Integer> m = valueCount.get(objKey);
-                        if (m.containsKey(str)) {
-                            str = tr("{0} ({1})", str, m.get(str));
-                            c.setFont(c.getFont().deriveFont(Font.ITALIC + Font.BOLD));
-                        }
-                    }
-                    ((JLabel) c).setText(str);
-                }
-                return c;
-            }
-        };
         private static final int FIELD_COLUMNS = 4;
         private final JTextField inputFileField;
@@ -375,5 +333,5 @@
         private final JTextField cParameterField;
         private final JTextField frequencyField;
-        
+
         private final JButton fileBrowseButton;
         private final JButton acceptConfigButton;
@@ -393,5 +351,4 @@
         private final JLabel frequencyErrorMessageLabel;
         private final JProgressBar trainingProgressBar;
-        //private final JLabel userHistoryLabel;
         private final JRadioButton byAreaRadioButton;
         private final JRadioButton byTimeRadioButton;
@@ -406,53 +363,51 @@
         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("Start Training"),tr("Cancel")});
-            super(Main.parent, tr("Training process configuration"), 
-                    new String[] {tr("Cancel")});
-
-            setButtonIcons(new String[] {"ok","cancel"});
+            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 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 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 javax.swing.JProgressBar(0,100);
+
+            trainingProgressBar = new JProgressBar(0, 100);
 
             ButtonGroup paramGroup = new ButtonGroup();
             ButtonGroup userGroup = new ButtonGroup();
-            inputFileLabel = new javax.swing.JLabel();
-            inputFileField = new javax.swing.JTextField();
-            cParameterField = new javax.swing.JTextField();  
-            topKField = new javax.swing.JTextField();
-            frequencyField = new javax.swing.JTextField();            
-            
+            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 javax.swing.JButton();
-            acceptConfigButton = new javax.swing.JButton("Accept Configuration");                       
-            resetConfigButton = new javax.swing.JButton("Reset Configuration/Cancel training");
-            startTrainingButton = new javax.swing.JButton("Train Model");
-            
-            inputFileErrorMessageLabel = new javax.swing.JLabel("");
-            cErrorMessageLabel = new javax.swing.JLabel("");
-            topKErrorMessageLabel = new javax.swing.JLabel(""); 
-            frequencyErrorMessageLabel = new javax.swing.JLabel(""); 
-          
+            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 javax.swing.JLabel("Username:");
-            userNameField = new javax.swing.JTextField();
-            
-            daysLabel = new javax.swing.JLabel("Days: ");
-            daysField = new javax.swing.JTextField();
-            
+            userNameLabel = new JLabel("Username:");
+            userNameField = new JTextField();
+
+            daysLabel = new JLabel("Days: ");
+            daysField = new JTextField();
+
             cParameterCheckBox.setSelected(true);
             userHistoryPanel.setEnabled(false);
@@ -465,12 +420,11 @@
             daysField.setEnabled(false);
             userNameField.setColumns(FIELD_COLUMNS);
-            daysField.setColumns(FIELD_COLUMNS);           
-            
+            daysField.setColumns(FIELD_COLUMNS);
+
             Collection<String> fileHistory = Main.pref.getCollection("file-open.history");
-            if(!fileHistory.isEmpty()){                
-                //System.out.println(fileName);
+            if (!fileHistory.isEmpty()) {
                 inputFileField.setText(MAIN_PATH);
             }
-                
+
             fileBrowseButton.setText("...");
             inputFileLabel.setText("OSM filepath: ");
@@ -480,21 +434,21 @@
             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);        
+            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
@@ -506,9 +460,8 @@
                 @Override
                 public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if(topKButton.isSelected()){                       
+                    if (topKButton.isSelected()) {
                         frequencyField.setEditable(false);
                         topKField.setEditable(true);
-                    }
-                    else{
+                    } else {
                         frequencyField.setEditable(true);
                         topKField.setEditable(false);
@@ -519,21 +472,19 @@
                 @Override
                 public void actionPerformed(java.awt.event.ActionEvent evt) {
-                    if(frequencyButton.isSelected()){
+                    if (frequencyButton.isSelected()) {
                         topKField.setEditable(false);
                         frequencyField.setEditable(true);
-                    }
-                    else{
+                    } 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{
+                    if (cParameterCheckBox.isSelected()) {
+                        cParameterField.setEditable(true);
+                    } else {
                         cParameterField.setEditable(false);
                     }
@@ -550,24 +501,22 @@
                 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()){
+                    if (!acceptConfigButton.isEnabled()) {
                         startTraining();
-                    }
-                    else{
+                    } 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()){
+                    if (trainFromUserCheckBox.isSelected()) {
                         userHistoryPanel.setEnabled(true);
                         byAreaRadioButton.setEnabled(true);
@@ -577,6 +526,5 @@
                         daysLabel.setEnabled(true);
                         daysField.setEnabled(true);
-                    }
-                    else{
+                    } else {
                         userHistoryPanel.setEnabled(false);
                         byAreaRadioButton.setEnabled(false);
@@ -585,39 +533,105 @@
                         userNameField.setEnabled(false);
                         daysLabel.setEnabled(false);
-                        daysField.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);                       
-                    }
-                }
-            });   
-            
+                    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);                       
-                    }
-                }
-            }); 
-            
+                    if (byTimeRadioButton.isSelected()) {
+                        daysField.setEditable(true);
+                    } else {
+                        daysField.setEditable(false);
+                    }
+                }
+            });
+
             //grouplayout for input panel
+            buildInputPanelGroupLayout(inputPanel);
+
+            //grouplayout for param panel
+            buildParamPanelGroupLayout(paramPanel);
+
+            inputPanel.add(inputFileLabel);
+            inputPanel.add(inputFileField);
+            inputPanel.add(fileBrowseButton);
+            inputPanel.add(inputFileErrorMessageLabel);
+
+            paramGroup.add(topKButton);
+            paramGroup.add(frequencyButton);
+
+            paramPanel.add(cParameterCheckBox);
+            paramPanel.add(cParameterField);
+            paramPanel.add(cErrorMessageLabel);
+            paramPanel.add(topKButton);
+            paramPanel.add(topKField);
+            paramPanel.add(topKErrorMessageLabel);
+            paramPanel.add(frequencyButton);
+            paramPanel.add(frequencyField);
+            paramPanel.add(frequencyErrorMessageLabel);
+
+            southPanel.add(acceptConfigButton);
+            southPanel.add(resetConfigButton);
+            southPanel.add(trainFromUserCheckBox);
+
+            userGroup.add(byAreaRadioButton);
+            userGroup.add(byTimeRadioButton);
+            userHistoryPanel.add(byAreaRadioButton);
+            userHistoryPanel.add(byTimeRadioButton);
+            userHistoryPanel.add(daysLabel);
+            userHistoryPanel.add(daysField);
+            userHistoryPanel.add(userNameLabel);
+            userHistoryPanel.add(userNameField);
+
+            //grouplayout for user history panel
+            /*
+                userNameLabel       userField
+                arearadiobutton
+                timeradiobutton     daysLabel   daysField
+             */
+            buildUserHistoryPanelGroupLayout();
+
+            configPanel.add(inputPanel, BorderLayout.NORTH);
+            configPanel.add(userHistoryPanel, BorderLayout.EAST);
+            configPanel.add(paramPanel, BorderLayout.WEST);
+            configPanel.add(southPanel, BorderLayout.SOUTH);
+
+            userHistoryPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
+                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "Train by user History"));
+            paramPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
+                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "SVM Configuration"));
+            inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+            configPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
+
+            mainPanel.add(configPanel, BorderLayout.NORTH);
+            mainPanel.add(startTrainingButton, BorderLayout.CENTER);
+            mainPanel.add(trainingProgressBar, BorderLayout.SOUTH);
+
+            AutoCompletionManager autocomplete = Main.getLayerManager().getEditLayer().data.getAutoCompletionManager();
+            List<AutoCompletionListItem> keyList = autocomplete.getKeys();
+            Collections.sort(keyList, defaultACItemComparator);
+
+            setContent(mainPanel, false);
+        }
+
+        private void buildInputPanelGroupLayout(JPanel inputPanel) {
             GroupLayout inputGroupLayout = new GroupLayout(inputPanel);
             inputPanel.setLayout(inputGroupLayout);
             inputGroupLayout.setAutoCreateGaps(true);
             inputGroupLayout.setAutoCreateContainerGaps(true);
-            
+
             GroupLayout.SequentialGroup inputHorGroup = inputGroupLayout.createSequentialGroup();
             inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileLabel).
@@ -626,5 +640,5 @@
             inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(fileBrowseButton));
             inputGroupLayout.setHorizontalGroup(inputHorGroup);
-            
+
             GroupLayout.SequentialGroup inputVerGroup = inputGroupLayout.createSequentialGroup();
             inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).addComponent(inputFileLabel).
@@ -633,21 +647,21 @@
                     addComponent(inputFileErrorMessageLabel));
             inputGroupLayout.setVerticalGroup(inputVerGroup);
-            
-            
-            //grouplayout for param panel
+        }
+
+        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));            
+                    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).
@@ -657,104 +671,34 @@
             paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
                     addComponent(frequencyButton).addComponent(frequencyField).addComponent(frequencyErrorMessageLabel));
-            paramGroupLayout.setVerticalGroup(paramVerGroup);      
-            
-            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);    
-            //userHistoryPanel.add(trainFromUserCheckBox);   
-            
-            //grouplayout for user history panel
-            /* 
-                userNameLabel       userField
-                arearadiobutton 
-                timeradiobutton     daysLabel   daysField
-            */
+            paramGroupLayout.setVerticalGroup(paramVerGroup);
+        }
+
+        private void buildUserHistoryPanelGroupLayout() {
             GroupLayout userHistoryGroupLayout = new GroupLayout(userHistoryPanel);
-            //userHistoryGroupLayout.se
             userHistoryPanel.setLayout(userHistoryGroupLayout);
             userHistoryGroupLayout.setAutoCreateGaps(true);
-            userHistoryGroupLayout.setAutoCreateContainerGaps(true); 
-            userHistoryGroupLayout.linkSize(SwingConstants.HORIZONTAL, userNameField, daysLabel,daysField);
-            
+            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));                        
+                    .addComponent(byAreaRadioButton).addComponent(byTimeRadioButton));
             userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameField)
-                    .addComponent(daysLabel));       
+                    .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));            
+                    addComponent(userNameLabel).addComponent(userNameField));
             userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(byAreaRadioButton));            
+                    addComponent(byAreaRadioButton));
             userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
-                    addComponent(byTimeRadioButton).addComponent(daysLabel).addComponent(daysField)); 
+                    addComponent(byTimeRadioButton).addComponent(daysLabel).addComponent(daysField));
             userHistoryGroupLayout.setVerticalGroup(userHistoryVerGroup);
-            
-            configPanel.add(inputPanel, BorderLayout.NORTH);
-            configPanel.add(userHistoryPanel, BorderLayout.EAST); 
-            configPanel.add(paramPanel, BorderLayout.WEST);
-            configPanel.add(southPanel, BorderLayout.SOUTH);           
-
-            userHistoryPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
-                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "Train by user History"));            
-            paramPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
-                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "SVM Configuration"));            
-            inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
-            configPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));            
-            
-            mainPanel.add(configPanel, BorderLayout.NORTH);
-            mainPanel.add(startTrainingButton, BorderLayout.CENTER);
-            mainPanel.add(trainingProgressBar, BorderLayout.SOUTH);
-            
-            AutoCompletionManager autocomplete = Main.main.getEditLayer().data.getAutoCompletionManager();
-            List<AutoCompletionListItem> keyList = autocomplete.getKeys();
-            Collections.sort(keyList, defaultACItemComparator);
-
-            setContent(mainPanel, false);
-
-            addWindowListener(new WindowAdapter() {
-                @Override
-                public void windowOpened(WindowEvent e) {
-                    if (initialFocusOnKey) {
-                        selectKeysComboBox();
-                    } else {
-                        selectValuesCombobox();
-                    }
-                }
-            });
-        }
-        
-        private void inputFileChooserButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                      
+        }
+
+        private void inputFileChooserButtonActionPerformed(ActionEvent evt) {
             try {
                 final File file = new File(inputFileField.getText());
@@ -762,80 +706,71 @@
 
                 final int returnVal = fileChooser.showOpenDialog(this);
-                if(returnVal == JFileChooser.APPROVE_OPTION) {
+                if (returnVal == JFileChooser.APPROVE_OPTION) {
                     inputFileField.setText(fileChooser.getSelectedFile().getAbsolutePath());
                 }
-            }
-            catch (RuntimeException ex) {
+            } catch (RuntimeException ex) {
                 Main.warn(ex);
-                //ex.printStackTrace();
-            }
-        } 
-        
-        private void acceptConfigButtonActionPerformed(java.awt.event.ActionEvent evt) {
+            }
+        }
+
+        private void acceptConfigButtonActionPerformed(ActionEvent evt) {
             //parse values
             inputFileValue = inputFileField.getText();
-            
-            if(!new File(inputFileValue).exists()){
+
+            if (!new File(inputFileValue).exists()) {
                 inputFileErrorMessageLabel.setText("OSM file does not exist");
                 resetConfigButtonActionPerformed();
                 return;
             }
-            
-            if(cParameterCheckBox.isSelected()){
+
+            if (cParameterCheckBox.isSelected()) {
                 String c = cParameterField.getText();
                 try {
-                    cParameterValue = Double.parseDouble(c.replace(",","."));
+                    cParameterValue = Double.parseDouble(c.replace(",", "."));
                     cErrorMessageLabel.setText("");
-                }
-                catch(NumberFormatException ex){
-                    
+                } 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 
+                    System.out.println("c must be a number!" + ex); //make empty textLabel beside c param to notify errors
                     resetConfigButtonActionPerformed();
-                    return; 
-                }
-                crossValidateFlag = false;               
-            }
-            else{
+                    return;
+                }
+                crossValidateFlag = false;
+            } else {
                 crossValidateFlag = true;
             }
-            
-            if(topKButton.isSelected()){
+
+            if (topKButton.isSelected()) {
                 String k = topKField.getText();
                 try {
-                    topKvalue = Integer.parseInt(k); 
+                    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!"); 
+                } catch (NumberFormatException ex) {
+                    topKErrorMessageLabel.setText("Must be an Integer!");
                     resetConfigButtonActionPerformed();
                     return;
                 }
-            }
-            
-            if(trainFromUserCheckBox.isSelected()){
+            } 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{
+                if (byTimeRadioButton.isSelected()) {
+                    try {
                         daysValue = Integer.parseInt(daysField.getText());
-                    }
-                    catch (NumberFormatException ex){
+                    } catch (NumberFormatException ex) {
                         daysField.setText("Integer!");
                         Main.warn(ex);
-                    } 
-                }
-                
+                    }
+                }
+
                 userHistoryPanel.setEnabled(false);
                 byAreaRadioButton.setEnabled(false);
@@ -844,53 +779,51 @@
                 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);                        
-            
+                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);  
+            cParameterField.setEditable(false);
             topKField.setEditable(false);
-            frequencyField.setEditable(false);                                
-            cParameterCheckBox.setEnabled(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){
+            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){
+                } 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);
-                }                
+                } catch (CancellationException ex) {
+                    startTrainingButton.setEnabled(true);
+                    System.out.println(ex);
+                }
             }
             inputFileField.setEditable(true);
-            cParameterField.setEditable(true);  
+            cParameterField.setEditable(true);
             topKField.setEditable(true);
-            frequencyField.setEditable(true);                                
-            cParameterCheckBox.setEnabled(true); 
+            frequencyField.setEditable(true);
+            cParameterCheckBox.setEnabled(true);
             topKButton.setEnabled(true);
             frequencyButton.setEnabled(true);
-            acceptConfigButton.setEnabled(true);          
+            acceptConfigButton.setEnabled(true);
             fileBrowseButton.setEnabled(true);
             trainFromUserCheckBox.setEnabled(true);
-            
-            if(trainFromUserCheckBox.isSelected()){
+
+            if (trainFromUserCheckBox.isSelected()) {
                 userHistoryPanel.setEnabled(true);
                 byAreaRadioButton.setEnabled(true);
@@ -899,35 +832,32 @@
                 userNameField.setEnabled(true);
                 daysLabel.setEnabled(true);
-                daysField.setEnabled(true); 
-            }    
-        }       
-        
+                daysField.setEnabled(true);
+            }
+        }
+
         private void startTraining() {
             startTrainingButton.setEnabled(false);
-            
-            if(trainFromUserCheckBox.isSelected()){ //if user training. train by area or days
-  
-                java.awt.EventQueue.invokeLater(new Runnable() {                    
+
+            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 = new UserDataExtractAndTrainWorker(inputFileValue, usernameValue, daysValue,
+                                byAreaRadioButton.isSelected(), crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
+                                topKButton.isSelected(), languageDetector);
+
                         userDataExtractAndTrainWorker.addPropertyChangeListener(new PropertyChangeListener() {
-                            
-                            @Override 
+                            @Override
                             public void propertyChange(PropertyChangeEvent evt) {
-                                if("progress".equals(evt.getPropertyName())) {
+                                if ("progress".equals(evt.getPropertyName())) {
                                     int progress = (Integer) evt.getNewValue();
                                     trainingProgressBar.setValue(progress);
-                                    if(progress == 100){
+                                    if (progress == 100) {
                                         startTrainingButton.setEnabled(true);
                                     }
                                 }
-                            }                                                 
-                        });                                                  
+                            }
+                        });
 
                         try {
@@ -936,34 +866,26 @@
                         } catch (Exception ex) {
                             Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
-                        }                    
-                    }
-                });                         
-            }
-            else {
-
-                java.awt.EventQueue.invokeLater(new Runnable() {
-                    //private TrainWorker trainWorker;
+                        }
+                    }
+                });
+            } else {
+                EventQueue.invokeLater(new Runnable() {
                     @Override
                     public void run() {
-
-                        trainWorker = new TrainWorker
-                                    (inputFileValue, crossValidateFlag, cParameterValue, topKvalue, frequencyValue, 
-                                            topKButton.isSelected(), languageDetector);
-                        
+                        trainWorker = new TrainWorker(inputFileValue, crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
+                                topKButton.isSelected(), languageDetector);
+
                         trainWorker.addPropertyChangeListener(new PropertyChangeListener() {
-                            @Override 
+                            @Override
                             public void propertyChange(PropertyChangeEvent evt) {
-                                if("progress".equals(evt.getPropertyName())) {
+                                if ("progress".equals(evt.getPropertyName())) {
                                     int progress = (Integer) evt.getNewValue();
                                     trainingProgressBar.setValue(progress);
-                                    if(progress == 100){
+                                    if (progress == 100) {
                                         startTrainingButton.setEnabled(true);
                                     }
                                 }
-    //                            if(cancelled){
-    //                                trainWorker.cancel(true);
-    //                            }
-                            }                                                 
-                        });                                                  
+                            }
+                        });
 
                         try {
@@ -971,21 +893,23 @@
                         } 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 class AbstractTagsDialog extends ExtendedDialog {
+    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;
-        Component componentUnderMouse;
-
-        public AbstractTagsDialog(Component parent, String title, String[] buttonTexts) {
+
+        AbstractTagsDialog(Component parent, String title, String[] buttonTexts) {
             super(parent, title, buttonTexts);
             addMouseListener(new PopupMenuLauncher(popupMenu));
@@ -1004,5 +928,5 @@
 
             setRememberWindowGeometry(getClass().getName() + ".geometry",
-                WindowGeometry.centerInWindow(Main.parent, size)); 
+                    WindowGeometry.centerInWindow(Main.parent, size));
         }
 
@@ -1024,70 +948,47 @@
                     rememberWindowGeometry(geometry);
                 }
-                if(keys != null){
-                   keys.setFixedLocale(PROPERTY_FIX_TAG_LOCALE.get()); 
-                }               
+                if (keys != null) {
+                    keys.setFixedLocale(PROPERTY_FIX_TAG_LOCALE.get());
+                }
             }
             super.setVisible(visible);
         }
 
-        private void selectACComboBoxSavingUnixBuffer(AutoCompletingComboBox cb) {
-            // select combobox with saving unix system selection (middle mouse paste)
-            Clipboard sysSel = Toolkit.getDefaultToolkit().getSystemSelection();
-            if(sysSel != null) {
-                Transferable old = sysSel.getContents(null);
-                cb.requestFocusInWindow();
-                cb.getEditor().selectAll();
-                sysSel.setContents(old, null);
-            } else {
-                cb.requestFocusInWindow();
-                cb.getEditor().selectAll();
-            }
-        }
-
-        public void selectKeysComboBox() {
-            //selectACComboBoxSavingUnixBuffer(keys);
-        }
-
-        public void selectValuesCombobox()   {
-            //selectACComboBoxSavingUnixBuffer(values);
-        }
-
         /**
-        * 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
-        */
+         * 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();
-                   objKey=key;
-               }
-           };
-           editor.addFocusListener(focus);
-           return focus;
+            // 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);
-                }
-            });
+                    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);
@@ -1097,17 +998,14 @@
     }
 
-    class ModelSettingsDialog extends JPanel{
-        
+    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 javax.swing.JList<>(combinationDefaultListModel);
+        private final JList<String> modelCombinationList = new JList<>(combinationDefaultListModel);
         private final JPanel modelCombinationPanel;
-        //private final JTextField weightTextField;
         private final JPanel weightsPanel;
-        //private final int hei;
-        //private final int wi;
         private final JCheckBox useModelCombinationCheckbox;
         private final JButton acceptWeightsButton;
@@ -1126,53 +1024,48 @@
         private final TitledBorder weightTitle;
         private final TitledBorder combineTitle;
-        //private final BorderLayout mainBorderLayout;
-        //private final BorderLayout mainBorderLayoutDefault;
-        //private final Dimension combinationPanelDimension;
         private final Dimension singleSelectionDimension;
         private final Dimension modelCombinationDimension;
         private final Dimension mainPanelDimension;
-        
-        
-        public ModelSettingsDialog(Collection<OsmPrimitive> sel1, final AddTagsDialog addDialog){ 
-            
+
+        ModelSettingsDialog(Collection<OsmPrimitive> sel1, final AddTagsDialog addDialog) {
+
             loadPreviousCombinedSVMModel();
-            singleSelectionDimension = new Dimension(470,70);
-            modelCombinationDimension = new Dimension(450,250);
-            mainPanelDimension = new Dimension(600,350);
-            
+            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));
+            mainPanel = new JPanel(new BorderLayout(10, 10));
+            singleSelectionPanel = new JPanel(new BorderLayout(10, 10));
             setResetWeightsPanel = new JPanel();
-            
-            chooseModelLabel = new javax.swing.JLabel("Choose a Model:");
-            chooseModelTextField = new javax.swing.JTextField();
-            chooseModelButton = new javax.swing.JButton("...");
-            chooseModelTextField.setText(MODEL_PATH);                        
-            
-            singleSelectionPanel.add(chooseModelLabel, BorderLayout.NORTH);  
+
+            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); 
-            
+            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 = new javax.swing.JList<>(combinationDefaultListModel);
-            modelCombinationList.setFixedCellHeight(20);  
+            modelCombinationList.setFixedCellHeight(20);
             modelCombinationList.setEnabled(false);
-            modelCombinationPanel = new JPanel(new BorderLayout(10,10)); //new BorderLayout() 
+            modelCombinationPanel = new JPanel(new BorderLayout(10, 10));
 
             weightsPanel = new JPanel();
-            weightsPanel.setLayout(new BoxLayout(weightsPanel, BoxLayout.Y_AXIS)); 
+            weightsPanel.setLayout(new BoxLayout(weightsPanel, BoxLayout.Y_AXIS));
             weightsPanel.setEnabled(false);
-            
-            
-            acceptWeightsButton = new javax.swing.JButton("Set Weights/Normalize");
-            resetWeightsButton = new javax.swing.JButton("Reset Weights");
-            removeSelectedModelButton = new javax.swing.JButton("Remove Selected");
+
+
+            acceptWeightsButton = new JButton("Set Weights/Normalize");
+            resetWeightsButton = new JButton("Reset Weights");
+            removeSelectedModelButton = new JButton("Remove Selected");
             setResetWeightsPanel.add(acceptWeightsButton);
             setResetWeightsPanel.add(resetWeightsButton);
@@ -1181,13 +1074,13 @@
             acceptWeightsButton.setEnabled(false);
             resetWeightsButton.setEnabled(false);
-            
+
             modelCombinationPanel.add(modelCombinationList, BorderLayout.CENTER);
             modelCombinationPanel.add(weightsPanel, BorderLayout.EAST);
-            modelCombinationPanel.add(setResetWeightsPanel, BorderLayout.SOUTH); 
+            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  
+            combinationScrollPane.setPreferredSize(modelCombinationDimension);   //new Dimension(450, 250) // w/h
 
             //------- </WEST of main> ---------//
@@ -1195,7 +1088,7 @@
             //------- <SOUTH of main> ---------//
             useModelCombinationCheckbox = new JCheckBox("Combine different models?");
-            
+
             //------- </SOUTH of main> ---------//
-            
+
             //------- <Borders> ---------//
             modelTitle = BorderFactory.createTitledBorder("Models");
@@ -1204,16 +1097,13 @@
             modelCombinationList.setBorder(modelTitle);
             weightsPanel.setBorder(weightTitle);
-            
-            for(Entry<JTextField, String> entry : weightFieldsAndPaths.entrySet()){
-                //modelCombinationList.add(entry.getValue());
+
+            for (Entry<JTextField, String> entry : weightFieldsAndPaths.entrySet()) {
                 combinationDefaultListModel.addElement(entry.getValue());
-                
-                JTextField weightTextField = new javax.swing.JTextField("0.00");                   
-                weightTextField.setMaximumSize(new Dimension(80,20));
-                weightsPanel.add(entry.getKey());               
-
-                //entry.getKey().setText("0.00");
-            }            
-            
+
+                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);
@@ -1226,6 +1116,6 @@
                     modelChooserButtonActionPerformed(evt);
                 }
-            }); 
-            
+            });
+
             useModelCombinationCheckbox.addActionListener(new java.awt.event.ActionListener() {
                 @Override
@@ -1234,5 +1124,5 @@
                 }
             });
-            
+
             acceptWeightsButton.addActionListener(new java.awt.event.ActionListener() {
                 @Override
@@ -1240,6 +1130,6 @@
                     acceptWeightsButtonActionPerformed(evt);
                 }
-            });  
-            
+            });
+
             resetWeightsButton.addActionListener(new java.awt.event.ActionListener() {
                 @Override
@@ -1247,6 +1137,6 @@
                     resetWeightsButtonActionPerformed(evt);
                 }
-            });  
-            
+            });
+
             removeSelectedModelButton.addActionListener(new java.awt.event.ActionListener() {
                 @Override
@@ -1254,32 +1144,28 @@
                     removeSelectedModelButtonActionPerformed(evt);
                 }
-            });            
+            });
             mainPanel.add(singleSelectionScrollPane, BorderLayout.NORTH);
-            mainPanel.add(combinationScrollPane, BorderLayout.CENTER);  
-            mainPanel.add(useModelCombinationCheckbox,BorderLayout.SOUTH);
+            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);
-            
-            //final JFrame frame = new JFrame();
+
             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()){
+                    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);                              
+
+                        addDialog.loadSVMmodel();
+                        addDialog.createOSMObject(sel);
                         saveCombinedModel();
                         dlg.setVisible(false);
-                        //this.setVisible(false);
-                    }
-                    else if(newValue instanceof Integer && (int) newValue == -1 && useModelCombinationCheckbox.isSelected()){
+                    } else if (newValue instanceof Integer && (int) newValue == -1 && useModelCombinationCheckbox.isSelected()) {
                         System.out.println("model settings button value: " + newValue);
                         useCombinedModel = false;
@@ -1290,6 +1176,5 @@
                         addDialog.createOSMObject(sel);
                         dlg.setVisible(false);
-                    } 
-                    else if(newValue instanceof Integer && (int) newValue == 0 && !useModelCombinationCheckbox.isSelected() ){
+                    } 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");
@@ -1299,6 +1184,5 @@
                         addDialog.createOSMObject(sel);
                         dlg.setVisible(false);
-                    } 
-                    else if(newValue instanceof Integer && (int) newValue == -1 && !useModelCombinationCheckbox.isSelected() ){
+                    } 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");
@@ -1308,72 +1192,64 @@
                         addDialog.createOSMObject(sel);
                         dlg.setVisible(false);
-                    }      
-                    else if(newValue == null || newValue.equals("uninitializedValue")){
+                    } else if (newValue == null || newValue.equals("uninitializedValue")) {
                         System.out.println("uninitializedValue, do nothing");
                     }
-                    //JOptionPane.showMessageDialog(frame.getContentPane(), "You have hit " + newValue);
-                }
-            };            
+                }
+            };
 
             dlg = pane.createDialog(Main.parent, tr("Model Settings"));
-            dlg.setVisible(true);  
-            
-        }
-        
-        public void makeVisible(boolean visible){ 
             dlg.setVisible(true);
         }
-        
-        private void modelChooserButtonActionPerformed(java.awt.event.ActionEvent evt) {   
-            
+
+        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) {
+                if (returnVal == JFileChooser.APPROVE_OPTION) {
                     chooseModelTextField.setText(fileChooser.getSelectedFile().getAbsolutePath());
                     useCustomSVMModel = true;
                     customSVMModelPath = fileChooser.getSelectedFile().getAbsolutePath();
                 }
-                               
-                if(useModelCombinationCheckbox.isSelected()){
+
+                if (useModelCombinationCheckbox.isSelected()) {
                     String svmModelPath = fileChooser.getSelectedFile().getAbsolutePath();
                     String svmModelText;
-                    if(System.getProperty("os.name").contains("ux")){
-                        if(svmModelPath.contains("/")){
+                    if (System.getProperty("os.name").contains("ux")) {
+                        if (svmModelPath.contains("/")) {
                             svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("/"));
-                        }
-                        else{
+                        } else {
                             svmModelText = svmModelPath;
                         }
-                    }
-                    else{
-                         if(svmModelPath.contains("\\")){
+                    } else {
+                        if (svmModelPath.contains("\\")) {
                             svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("\\"));
-                        }
-                        else{
+                        } else {
                             svmModelText = svmModelPath;
-                        }                       
+                        }
                     }
                     combinationDefaultListModel.addElement(svmModelText);
-                    JTextField weightTextField = new javax.swing.JTextField("0.00");
+                    JTextField weightTextField = new JTextField("0.00");
                     weightFieldsAndPaths.put(weightTextField, svmModelPath);
                     System.out.println("weights size: " + weightFieldsAndPaths.size());
-                    
-                    weightTextField.setMaximumSize(new Dimension(80,20));
+
+                    weightTextField.setMaximumSize(new Dimension(80, 20));
                     weightsPanel.add(weightTextField);
                     //add additional textbox
-                }                  
-            }
-            catch (RuntimeException ex) {
+                }
+            } catch (RuntimeException ex) {
                 Main.warn(ex);
-                //ex.printStackTrace();
-            }
-        }
-        
+            }
+        }
+
         private void userCombinationCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
 
-            if(useModelCombinationCheckbox.isSelected()){
+            if (useModelCombinationCheckbox.isSelected()) {
                 useCombinedModel = true;
                 useCustomSVMModel = false; //reseting the selected custom SVM model only here
@@ -1381,5 +1257,5 @@
                 acceptWeightsButton.setEnabled(true);
                 resetWeightsButton.setEnabled(true);
-                
+
                 chooseModelTextField.setEnabled(false);
                 modelCombinationList.setEnabled(true);
@@ -1389,7 +1265,5 @@
                     weightPanelComponent.setEnabled(true);
                 }
-                
-            }
-            else{
+            } else {
                 useCombinedModel = false;
                 useCustomSVMModel = true;
@@ -1397,5 +1271,5 @@
                 acceptWeightsButton.setEnabled(false);
                 resetWeightsButton.setEnabled(false);
-                
+
                 chooseModelTextField.setEnabled(true);
                 modelCombinationList.setEnabled(false);
@@ -1407,15 +1281,15 @@
             }
         }
-        
+
         private void acceptWeightsButtonActionPerformed(ActionEvent evt) {
             int weightsCount = 0;
             removeSelectedModelButton.setEnabled(false);
-            double weightSum = 0;            
-            for(JTextField weightField : weightFieldsAndPaths.keySet()){
-                if(weightField.getText().equals("")){
+            double weightSum = 0;
+            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
+                if (weightField.getText().equals("")) {
                     weightField.setText("0.00");
                 }
-                
-                try{
+
+                try {
                     //TODO replace "," with "." to parse doubles with commas
                     Double weightValue = Double.parseDouble(weightField.getText());
@@ -1423,61 +1297,56 @@
                     weightValue = Math.abs(weightValue);
                     weightSum += weightValue;
-                }    
-                catch (NumberFormatException ex){
+                } catch (NumberFormatException ex) {
                     Main.warn(ex);
                 }
                 weightsCount++;
-            }  
-            
-            if(!filesAndWeights.isEmpty()){
+            }
+
+            if (!filesAndWeights.isEmpty()) {
                 filesAndWeights.clear();
             }
-            
-            for(JTextField weightField : weightFieldsAndPaths.keySet()){
-                try{
+
+            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
+                try {
                     Double weightValue = Double.parseDouble(weightField.getText());
 
                     weightValue = Math.abs(weightValue)/weightSum; //normalize
-                    
-                    if(weightSum == 0){
-                        //System.out.println("Zero weights");
+
+                    if (weightSum == 0) {
                         weightValue = 1.0/weightsCount;
-                    }                    
-                    
+                    }
+
                     weightField.setText(new DecimalFormat("#.##").format(weightValue));
-                    normalizedPathsAndWeights.put(weightFieldsAndPaths.get(weightField), weightValue);                   
+                    normalizedPathsAndWeights.put(weightFieldsAndPaths.get(weightField), weightValue);
                     filesAndWeights.put(new File(weightFieldsAndPaths.get(weightField)), weightValue);
-                    System.out.println("normalized: " + weightFieldsAndPaths.get(weightField) + "->"  + weightValue); 
+                    System.out.println("normalized: " + weightFieldsAndPaths.get(weightField) + "->" + weightValue);
                     weightField.setEnabled(false);
 
-                }    
-                catch (NumberFormatException ex){
+                } catch (NumberFormatException ex) {
                     Main.warn(ex);
-                }      
+                }
             }
 
             useCombinedModel = true;
             useCustomSVMModel = false;
-            
-            //filesAndWeights.putAll(normalizedPathsAndWeights);
-        }
-        
+        }
+
         private void resetWeightsButtonActionPerformed(ActionEvent evt) {
             removeSelectedModelButton.setEnabled(true);
-            for(JTextField weightField : weightFieldsAndPaths.keySet()){
+            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
                 weightField.setEnabled(true);
             }
         }
-        
+
         private void removeSelectedModelButtonActionPerformed(ActionEvent evt) {
-            int index  = modelCombinationList.getSelectedIndex();
+            int index = modelCombinationList.getSelectedIndex();
             String modelToBeRemoved = combinationDefaultListModel.get(index);
-            combinationDefaultListModel.remove(index); 
+            combinationDefaultListModel.remove(index);
             System.out.println("model to be removed: " + modelToBeRemoved);
 
-            Iterator<Entry<JTextField, String>> it = weightFieldsAndPaths.entrySet().iterator();               
+            Iterator<Entry<JTextField, String>> it = weightFieldsAndPaths.entrySet().iterator();
             while (it.hasNext()) {
                 Entry<JTextField, String> en = it.next();
-                if(en.getValue().equals(modelToBeRemoved)){
+                if (en.getValue().equals(modelToBeRemoved)) {
                     it.remove();
                 }
@@ -1485,5 +1354,5 @@
             System.out.println("model to be removed: " + modelToBeRemoved);
 
-            weightsPanel.remove(index); 
+            weightsPanel.remove(index);
             weightsPanel.revalidate();
             weightsPanel.repaint();
@@ -1507,11 +1376,11 @@
                 } finally {
                     try {
-                        if(in!=null){
+                        if (in != null) {
                             in.close();
                         }
-                        if(fileIn!=null){
+                        if (fileIn != null) {
                             fileIn.close();
                         }
-                        
+
                     } catch (IOException ex) {
                         Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
@@ -1529,5 +1398,5 @@
         private void saveCombinedModel() {
             try (FileOutputStream fileOut = new FileOutputStream(combinedModelClasses);
-                ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
+                    ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
                 out.writeObject(weightFieldsAndPaths);
             } catch (IOException e) {
@@ -1536,6 +1405,6 @@
         }
     }
-    
-    class AddTagsDialog extends  AbstractTagsDialog {
+
+    class AddTagsDialog extends AbstractTagsDialog {
         List<JosmAction> recentTagsActions = new ArrayList<>();
 
@@ -1554,16 +1423,15 @@
         private Map<Integer, String> idsWithMappings;
         private List<String> textualList = new ArrayList<>();
-        //private boolean useClassFeatures = false;
-        private final JCheckBox useTagsCheckBox;  
+        private final JCheckBox useTagsCheckBox;
         private ModelSettingsDialog modelSettingsDialog;
         private static final int RECOMMENDATIONS_SIZE = 10;
 
-        public AddTagsDialog() {
-            super(Main.parent, tr("Add value?"), new String[] {tr("OK"),tr("Cancel")});
-            setButtonIcons(new String[] {"ok","cancel"});
+        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
@@ -1572,124 +1440,111 @@
             System.out.println("path for textual: " + TEXTUAL_LIST_PATH);
             File textualListFile = new File(TEXTUAL_LIST_PATH);
-            if(textualListFile.exists()){
+            if (textualListFile.exists()) {
                 loadTextualList(textualListFile);
-            }
-            else{
-                loadDefaultTextualList(); 
-            }
-            
+            } else {
+                loadDefaultTextualList();
+            }
+
             //if training process has not been performed, we use two sample SVM models, extracted from the jar
-            //File bestModelFile = new File(bestModelPath);
-            //File bestModelWithClassesFile = new File(modelWithClassesPath);
-
-            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 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 javax.swing.JButton("Add and continue");
-            modelSettingsButton = new javax.swing.JButton("Model Settings"); 
-            useTagsCheckBox = new javax.swing.JCheckBox("Predict using tags");
-            recommendedClassesLabel = new javax.swing.JLabel("Recommended Classes:");           
-            
+
+            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) {                   
+                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()){
+                    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{
+                        } else {
                             //recommend using tags: set the checkbox selected to avoid confusing the user
                             useTagsCheckBox.setSelected(true);
-                            
-                            if(useTagsCheckBox.isSelected()){
+
+                            if (useTagsCheckBox.isSelected()) {
                                 //load model with classes
                                 modelWithClasses = true;
                                 loadSVMmodel();
-                                createOSMObject(sel); //create object including class features                              
-                            }
-                            else{
+                                createOSMObject(sel); //create object including class features
+                            } else {
                                 modelWithClasses = false;
                                 loadSVMmodel();
-                                createOSMObject(sel); //create object including class features    
+                                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){
+                    if (modelSettingsDialog == null) {
                         System.out.println("new modelSettingsDialog");
-                        modelSettingsDialog = new ModelSettingsDialog(sel, addTagsDialog);  
-                        
-                        //modelSettingsDialog.makeVisible(true);
-                        //modelSettingsDialog.setVisible(true);
-                    }
-                    else{
+                        modelSettingsDialog = new ModelSettingsDialog(sel, addTagsDialog);
+                    } else {
                         System.out.println("set modelSettingsDialog visible");
                         modelSettingsDialog.makeVisible(true);
-                        //modelSettingsDialog.setVisible(true);
-                    } 
-                }
-            });         
-
-            useTagsCheckBox.addActionListener(new java.awt.event.ActionListener() {                
+                    }
+                }
+            });
+
+            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()){
+                    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{
+                        } else {
                             //useTagsCheckBox
-                            if(useTagsCheckBox.isSelected()){
+                            if (useTagsCheckBox.isSelected()) {
                                 //load model with classes
                                 modelWithClasses = true;
                                 loadSVMmodel();
-                                createOSMObject(sel); //create object including class features                               
-                            }
-                            else{
+                                createOSMObject(sel); //create object including class features
+                            } else {
                                 modelWithClasses = false;
                                 loadSVMmodel();
-                                createOSMObject(sel); //create object including class features    
+                                createOSMObject(sel); //create object including class features
                             }
-                        }                        
-                    }                    
+                        }
+                    }
                 }
             });
-            
+
             keys = new AutoCompletingComboBox();
             values = new AutoCompletingComboBox();
 
             mainPanel.add(new JLabel("<html>"+trn("This will change up to {0} object.",
-                "This will change up to {0} objects.", sel.size(),sel.size())
-                +"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL));
-
-            AutoCompletionManager autocomplete = Main.main.getEditLayer().data.getAutoCompletionManager();
+                    "This will change up to {0} objects.", sel.size(), sel.size())
+            +"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL));
+
+            AutoCompletionManager autocomplete = Main.getLayerManager().getEditLayer().data.getAutoCompletionManager();
             List<AutoCompletionListItem> keyList = autocomplete.getKeys();
 
@@ -1718,45 +1573,43 @@
 
             mainPanel.add(keys, GBC.eop().fill());
-            mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol());            
- 
+            mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol());
+
             model = new DefaultListModel<>();
-            
-            parseTagsMappedToClasses(); 
-            
+
+            parseTagsMappedToClasses();
+
             List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
             OsmPrimitive s;
             //get a simple selection
-            if(!osmPrimitiveSelection.isEmpty()){
-                s = osmPrimitiveSelection.get(0);     
+            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()){
+                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{
+                    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);                   
+                    useTagsCheckBox.setSelected(true);
                     modelWithClasses = true;
-                    loadSVMmodel();//load model with classes          
-                    createOSMObject(sel); //create object including class features                              
-                }                        
-            } 
-            
+                    loadSVMmodel(); //load model with classes
+                    createOSMObject(sel); //create object including class features
+                }
+            }
+
             categoryList = new JList<>(model);
 
-            ListSelectionListener listSelectionListener = new ListSelectionListener() {       
+            ListSelectionListener listSelectionListener = new ListSelectionListener() {
                 @Override
                 public void valueChanged(ListSelectionEvent listSelectionEvent) {
-                    if (!listSelectionEvent.getValueIsAdjusting()) {//This prevents double events
-                        //System.out.println("tag selected: " + categoryList.getSelectedValue());
-                        
+                    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){
+                        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(" "));
@@ -1764,6 +1617,5 @@
                                 keys.setSelectedItem(keyTag); //adding selected tags to textBoxes
                                 values.setSelectedItem(valueTag);
-                            }
-                            else{
+                            } else {
                                 //value does not have a value, add the key tag only
                                 String keyTag = selectedClass; //test it
@@ -1772,8 +1624,8 @@
                             }
                         }
-                    }                   
+                    }
                 }
             };
-            
+
             categoryList.addListSelectionListener(listSelectionListener);
             categoryList.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
@@ -1798,15 +1650,4 @@
             }
 
-            // Add tag on Shift-Enter
-//            mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
-//                        KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_MASK), "addAndContinue");
-//                mainPanel.getActionMap().put("addAndContinue", new AbstractAction() {
-//                    @Override
-//                    public void actionPerformed(ActionEvent e) {
-//                        performTagAdding();
-//                        selectKeysComboBox();
-//                    }
-//                });
-
             suggestRecentlyAddedTags(mainPanel, recentTagsToShow, focus);
 
@@ -1814,5 +1655,5 @@
             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);
@@ -1820,14 +1661,12 @@
             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);
-
-            selectKeysComboBox();
 
             popupMenu.add(new AbstractAction(tr("Set number of recently added tags")) {
@@ -1838,27 +1677,25 @@
             });
             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();
-                }
-            });
+                    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();
-            selectKeysComboBox();
-        }
-        
+        }
+
         private void selectNumberOfTags() {
             String s = JOptionPane.showInputDialog(this, tr("Please enter the number of recently added tags to display"));
-            if (s!=null) try {
+            if (s != null) try {
                 int v = Integer.parseInt(s);
-                if (v>=0 && v<=MAX_LRU_TAGS_NUMBER) {
+                if (v >= 0 && v <= MAX_LRU_TAGS_NUMBER) {
                     PROPERTY_RECENT_TAGS_NUMBER.put(v);
                     return;
@@ -1878,14 +1715,16 @@
             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.
+            // 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 actionShortcutKey = "properties:recent:"+count;
-                String actionShortcutShiftKey = "properties:recent:shift:"+count;
-                Shortcut sc = Shortcut.registerShortcut(actionShortcutKey, tr("Choose recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL);
-                final JosmAction action = new JosmAction(actionShortcutKey, null, tr("Use this tag again"), sc, false) {
+                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) {
@@ -1894,14 +1733,12 @@
                         focus.focusGained(null);
                         values.setSelectedItem(t.getValue());
-                        selectValuesCombobox();
                     }
                 };
-                Shortcut scShift = Shortcut.registerShortcut(actionShortcutShiftKey, tr("Apply recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL_SHIFT);
-                final JosmAction actionShift = new JosmAction(actionShortcutShiftKey, null, tr("Use this tag again"), scShift, false) {
+                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();
-                        selectKeysComboBox();
                     }
                 };
@@ -1915,10 +1752,4 @@
                     Map<String, String> map = new HashMap<>();
                     map.put(t.getKey(), t.getValue());
-//                    for (TaggingPreset tp : TaggingPreset.getMatchingPresets(null, map, false)) {
-//                        icon = tp.getIcon();
-//                        if (icon != null) {
-//                            break;
-//                        }
-//                    }
                     // If still nothing display an empty icon
                     if (icon == null) {
@@ -1932,12 +1763,12 @@
                 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>");
+                        + "<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(), actionShortcutKey);
-                    mainPanel.getActionMap().put(actionShortcutKey, action);
-                    mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(scShift.getKeyStroke(), actionShortcutShiftKey);
-                    mainPanel.getActionMap().put(actionShortcutShiftKey, actionShift);
+                    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));
@@ -1948,6 +1779,6 @@
                             action.actionPerformed(null);
                             // add tags and close window on double-click
-                            
-                            if (e.getClickCount()>1) {
+
+                            if (e.getClickCount() > 1) {
                                 buttonAction(0, null); // emulate OK click and close the dialog
                             }
@@ -1955,5 +1786,4 @@
                             if (e.isShiftDown()) {
                                 performTagAdding();
-                                selectKeysComboBox();
                             }
                         }
@@ -2021,8 +1851,8 @@
             File modelDirectory = new File(MODEL_PATH);
             File modelFile;
-            if(useCombinedModel){
-                if(filesAndWeights.isEmpty()){
+            if (useCombinedModel) {
+                if (filesAndWeights.isEmpty()) {
                     System.out.println("No models selected! Loading defaults..");
-                    if(modelWithClasses){
+                    if (modelWithClasses) {
                         System.out.println("Using default/last model with classes: " + modelDirectory.getAbsolutePath() + "/model_with_classes");
                         modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
@@ -2037,6 +1867,5 @@
                         modelSVMLabelSize = modelSVM.getLabels().length;
                         modelSVMLabels = modelSVM.getLabels();
-                    }
-                    else{
+                    } else {
                         System.out.println("Using default/last model without classes: " + modelDirectory.getAbsolutePath() + "/best_model");
                         modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
@@ -2051,30 +1880,25 @@
                         modelSVMLabelSize = modelSVM.getLabels().length;
                         modelSVMLabels = modelSVM.getLabels();
-                    } 
-                }               
-                if(modelWithClasses){ //check filenames to define if model with classes is selected
+                    }
+                }
+                if (modelWithClasses) { //check filenames to define if model with classes is selected
                     System.out.println("Using combined model with classes");
                     useCombinedSVMmodels(sel, true);
-                }
-                else{
+                } else {
                     System.out.println("Using combined model without classes");
                     useCombinedSVMmodels(sel, false);
-                }               
-                                
-            }
-            else if(useCustomSVMModel){
+                }
+            } else if (useCustomSVMModel) {
                 System.out.println("custom path: " + customSVMModelPath);
-                File checkExistance = new File(customSVMModelPath);             
-                if(checkExistance.exists() && checkExistance.isFile()){
+                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.replace(".0", ".1");
                             String customSVMModelPathWithClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".1";
 
                             modelFile = new File(customSVMModelPathWithClasses);
                             System.out.println(customSVMModelPathWithClasses);
-                        } 
-                        else {
+                        } else {
                             modelFile = new File(customSVMModelPath);
                         }
@@ -2098,14 +1922,12 @@
                     }
                     modelSVMLabelSize = modelSVM.getLabels().length;
-                    modelSVMLabels = modelSVM.getLabels();                    
-
-                } 
-                else {
+                    modelSVMLabels = modelSVM.getLabels();
+
+                } else {
                     //user chose to use a custom model, but did not provide a path to a model:
-                    if(modelWithClasses){
+                    if (modelWithClasses) {
                         System.out.println("Using default/last model with classes");
                         modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
-                    }
-                    else{
+                    } else {
                         System.out.println("Using default/last model without classes");
                         modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
@@ -2121,18 +1943,16 @@
                     }
                     modelSVMLabelSize = modelSVM.getLabels().length;
-                    modelSVMLabels = modelSVM.getLabels();                    
-                    
-                }
-            } 
-            else {
-                if(modelWithClasses){
+                    modelSVMLabels = modelSVM.getLabels();
+
+                }
+            } else {
+                if (modelWithClasses) {
                     System.out.println("Using default/last model with classes");
                     modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
-                }
-                else{
+                } 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());
@@ -2144,11 +1964,11 @@
                 }
                 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.");           
-            
+                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();
@@ -2157,5 +1977,5 @@
             try {
                 transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
-                
+
             } catch (FactoryException ex) {
                 Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
@@ -2165,21 +1985,18 @@
             List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
             OsmPrimitive s;
-            
+
             //get a simple selection
-            if(!osmPrimitiveSelection.isEmpty()){
+            if (!osmPrimitiveSelection.isEmpty()) {
                 s = osmPrimitiveSelection.get(0);
-            }
-            else {
+            } else {
                 return;
             }
 
             selectedInstance = new OSMWay();
-            for(Way selectedWay : s.getDataSet().getSelectedWays()){   
-               // System.out.println(nod.getNodes());
+            for (Way selectedWay : s.getDataSet().getSelectedWays()) {
                 List<Node> selectedWayNodes = selectedWay.getNodes();
-                for(Node node : selectedWayNodes){
+                for (Node node : selectedWayNodes) {
                     node.getCoor();
-                    //System.out.println(node.getCoor()); 
-                    if(node.isLatLonKnown()){
+                    if (node.isLatLonKnown()) {
                         double lat = node.getCoor().lat();
                         double lon = node.getCoor().lon();
@@ -2187,11 +2004,11 @@
                         Coordinate sourceCoordinate = new Coordinate(lon, lat);
                         Coordinate targetGeometry = null;
-                        try {    
+                        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));   
+                        }
+
+                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
                         selectedInstance.addNodeGeometry(geom);
                     }
@@ -2199,10 +2016,9 @@
             }
             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.                    
+            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);
@@ -2210,12 +2026,10 @@
 
                 System.out.println("\n\npolygon");
-            }
-            else if (selectedInstance.getNodeGeometries().size()>1){
-            //it is an open geometry with more than one nodes, make it linestring 
+            } 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
+                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());
@@ -2224,145 +2038,114 @@
 
             Map<String, String> selectedTags = s.getInterestingTags();
-            selectedInstance.setAllTags(selectedTags);             
- 
+            selectedInstance.setAllTags(selectedTags);
+
             //construct vector
-            if(selectedInstance != null){
+            if (selectedInstance != null) {
                 int id;
-                
+
                 OSMClassification classifier = new OSMClassification();
                 classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-                
-                if(useClassFeatures){
+
+                if (useClassFeatures) {
                     ClassFeatures classFeatures = new ClassFeatures();
                     classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
                     id = 1422;
-                }
-                else{
+                } else {
                     id = 1;
                 }
-                
+
                 GeometryFeatures geometryFeatures = new GeometryFeatures(id);
                 geometryFeatures.createGeometryFeatures(selectedInstance);
-                id=geometryFeatures.getLastID();
+                id = geometryFeatures.getLastID();
                 TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
-                textualFeatures.createTextualFeatures(selectedInstance);               
-                
+                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){
-
+                for (FeatureNode featureNode : featureNodeList) {
                     featureNodeArray[i] = featureNode;
-                    //System.out.println("i: " + i + " array:" + featureNodeArray[i]);
                     i++;
-
-                }                    
-                FeatureNode[] testInstance2 = featureNodeArray;                                           
-                
+                }
+                FeatureNode[] testInstance2 = featureNodeArray;
+
                 //compute prediction list for every model
                 int[] ranks = new int[10];
-                
-                for(int l=0; l<10; l++){
+
+                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()){
-                    
+
+                for (File modelFile : alignedFilesAndWeights.keySet()) {
 
                     try {
                         modelSVM = Model.load(modelFile);
-                        //System.out.println("model loaded: " + modelFile.getAbsolutePath());
                     } catch (IOException ex) {
                         Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
                     }
                     modelSVMLabelSize = modelSVM.getLabels().length;
-                    modelSVMLabels = modelSVM.getLabels();            
-                                                               
-                
+                    modelSVMLabels = modelSVM.getLabels();
+
                     Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
-                    for(int h =0; h < modelSVMLabelSize; h++){
-
+                    for (int h = 0; h < modelSVMLabelSize; h++) {
                         mapLabelsToIDs.put(modelSVMLabels[h], h);
-                        //System.out.println(h + "   <->    " + modelSVMLabels[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++){
+                    for (int h = 0; h < scores.length; h++) {
                         scoresValues.put(scores[h], h);
-                        //System.out.println(h + "   <->    " + scores[h]);
-                    }                
+                    }
 
                     Arrays.sort(scores);
-                    int predicted1 = modelSVMLabels[scoresValues.get(scores[scores.length-1])];  
+                    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 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 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])];                  
+                    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)){
-                            //System.out.println("1st predicted class: " +entry.getKey());                     
+                    for (Map.Entry<String, Integer> entry : mapperWithIDs.entrySet()) {
+
+                        if (entry.getValue().equals(predicted1)) {
                             predictedTags[0] = entry.getKey();
-                        }
-                        else if(entry.getValue().equals(predicted2)){
+                        } else if (entry.getValue().equals(predicted2)) {
                             predictedTags[1] = entry.getKey();
-                            //System.out.println("2nd predicted class: " +entry.getKey());
-                        }
-                        else if(entry.getValue().equals(predicted3)){
+                        } else if (entry.getValue().equals(predicted3)) {
                             predictedTags[2] = entry.getKey();
-                            //System.out.println("3rd predicted class: " +entry.getKey()); 
-                        }
-                        else if(entry.getValue().equals(predicted4)){
+                        } else if (entry.getValue().equals(predicted4)) {
                             predictedTags[3] = entry.getKey();
-                            //System.out.println("2nd predicted class: " +entry.getKey());
-                        }
-                        else if(entry.getValue().equals(predicted5)){
+                        } else if (entry.getValue().equals(predicted5)) {
                             predictedTags[4] = entry.getKey();
-                            //System.out.println("3rd predicted class: " +entry.getKey()); 
-                        }                    
-                        else if(entry.getValue().equals(predicted6)){
+                        } else if (entry.getValue().equals(predicted6)) {
                             predictedTags[5] = entry.getKey();
-                            //System.out.println("2nd predicted class: " +entry.getKey());
-                        }
-                        else if(entry.getValue().equals(predicted7)){
+                        } else if (entry.getValue().equals(predicted7)) {
                             predictedTags[6] = entry.getKey();
-                            //System.out.println("3rd predicted class: " +entry.getKey()); 
-                        }
-                        else if(entry.getValue().equals(predicted8)){
+                        } else if (entry.getValue().equals(predicted8)) {
                             predictedTags[7] = entry.getKey();
-                            //System.out.println("2nd predicted class: " +entry.getKey());
-                        }
-                        else if(entry.getValue().equals(predicted9)){
+                        } else if (entry.getValue().equals(predicted9)) {
                             predictedTags[8] = entry.getKey();
-                            //System.out.println("3rd predicted class: " +entry.getKey()); 
-                        }     
-                        else if(entry.getValue().equals(predicted10)){
+                        } else if (entry.getValue().equals(predicted10)) {
                             predictedTags[9] = entry.getKey();
-                            //System.out.println("3rd predicted class: " +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])){
+                    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());
@@ -2371,46 +2154,38 @@
                     }
                     System.out.println("combined, predicted classes: " + Arrays.toString(predictedTags));
-                    
-                    for(int r = 0; r<ranks.length; r++){
+
+                    for (int r = 0; r < ranks.length; r++) {
                         String predictedTag = predictedTags[r];
                         Double currentWeight = alignedFilesAndWeights.get(modelFile);
                         double finalRank = ranks[r]*currentWeight;
-                        //String roundedWeight = new DecimalFormat("##.###").format(finalRank);
-                        //double finalRounded = Double.parseDouble(roundedWeight);
-                        //System.out.println("rank: " + ranks[r] + ", weight: " + currentWeight 
-                               // + ", final rank: " + finalRounded + " " + predictedTags[r]);
-                       
-                        if(scoreMap.containsKey(predictedTag)){
+
+                        if (scoreMap.containsKey(predictedTag)) {
                             Double scoreToAdd = scoreMap.get(predictedTag);
                             scoreMap.put(predictedTag, finalRank+scoreToAdd);
-                        }
-                        else{
+                        } else {
                             scoreMap.put(predictedTag, finalRank);
-                        }                     
+                        }
                         //add final weight - predicted tag
-                    }                    
-                } //files iter  
+                    }
+                } //files iter
                 model.clear();
                 List<Double> scoresList = new ArrayList<>(scoreMap.values());
-                Collections.sort(scoresList ,Collections.reverseOrder());
-                
-                for(Double sco : scoresList){
-                    if(model.size()>9){
+                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.toString()); //displaying score                           
+                    for (Map.Entry<String, Double> scoreEntry : scoreMap.entrySet()) {
+                        if (scoreEntry.getValue().equals(sco)) {
                             model.addElement(scoreEntry.getKey());
                         }
                     }
                 }
-                //System.out.println("final list:" + scoreMap);
-            }           
+            }
         }
 
         private void createOSMObject(Collection<OsmPrimitive> sel) {
-                        
+
             MathTransform transform = null;
             GeometryFactory geometryFactory = new GeometryFactory();
@@ -2419,36 +2194,30 @@
             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
-            //int singleSelectionCount = 0;
-            //Collection<OsmPrimitive> paa = Main.main.getInProgressSelection();
-            
+
             OSMWay selectedInstance;
             List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
             OsmPrimitive s;
-            
+
             //get a simple selection
-            if(!osmPrimitiveSelection.isEmpty()){
+            if (!osmPrimitiveSelection.isEmpty()) {
                 s = osmPrimitiveSelection.get(0);
-            }
-            else {
+            } else {
                 return;
             }
 
             selectedInstance = new OSMWay();
-            for(Way selectedWay : s.getDataSet().getSelectedWays()){   
-               // System.out.println(nod.getNodes());
+            for (Way selectedWay : s.getDataSet().getSelectedWays()) {
                 List<Node> selectedWayNodes = selectedWay.getNodes();
-                for(Node node : selectedWayNodes){
+                for (Node node : selectedWayNodes) {
                     node.getCoor();
-                    //System.out.println(node.getCoor()); 
-                    if(node.isLatLonKnown()){
-                        //LatLon coord = nod.getCoor();
+                    if (node.isLatLonKnown()) {
                         double lat = node.getCoor().lat();
                         double lon = node.getCoor().lon();
@@ -2456,11 +2225,11 @@
                         Coordinate sourceCoordinate = new Coordinate(lon, lat);
                         Coordinate targetGeometry = null;
-                        try {    
+                        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));   
+                        }
+
+                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
                         selectedInstance.addNodeGeometry(geom);
                     }
@@ -2468,14 +2237,12 @@
             }
             Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
-            //System.out.println("full geom: " + fullGeom.toText());
 
             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.                    
+            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);
@@ -2483,12 +2250,10 @@
 
                 System.out.println("\n\npolygon");
-            }
-            else if (selectedInstance.getNodeGeometries().size()>1){
-            //it is an open geometry with more than one nodes, make it linestring 
+            } 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
+                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());
@@ -2496,93 +2261,75 @@
             }
 
-            //System.out.println(tt + "  " + s.getDataSet().getNodes());
-            //Collection<Node> nodes = s.getDataSet().getNodes();
-            //nodeTmp.setGeometry(geom);
-
             Map<String, String> selectedTags = s.getInterestingTags();
             selectedInstance.setAllTags(selectedTags);
-            //System.out.println("selected instance interested tags: " + s.getInterestingTags());
-            //selectedInstance.setTagKeyValue(selectedTags);
-
-            //singleSelectionCount++;               
- 
+
             //construct vector here
-            if(selectedInstance != null){
+            if (selectedInstance != null) {
                 int id;
-                if(mappings == null){
-                   System.out.println("null mappings ERROR");
-                }
-                
+                if (mappings == null) {
+                    System.out.println("null mappings ERROR");
+                }
+
                 OSMClassification classifier = new OSMClassification();
                 classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-                
-                if(modelWithClasses){
+
+                if (modelWithClasses) {
                     ClassFeatures classFeatures = new ClassFeatures();
                     classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
                     id = 1422;
-                }
-                else{
+                } else {
                     id = 1;
                 }
-                
+
                 GeometryFeatures geometryFeatures = new GeometryFeatures(id);
                 geometryFeatures.createGeometryFeatures(selectedInstance);
-                id=geometryFeatures.getLastID();
+                id = geometryFeatures.getLastID();
                 TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
-                textualFeatures.createTextualFeatures(selectedInstance);               
-                
+                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){
-
+                for (FeatureNode featureNode : featureNodeList) {
                     featureNodeArray[i] = featureNode;
-                    //System.out.println("i: " + i + " array:" + featureNodeArray[i]);
                     i++;
-
-                }                    
-                FeatureNode[] testInstance2 = featureNodeArray;                                           
-                
+                }
+                FeatureNode[] testInstance2 = featureNodeArray;
+
                 Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
-                for(int h =0; h < modelSVMLabelSize; h++){
-                    
+                for (int h = 0; h < modelSVMLabelSize; h++) {
                     mapLabelsToIDs.put(modelSVMLabels[h], h);
-                    //System.out.println(h + "   <->    " + modelSVMLabels[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++){
+                for (int h = 0; h < scores.length; h++) {
                     scoresValues.put(scores[h], h);
-                    //System.out.println(h + "   <->    " + scores[h]);
                 }
 
                 Arrays.sort(scores);
-                
+
                 int[] preds = new int[RECOMMENDATIONS_SIZE];
-                for(int p=0; p < RECOMMENDATIONS_SIZE; p++){
+                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])){
+
+                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])){
+                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());
@@ -2590,5 +2337,4 @@
                     }
                 }
-                //System.out.println("createdOSM object, predicted classes: " + Arrays.toString(predictedTags));
                 System.out.println("Optimized - create OSMObject, predicted classes: " + Arrays.toString(predictedTags2));
             }
@@ -2599,5 +2345,5 @@
             InputStream tagsToClassesMapping = TrainWorker.class.getResourceAsStream("/resources/files/Map");
             Mapper mapper = new Mapper();
-            try {   
+            try {
                 mapper.parseFile(tagsToClassesMapping);
 
@@ -2606,25 +2352,22 @@
             }
             mappings = mapper.getMappings();
-            mapperWithIDs = mapper.getMappingsWithIDs(); 
+            mapperWithIDs = mapper.getMappingsWithIDs();
             idsWithMappings = mapper.getIDsWithMappings();
-            //System.out.println("mappings " + mappings);
-            //System.out.println("mapperWithIDs " + mapperWithIDs);
         }
 
         private void loadTextualList(File textualListFile) {
-          
+
             Scanner input = null;
-            
+
             try {
                 input = new Scanner(textualListFile);
-            } 
-            catch (FileNotFoundException ex) {
-                //Logger.getLogger(Statistics.class.getName()).log(Level.SEVERE, null, ex);
-            }
-            while(input.hasNext()) {
+            } catch (FileNotFoundException ex) {
+                Main.warn(ex);
+            }
+            while (input.hasNext()) {
                 String nextLine = input.nextLine();
                 textualList.add(nextLine);
             }
-            System.out.println("Textual List parsed from file successfully." + textualList);  
+            System.out.println("Textual List parsed from file successfully." + textualList);
         }
 
@@ -2647,33 +2390,30 @@
         private Map<File, Double> getAlignedModels(Map<File, Double> filesAndWeights) {
             Map<File, Double> alignedFilesAndWeights = new HashMap<>();
-            if(modelWithClasses){
-                for(Entry<File, Double> entry : filesAndWeights.entrySet()){
+            if (modelWithClasses) {
+                for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
                     String absolutePath = entry.getKey().getAbsolutePath();
-                    if(absolutePath.endsWith(".0")){
+                    if (absolutePath.endsWith(".0")) {
                         String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".1";
                         File alignedFile = new File(newPath);
-                        if(alignedFile.exists()){
+                        if (alignedFile.exists()) {
                             alignedFilesAndWeights.put(alignedFile, entry.getValue());
-                        }                        
-                    }                    
-                    else{
+                        }
+                    } else {
                         alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
-                    }                    
-                }
-            }
-            else{
-                for(Entry<File, Double> entry : filesAndWeights.entrySet()){
+                    }
+                }
+            } else {
+                for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
                     String absolutePath = entry.getKey().getAbsolutePath();
-                    if(absolutePath.endsWith(".1")){
+                    if (absolutePath.endsWith(".1")) {
                         String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".0";
                         File alignedFile = new File(newPath);
-                        if(alignedFile.exists()){
+                        if (alignedFile.exists()) {
                             alignedFilesAndWeights.put(alignedFile, entry.getValue());
-                        }                       
-                    }
-                    else{
+                        }
+                    } else {
                         alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
-                    }                    
-                }                
+                    }
+                }
             }
             return alignedFilesAndWeights;
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecToggleDialog.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecToggleDialog.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecToggleDialog.java	(revision 32404)
@@ -1,4 +1,6 @@
-
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.GridBagLayout;
@@ -19,4 +21,5 @@
 import java.util.Set;
 import java.util.TreeMap;
+
 import javax.swing.JLabel;
 import javax.swing.JPanel;
@@ -41,13 +44,11 @@
 import org.openstreetmap.josm.gui.SideButton;
 import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
-import static org.openstreetmap.josm.tools.I18n.tr;
-import org.openstreetmap.josm.tools.Predicates;
+import org.openstreetmap.josm.gui.dialogs.relation.RelationEditor;
 import org.openstreetmap.josm.tools.Shortcut;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
  * This class is a modification of the PropertiesDialog for the OSMRec.
- * 
- * 
+ *
+ *
  * This dialog displays the tags of the current selected primitives.
  *
@@ -101,6 +102,6 @@
     private final AddAction addAction = new AddAction();
     private final EditActionTrain editAction = new EditActionTrain();
-//    private final DeleteAction deleteAction = new DeleteAction();
-//    private final JosmAction[] josmActions = new JosmAction[]{addAction, editAction, deleteAction};
+    //    private final DeleteAction deleteAction = new DeleteAction();
+    //    private final JosmAction[] josmActions = new JosmAction[]{addAction, editAction, deleteAction};
 
     /**
@@ -143,9 +144,9 @@
         membershipTable.addMouseListener(mouseClickWatch);
         scrollPane.addMouseListener(mouseClickWatch);
-        editHelper.loadTagsIfNeeded(); 
-
-    }
-
-     /**
+        editHelper.loadTagsIfNeeded();
+
+    }
+
+    /**
      * This simply fires up an {@link RelationEditor} for the relation shown; everything else
      * is the editor's business.
@@ -154,10 +155,10 @@
      */
     private void editMembership(int row) {
-        Relation relation = (Relation)membershipData.getValueAt(row, 0);
+        Relation relation = (Relation) membershipData.getValueAt(row, 0);
         Main.map.relationListDialog.selectRelation(relation);
     }
 
     private int findRow(TableModel model, Object value) {
-        for (int i=0; i<model.getRowCount(); i++) {
+        for (int i = 0; i < model.getRowCount(); i++) {
             if (model.getValueAt(i, 0).equals(value))
                 return i;
@@ -174,5 +175,5 @@
     }
 
-   // </editor-fold>
+    // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="Event listeners methods">
@@ -196,8 +197,8 @@
         selectedTag = editHelper.getChangedKey(); // select last added or last edited key by default
         if (selectedTag == null && tagTable.getSelectedRowCount() == 1) {
-            selectedTag = (String)tagData.getValueAt(tagTable.getSelectedRow(), 0);
+            selectedTag = (String) tagData.getValueAt(tagTable.getSelectedRow(), 0);
         }
         if (membershipTable.getSelectedRowCount() == 1) {
-            selectedRelation = (Relation)membershipData.getValueAt(membershipTable.getSelectedRow(), 0);
+            selectedRelation = (Relation) membershipData.getValueAt(membershipTable.getSelectedRow(), 0);
         }
 
@@ -228,5 +229,5 @@
                     Relation r = (Relation) ref;
                     MemberInfo mi = roles.get(r);
-                    if(mi == null) {
+                    if (mi == null) {
                         mi = new MemberInfo(newSel);
                     }
@@ -248,6 +249,5 @@
                 int comp = Boolean.valueOf(o1.isDisabledAndHidden()).compareTo(o2.isDisabledAndHidden());
                 return comp != 0 ? comp : DefaultNameFormatter.getInstance().getRelationComparator().compare(o1, o2);
-            }}
-                );
+            } });
 
         for (Relation r: sortedRelations) {
@@ -261,5 +261,5 @@
         boolean hasTags = hasSelection && tagData.getRowCount() > 0;
         boolean hasMemberships = hasSelection && membershipData.getRowCount() > 0;
-          
+
         addAction.setEnabled(hasSelection);
         //editAction.setEnabled(hasTags || hasMemberships);
@@ -268,5 +268,5 @@
         tagTable.getTableHeader().setVisible(hasTags);
         selectSth.setVisible(!hasSelection);
-        
+
         int selectedIndex;
         if (selectedTag != null && (selectedIndex = findRow(tagData, selectedTag)) != -1) {
@@ -274,7 +274,7 @@
         } else if (selectedRelation != null && (selectedIndex = findRow(membershipData, selectedRelation)) != -1) {
             membershipTable.changeSelection(selectedIndex, 0, false, false);
-        } else if(hasTags) {
+        } else if (hasTags) {
             tagTable.changeSelection(0, 0, false, false);
-        } else if(hasMemberships) {
+        } else if (hasMemberships) {
             membershipTable.changeSelection(0, 0, false, false);
         }
@@ -316,5 +316,5 @@
     // </editor-fold>
 
-     /**
+    /**
      * Class that watches for mouse clicks
      * @author imi
@@ -330,5 +330,5 @@
                     tagTable.clearSelection();
                 }
-            } else if (e.getSource() == tagTable ) {
+            } else if (e.getSource() == tagTable) {
                 // double click, edit or add tag
                 int row = tagTable.rowAtPoint(e.getPoint());
@@ -338,5 +338,4 @@
                 } else {
                     editHelper.addTag();
-                    //btnAdd.requestFocusInWindow();
                 }
             } else if (e.getSource() == membershipTable) {
@@ -347,5 +346,4 @@
             } else {
                 editHelper.addTag();
-                //btnAdd.requestFocusInWindow();
             }
         }
@@ -379,32 +377,4 @@
         }
 
-        String getPositionString() {
-            if (positionString == null) {
-                positionString = Utils.getPositionListString(position);
-                // if not all objects from the selection are member of this relation
-                if (Utils.exists(selection, Predicates.not(Predicates.inCollection(members)))) {
-                    positionString += ",\u2717";
-                }
-                members = null;
-                position = null;
-                selection = null;
-            }
-            return Utils.shortenString(positionString, 20);
-        }
-
-        String getRoleString() {
-            if (roleString == null) {
-                for (RelationMember r : role) {
-                    if (roleString == null) {
-                        roleString = r.getRole();
-                    } else if (!roleString.equals(r.getRole())) {
-                        roleString = tr("<different>");
-                        break;
-                    }
-                }
-            }
-            return roleString;
-        }
-
         @Override
         public String toString() {
@@ -424,4 +394,5 @@
             return false;
         }
+
         @Override
         public Class<?> getColumnClass(int columnIndex) {
@@ -443,5 +414,5 @@
         public void actionPerformed(ActionEvent e) {
             editHelper.addTag();
-            btnAdd.requestFocusInWindow();            
+            btnAdd.requestFocusInWindow();
         }
     }
@@ -452,10 +423,10 @@
      */
     class EditActionTrain extends JosmAction implements ListSelectionListener {
-        EditActionTrain() {            
+        EditActionTrain() {
             super(tr("Train a Model"), /* ICON() */ "dialogs/fix", tr("Start the training engine!"),
                     Shortcut.registerShortcut("properties:edit", tr("Edit Tags"), KeyEvent.VK_S,
                             Shortcut.ALT), false);
             setEnabled(true);
-            updateEnabledState(); 
+            updateEnabledState();
         }
 
@@ -470,7 +441,5 @@
                 int row = membershipTable.getSelectedRow();
                 editHelper.editTag(row, false);
-                //editMembership(row);
-            }
-            else{
+            } else {
                 editHelper.editTag(1, false);
             }
@@ -480,8 +449,4 @@
         protected void updateEnabledState() {
             setEnabled(true);
-//            setEnabled(
-//                    (tagTable != null && tagTable.getSelectedRowCount() == 1)
-//                    ^ (membershipTable != null && membershipTable.getSelectedRowCount() == 1)
-//                    );            
         }
 
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMNode.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMNode.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMNode.java	(revision 32404)
@@ -0,0 +1,108 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.container;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Class containing information about the OSM nodes.
+ * @author imis-nkarag
+ */
+public class OSMNode {
+
+    private String id;
+    private String action; //e.g modify
+    private String visible;
+    private Geometry geometry;
+    private String timestamp;
+    private String uid;
+    private String user;
+    private String version;
+    private String changeset;
+    private final Map<String, String> tags = new HashMap<>();
+
+    //attribute getters
+    public String getID() {
+        return id;
+    }
+
+    public String getAction() {
+        return action;
+    }
+
+    public String getVisible() {
+        return visible;
+    }
+
+    public Geometry getGeometry() {
+        return this.geometry;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public String getUid() {
+        return uid;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public String getChangeset() {
+        return changeset;
+    }
+
+    public Map<String, String> getTagKeyValue() {
+        return tags;
+    }
+
+    //attributes setters
+    public void setID(String id) {
+        this.id = id;
+    }
+
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    public void setVisible(String visible) {
+        this.visible = visible;
+    }
+
+    public void setGeometry(Geometry geometry) {
+        this.geometry = geometry;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public void setChangeset(String changeset) {
+        this.changeset = changeset;
+    }
+
+    public void setTagKeyValue(String tagKey, String tagValue) {
+        this.tags.put(tagKey, tagValue);
+    }
+
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMRelation.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMRelation.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMRelation.java	(revision 32404)
@@ -0,0 +1,55 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.container;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Class containing information about the OSM relations.
+ *
+ * @author imis-nkarag
+ */
+
+public class OSMRelation implements Serializable {
+
+    private String id;
+    private Set<Integer> classIDs;
+    private final List<String> memberReferences = new ArrayList<>();
+    private final Map<String, String> tags = new HashMap<>();
+
+    public String getID() {
+        return id;
+    }
+
+    public List<String> getMemberReferences() {
+        return memberReferences;
+    }
+
+    public Set<Integer> getClassIDs() {
+        return this.classIDs;
+    }
+
+    public Map<String, String> getTagKeyValue() {
+        return tags;
+    }
+
+    public void setID(String id) {
+        this.id = id;
+    }
+
+    public void setClassIDs(Set<Integer> classIDs) {
+        this.classIDs = classIDs;
+    }
+
+    public void addMemberReference(String memberReference) {
+        memberReferences.add(memberReference);
+    }
+
+    public void setTagKeyValue(String tagKey, String tagValue) {
+        this.tags.put(tagKey, tagValue);
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMWay.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMWay.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/container/OSMWay.java	(revision 32404)
@@ -0,0 +1,130 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.container;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+
+/**
+ * Class containing information about the OSM ways.
+ *
+ * @author imis-nkarag
+ */
+public class OSMWay implements Serializable {
+
+    private String id;
+    private String user;
+    private int classID;
+    private Set<Integer> classIDs;
+    private final List<String> nodeReferences = new ArrayList<>(); //node references  //made final
+    private final List<Geometry> nodeGeometries = new ArrayList<>(); //nodeGeometries   //made final
+    private Coordinate[] coordinateList;
+    private Map<String, String> tags = new HashMap<>();
+    private Geometry geometry;
+    private TreeMap<Integer, Double> indexVector = new TreeMap<>();
+    private ArrayList<FeatureNode> featureNodeList = new ArrayList<>();
+
+    //way attributes getters
+    public String getID() {
+        return id;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public List<Geometry> getNodeGeometries() {
+        return nodeGeometries;
+    }
+
+    public Coordinate[] getCoordinateList() {
+        coordinateList = nodeGeometries.toArray(new Coordinate[0]);
+        return coordinateList;
+    }
+
+    public Geometry getGeometry() {
+        return geometry;
+    }
+
+    public List<String> getNodeReferences() {
+        return nodeReferences;
+    }
+
+    public int getNumberOfNodes() {
+        return nodeReferences.size();
+    }
+
+    public Map<String, String> getTagKeyValue() {
+        return tags;
+    }
+
+    public int getClassID() {
+        return classID;
+    }
+
+    public Set<Integer> getClassIDs() {
+        return classIDs;
+    }
+
+    public TreeMap<Integer, Double> getIndexVector() {
+        return indexVector;
+    }
+
+    public void setIndexVector(TreeMap<Integer, Double> indexVector) {
+        this.indexVector = indexVector;
+    }
+
+    //way attributes setters
+    public void setID(String id) {
+        this.id = id;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public void setTagKeyValue(String tagKey, String tagValue) {
+        this.tags.put(tagKey, tagValue);
+    }
+
+    public void addNodeReference(String nodeReference) {
+        nodeReferences.add(nodeReference);
+    }
+
+    public void addNodeGeometry(Geometry geometry) {
+        nodeGeometries.add(geometry);
+    }
+
+    public void setGeometry(Geometry geometry) {
+        this.geometry = geometry;
+    }
+
+    public void setClassID(int classID) {
+        this.classID = classID;
+    }
+
+    public void setClassIDs(Set<Integer> classIDs) {
+        this.classIDs = classIDs;
+    }
+
+    public void setFeature(FeatureNode featureNode) {
+        this.featureNodeList.add(featureNode);
+    }
+
+    public List<FeatureNode> getFeatureNodeList() {
+        return featureNodeList;
+    }
+
+    public void setAllTags(Map<String, String> selectedTags) {
+        tags.putAll(selectedTags);
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/core/TrainWorker.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/core/TrainWorker.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/core/TrainWorker.java	(revision 32404)
@@ -0,0 +1,849 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.core;
+
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.SwingWorker;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.plugins.osmrec.extractor.Analyzer;
+import org.openstreetmap.josm.plugins.osmrec.extractor.LanguageDetector;
+import org.openstreetmap.josm.plugins.osmrec.features.ClassFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.GeometryFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.OSMClassification;
+import org.openstreetmap.josm.plugins.osmrec.features.RelationFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.TextualFeatures;
+import org.openstreetmap.josm.plugins.osmrec.parsers.Mapper;
+import org.openstreetmap.josm.plugins.osmrec.parsers.OSMParser;
+import org.openstreetmap.josm.plugins.osmrec.parsers.Ontology;
+import org.openstreetmap.josm.plugins.osmrec.parsers.TextualStatistics;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+import de.bwaldvogel.liblinear.Linear;
+import de.bwaldvogel.liblinear.Model;
+import de.bwaldvogel.liblinear.Parameter;
+import de.bwaldvogel.liblinear.Problem;
+import de.bwaldvogel.liblinear.SolverType;
+
+/**
+ * Provides the necessary functionality for cross validating and training of SVM models.
+ *
+ * @author imis-nkarag
+ */
+public class TrainWorker extends SwingWorker<Void, Void> implements ActionListener {
+
+    private final String inputFilePath;
+    private static Map<String, String> mappings;
+    private static Map<String, Integer> mapperWithIDs;
+
+    private static List<OSMWay> wayList;
+    private static List<OSMRelation> relationList;
+
+    private static Map<String, List<String>> indirectClasses;
+    private static Map<String, Integer> indirectClassesWithIDs;
+    private static List<String> namesList;
+    private int numberOfTrainingInstances;
+    private final String modelDirectoryPath;
+    private final File modelDirectory;
+    private static double score1 = 0;
+    private static double score5 = 0;
+    private static double score10 = 0;
+    private static double foldScore1 = 0;
+    private static double foldScore5 = 0;
+    private static double foldScore10 = 0;
+    private static double bestScore = 0;
+    private int trainProgress = 0;
+    private final boolean validateFlag;
+    private final double cParameterFromUser;
+    private double bestConfParam;
+    private final int topK;
+    private final int frequency;
+    private final boolean topKIsSelected;
+    private String textualListFilePath;
+
+    private static final boolean USE_CLASS_FEATURES = false;
+    private static final boolean USE_RELATION_FEATURES = false;
+    private static final boolean USE_TEXTUAL_FEATURES = true;
+    private static int numberOfFeatures;
+    private static LanguageDetector languageDetector;
+    private final String inputFileName;
+
+    public TrainWorker(String inputFilePath, boolean validateFlag, double cParameterFromUser,
+            int topK, int frequency, boolean topKIsSelected, LanguageDetector languageDetector) {
+        TrainWorker.languageDetector = languageDetector;
+        this.inputFilePath = inputFilePath;
+        this.validateFlag = validateFlag;
+        this.cParameterFromUser = cParameterFromUser;
+        this.topK = topK;
+        this.frequency = frequency;
+        this.topKIsSelected = topKIsSelected;
+        if (System.getProperty("os.name").contains("ux")) {
+            inputFileName = inputFilePath.substring(inputFilePath.lastIndexOf("/"));
+        } else {
+            inputFileName = inputFilePath.substring(inputFilePath.lastIndexOf("\\"));
+        }
+        System.out.println("find parent directory, create osmrec dir for models: " + new File(inputFilePath).getParentFile());
+        modelDirectoryPath = new File(inputFilePath).getParentFile() + "/OSMRec_models";
+
+        modelDirectory = new File(modelDirectoryPath);
+
+        if (!modelDirectory.exists()) {
+            modelDirectory.mkdir();
+            System.out.println("model directory created!");
+        } else {
+            System.out.println("directory already exists!");
+        }
+    }
+
+    @Override
+    public Void doInBackground() throws Exception {
+        extractTextualList();
+        parseFiles();
+        if (validateFlag) {
+            validateLoop();
+            System.out.println("Training model with the best c: " + bestConfParam);
+            clearDataset();
+            trainModel(bestConfParam);
+            clearDataset();
+            trainModelWithClasses(bestConfParam);
+        } else {
+            clearDataset();
+            trainModel(cParameterFromUser);
+            clearDataset();
+            trainModelWithClasses(cParameterFromUser);
+            System.out.println("done.");
+        }
+        return null;
+    }
+
+    private void extractTextualList() {
+        System.out.println("Running analysis..");
+        //provide top-K
+        //Keep the top-K most frequent terms
+        //Keep terms with frequency higher than N
+        //Use the remaining terms as training features
+
+        Analyzer anal = new Analyzer(inputFilePath, languageDetector);
+        anal.runAnalysis();
+
+        textualListFilePath = modelDirectory.getAbsolutePath()+"/textualList.txt";
+        File textualFile = new File(textualListFilePath); //decide path of models
+        if (textualFile.exists()) {
+            textualFile.delete();
+        }
+        try {
+            textualFile.createNewFile();
+        } catch (IOException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        List<Map.Entry<String, Integer>> textualList;
+        if (topKIsSelected) {
+            textualList = anal.getTopKMostFrequent(topK);
+        } else {
+            textualList = anal.getWithFrequency(frequency);
+        }
+
+        writeTextualListToFile(textualListFilePath, textualList);
+        System.out.println("textual list saved at location:\n" + textualListFilePath);
+        //write list to file and let parser do the loading from the names file
+
+        //method read default list
+        //method extract textual list - > the list will be already in memory, so the names parser doesn t have to be called
+        if (USE_CLASS_FEATURES) {
+            numberOfFeatures = 1422 + 105 + textualList.size(); //105 is number of geometry features
+        } else {
+            numberOfFeatures = 105 + textualList.size();
+        }
+    }
+
+    private void parseFiles() {
+        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();
+
+        InputStream ontologyStream = TrainWorker.class.getResourceAsStream("/resources/files/owl.xml");
+        Ontology ontology = new Ontology(ontologyStream);
+
+        ontology.parseOntology();
+        System.out.println("ontology parsed ");
+        indirectClasses = ontology.getIndirectClasses();
+        indirectClassesWithIDs = ontology.getIndirectClassesIDs();
+
+        InputStream textualFileStream = null;
+        try {
+            textualFileStream = new FileInputStream(new File(textualListFilePath));
+        } catch (FileNotFoundException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        readTextualFromDefaultList(textualFileStream);
+
+        OSMParser osmParser = new OSMParser(inputFilePath);
+
+        osmParser.parseDocument();
+        relationList = osmParser.getRelationList();
+        wayList = osmParser.getWayList();
+        numberOfTrainingInstances = osmParser.getWayList().size();
+        System.out.println("number of instances: " + numberOfTrainingInstances);
+        System.out.println("end of parsing files.");
+
+    }
+
+    public void validateLoop() {
+        Double[] confParams = new Double[] {Math.pow(2, -3), Math.pow(2, 1),
+                Math.pow(2, -10), Math.pow(2, -10), Math.pow(2, -5), Math.pow(2, -3)};
+
+        double bestC = Math.pow(2, -10);
+
+        for (Double param : confParams) {
+
+            foldScore1 = 0;
+            foldScore5 = 0;
+            foldScore10 = 0;
+            System.out.println("\n\n\nrunning for C = " + param);
+            clearDataset();
+            System.out.println("fold1");
+            crossValidateFold(0, 4, 4, 5, false, param); //4-1
+            setProgress(4*((5*(trainProgress++))/confParams.length));
+
+            foldScore1 = foldScore1 + score1;
+            foldScore5 = foldScore5 + score5;
+            foldScore10 = foldScore10 + score10;
+            clearDataset();
+            System.out.println("fold2");
+            crossValidateFold(1, 5, 0, 1, false, param);
+            setProgress(4*((5*(trainProgress++))/confParams.length));
+
+            foldScore1 = foldScore1 + score1;
+            foldScore5 = foldScore5 + score5;
+            foldScore10 = foldScore10 + score10;
+            clearDataset();
+            System.out.println("fold3");
+            crossValidateFold(0, 5, 1, 2, true, param);
+            setProgress(4*((5*(trainProgress++))/confParams.length));
+
+            foldScore1 = foldScore1 + score1;
+            foldScore5 = foldScore5 + score5;
+            foldScore10 = foldScore10 + score10;
+            clearDataset();
+            System.out.println("fold4");
+            //crossValidateFold(0, 5, 1, 2, true, param);
+            crossValidateFold(0, 5, 2, 3, true, param);
+            setProgress(4*((5*(trainProgress++))/confParams.length));
+            //System.out.println((5*trainProgress)/confParams.length);
+
+            foldScore1 = foldScore1 + score1;
+            foldScore5 = foldScore5 + score5;
+            foldScore10 = foldScore10 + score10;
+            clearDataset();
+            System.out.println("fold5");
+            crossValidateFold(0, 5, 3, 4, true, param);
+            setProgress(4*((5*(trainProgress++))/confParams.length));
+
+            foldScore1 = foldScore1 + score1;
+            foldScore5 = foldScore5 + score5;
+            foldScore10 = foldScore10 + score10;
+            System.out.println("\n\nC=" + param + ", average score 1-5-10: " + foldScore1/5 +" "+ foldScore5/5 + " "+ foldScore10/5);
+            if (bestScore < foldScore1) {
+                bestScore = foldScore1;
+                bestC = param;
+            }
+
+        }
+        System.out.println(4*((5*(trainProgress++))/confParams.length));
+        bestConfParam = bestC;
+        System.out.println("best c param= " + bestC + ", score: " + bestScore/5);
+    }
+
+    public void crossValidateFold(int a, int b, int c, int d, boolean skip, double param) {
+        System.out.println("Starting cross validation");
+        int testSize = wayList.size()/5;
+
+        List<OSMWay> trainList = new ArrayList<>();
+        for (int g = a*testSize; g < b*testSize; g++) {  // 0~~1~~2~~3~~4~~5
+            if (skip) {
+                if (g == (c)*testSize) {
+                    g = (c+1)*testSize;
+                }
+            }
+            trainList.add(wayList.get(g));
+        }
+
+        int wayListSizeWithoutUnclassified = trainList.size();
+        System.out.println("trainList size: " + wayListSizeWithoutUnclassified);
+
+        //set classes for each osm instance
+        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size
+        for (OSMWay way : trainList) {
+
+            OSMClassification classifyInstances = new OSMClassification();
+            classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+
+            if (way.getClassIDs().isEmpty()) {
+                wayListSizeWithoutUnclassified -= 1;
+            } else {
+                sizeToBeAddedToArray = sizeToBeAddedToArray + way.getClassIDs().size()-1;
+            }
+        }
+        double C = param;
+        double eps = 0.001;
+        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];
+        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures];
+        int k = 0;
+
+        for (OSMWay way : trainList) {
+            //adding multiple vectors
+            int id;
+            if (USE_CLASS_FEATURES) {
+                ClassFeatures class_vector = new ClassFeatures();
+                class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+                id = 1422;
+            } else {
+                id = 1;
+            }
+            //pass id also: 1422 if using classes, 1 if not
+            GeometryFeatures geometryFeatures = new GeometryFeatures(id);
+            geometryFeatures.createGeometryFeatures(way);
+            id = geometryFeatures.getLastID();
+            //id after geometry, cases: all geometry features with mean-variance boolean intervals:
+            //id = 1526
+            if (USE_RELATION_FEATURES) {
+                RelationFeatures relationFeatures = new RelationFeatures(id);
+                relationFeatures.createRelationFeatures(way, relationList);
+                id = relationFeatures.getLastID();
+            } else {
+                id = geometryFeatures.getLastID();
+            }
+            //id 1531
+
+            TextualFeatures textualFeatures;
+            if (USE_TEXTUAL_FEATURES) {
+                textualFeatures = new TextualFeatures(id, namesList, languageDetector);
+                textualFeatures.createTextualFeatures(way);
+            }
+
+            List<FeatureNode> featureNodeList = way.getFeatureNodeList();
+            FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
+
+            if (!way.getClassIDs().isEmpty()) {
+                int i = 0;
+                for (FeatureNode featureNode : featureNodeList) {
+                    featureNodeArray[i] = featureNode;
+                    i++;
+                }
+                for (int classID : way.getClassIDs()) {
+                    trainingSetWithUnknown2[k] = featureNodeArray;
+                    GROUPS_ARRAY2[k] = classID;
+                    k++;
+                }
+            }
+        }
+
+        Problem problem = new Problem();
+        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;
+        problem.n = numberOfFeatures;
+        //(geometry 105 + textual        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
+        problem.x = trainingSetWithUnknown2; // feature nodes
+        problem.y = GROUPS_ARRAY2; // target values
+        //SolverType solver = SolverType.MCSVM_CS; //Cramer and Singer for multiclass classification - equivalent of SVMlight
+        SolverType solver2 = SolverType.getById(2); //2 -- L2-regularized L2-loss support vector classification (primal)
+
+        Parameter parameter = new Parameter(solver2, C, eps);
+
+        long start = System.nanoTime();
+        System.out.println("training...");
+        PrintStream original = System.out;
+        System.setOut(new PrintStream(new OutputStream() {
+            @Override
+            public void write(int arg0) throws IOException {
+
+            }
+        }));
+
+        Model model = Linear.train(problem, parameter);
+        long end = System.nanoTime();
+        Long elapsedTime = end-start;
+        System.setOut(original);
+        System.out.println("training process completed in: " + NANOSECONDS.toSeconds(elapsedTime) + " seconds.");
+
+        //decide model path and naming and/or way of deleting/creating 1 or more models.
+
+        File modelFile;
+        if (USE_CLASS_FEATURES) {
+            modelFile = new File(modelDirectory.getAbsolutePath()+"/model_with_classes_c=" + param);
+        } else {
+            modelFile = new File(modelDirectory.getAbsolutePath()+"/model_geometries_textual_c=" + param);
+        }
+
+        if (modelFile.exists()) {
+            modelFile.delete();
+        }
+        try {
+            model.save(modelFile);
+            System.out.println("model saved at: " + modelFile);
+        } catch (IOException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        //end of evaluation training
+
+        //test set
+        List<OSMWay> testList = new ArrayList<>();
+        for (int g = c*testSize; g < d*testSize; g++) {
+            testList.add(wayList.get(g));
+            //liblinear test
+        }
+        System.out.println("testList size: " + testList.size());
+        int succededInstances = 0;
+        int succededInstances5 = 0;
+        int succededInstances10 = 0;
+        try {
+            model = Model.load(modelFile);
+        } catch (IOException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        int modelLabelSize = model.getLabels().length;
+        int[] labels = model.getLabels();
+        Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
+        for (int h = 0; h < model.getLabels().length; h++) {
+            mapLabelsToIDs.put(labels[h], h);
+        }
+
+        int wayListSizeWithoutUnclassified2 = testList.size();
+        for (OSMWay way : testList) {
+
+            OSMClassification classifyInstances = new OSMClassification();
+            classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+            if (way.getClassIDs().isEmpty()) {
+                wayListSizeWithoutUnclassified2 -= 1;
+            }
+        }
+
+        FeatureNode[] testInstance2;
+        for (OSMWay way : testList) {
+
+            int id;
+
+            if (USE_CLASS_FEATURES) {
+                ClassFeatures class_vector = new ClassFeatures();
+                class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+                id = 1422;
+            } else {
+                id = 1;
+            }
+
+            //pass id also: 1422 if using classes, 1 if not
+            GeometryFeatures geometryFeatures = new GeometryFeatures(id);
+            geometryFeatures.createGeometryFeatures(way);
+            id = geometryFeatures.getLastID();
+            //id after geometry, cases: all geometry features with mean-variance boolean intervals:
+            //id = 1526
+            if (USE_RELATION_FEATURES) {
+                RelationFeatures relationFeatures = new RelationFeatures(id);
+                relationFeatures.createRelationFeatures(way, relationList);
+                id = relationFeatures.getLastID();
+            } else {
+                id = geometryFeatures.getLastID();
+            }
+            //id 1531
+            if (USE_TEXTUAL_FEATURES) {
+                TextualFeatures textualFeatures = new TextualFeatures(id, namesList, languageDetector);
+                textualFeatures.createTextualFeatures(way);
+            }
+            List<FeatureNode> featureNodeList = way.getFeatureNodeList();
+
+            FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
+
+            int i = 0;
+            for (FeatureNode featureNode : featureNodeList) {
+                featureNodeArray[i] = featureNode;
+                i++;
+            }
+
+            testInstance2 = featureNodeArray;
+            double[] scores = new double[modelLabelSize];
+            Linear.predictValues(model, testInstance2, scores);
+
+            //find index of max values in scores array: predicted classes are the elements of these indexes from array model.getlabels
+            //iter scores and find 10 max values with their indexes first. then ask those indexes from model.getlabels
+            Map<Double, Integer> scoresValues = new HashMap<>();
+            for (int h = 0; h < scores.length; h++) {
+                scoresValues.put(scores[h], h);
+                //System.out.println(h + "   <->    " + scores[h]);
+            }
+
+            Arrays.sort(scores);
+            if (way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])])) {
+                succededInstances++;
+            }
+            if (
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-2])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-3])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-4])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-5])])
+                    ) {
+                succededInstances5++;
+            }
+            if (
+
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-2])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-3])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-4])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-5])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-6])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-7])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-8])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-9])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-10])])
+                    ) {
+                succededInstances10++;
+            }
+        }
+
+        System.out.println("Succeeded " + succededInstances + " of " + testList.size() + " total (1 class prediction)");
+        double precision1 = succededInstances/(double) wayListSizeWithoutUnclassified2;
+        score1 = precision1;
+        System.out.println(precision1);
+
+        System.out.println("Succeeded " + succededInstances5 + " of " + testList.size()+ " total (5 class prediction)");
+        double precision5 = succededInstances5/(double) wayListSizeWithoutUnclassified2;
+        score5 = precision5;
+        System.out.println(precision5);
+
+        System.out.println("Succeeded " + succededInstances10 + " of " + testList.size()+ " total (10 class prediction)");
+        double precision10 = succededInstances10/(double) wayListSizeWithoutUnclassified2;
+        score10 = precision10;
+        System.out.println(precision10);
+    }
+
+    private void trainModel(double param) {
+
+        int wayListSizeWithoutUnclassified = wayList.size();
+        System.out.println("trainList size: " + wayListSizeWithoutUnclassified);
+
+        //set classes for each osm instance
+        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size
+        if (trainProgress > 11) {
+            setProgress(trainProgress-10);
+        } else {
+            setProgress(trainProgress+10);
+        }
+        for (OSMWay way : wayList) {
+            OSMClassification classifyInstances = new OSMClassification();
+            classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+
+            if (way.getClassIDs().isEmpty()) {
+                wayListSizeWithoutUnclassified -= 1;
+            } else {
+                sizeToBeAddedToArray = sizeToBeAddedToArray + way.getClassIDs().size()-1;
+            }
+        }
+        double C = param;
+        double eps = 0.001;
+        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];
+        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures];
+        int k = 0;
+
+        for (OSMWay way : wayList) {
+            //adding multiple vectors
+            int id;
+            if (USE_CLASS_FEATURES) {
+                ClassFeatures class_vector = new ClassFeatures();
+                class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+                id = 1422;
+            } else {
+                id = 1;
+            }
+            //pass id also: 1422 if using classes, 1 if not
+            GeometryFeatures geometryFeatures = new GeometryFeatures(id);
+            geometryFeatures.createGeometryFeatures(way);
+            id = geometryFeatures.getLastID();
+            //id after geometry, cases: all geometry features with mean-variance boolean intervals:
+            //id = 1526
+            if (USE_RELATION_FEATURES) {
+                RelationFeatures relationFeatures = new RelationFeatures(id);
+                relationFeatures.createRelationFeatures(way, relationList);
+                id = relationFeatures.getLastID();
+            } else {
+                id = geometryFeatures.getLastID();
+            }
+            //id 1531
+
+            TextualFeatures textualFeatures;
+            if (USE_TEXTUAL_FEATURES) {
+                textualFeatures = new TextualFeatures(id, namesList, languageDetector);
+                textualFeatures.createTextualFeatures(way);
+            }
+
+            List<FeatureNode> featureNodeList = way.getFeatureNodeList();
+            FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
+
+            if (!way.getClassIDs().isEmpty()) {
+                int i = 0;
+                for (FeatureNode featureNode : featureNodeList) {
+                    featureNodeArray[i] = featureNode;
+                    i++;
+                }
+                for (int classID : way.getClassIDs()) {
+                    trainingSetWithUnknown2[k] = featureNodeArray;
+                    GROUPS_ARRAY2[k] = classID;
+                    k++;
+                }
+            }
+        }
+        Problem problem = new Problem();
+        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;
+        problem.n = numberOfFeatures;
+        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
+        problem.x = trainingSetWithUnknown2; // feature nodes
+        problem.y = GROUPS_ARRAY2; // target values
+        SolverType solver2 = SolverType.getById(2); //2 -- L2-regularized L2-loss support vector classification (primal)
+
+        Parameter parameter = new Parameter(solver2, C, eps);
+
+        long start = System.nanoTime();
+        System.out.println("training...");
+        PrintStream original = System.out;
+        System.setOut(new PrintStream(new OutputStream() {
+            @Override
+            public void write(int arg0) throws IOException {
+
+            }
+        }));
+
+        Model model = Linear.train(problem, parameter);
+        long end = System.nanoTime();
+        Long elapsedTime = end-start;
+        System.setOut(original);
+        System.out.println("training process completed in: " + NANOSECONDS.toSeconds(elapsedTime) + " seconds.");
+
+        //decide model path and naming and/or way of deleting/creating 1 or more models.
+
+        File modelFile = new File(modelDirectory.getAbsolutePath()+"/best_model"); //decide path of models
+
+        File customModelFile;
+        if (topKIsSelected) {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_topK" + topK + ".0");
+        } else {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_maxF" + frequency + ".0");
+        }
+
+
+        if (modelFile.exists()) {
+            modelFile.delete();
+        }
+        if (customModelFile.exists()) {
+            customModelFile.delete();
+        }
+
+        try {
+            //System.out.println("file created");
+            model.save(modelFile);
+            model.save(customModelFile);
+            System.out.println("best model saved at: " + modelFile);
+            System.out.println("custom model saved at: " + customModelFile);
+        } catch (IOException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    private void trainModelWithClasses(double param) {
+
+        int wayListSizeWithoutUnclassified = wayList.size();
+        System.out.println("trainList size: " + wayListSizeWithoutUnclassified);
+
+        //set classes for each osm instance
+        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size
+        for (OSMWay way : wayList) {
+            OSMClassification classifyInstances = new OSMClassification();
+            classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+
+            if (way.getClassIDs().isEmpty()) {
+                wayListSizeWithoutUnclassified -= 1;
+            } else {
+                sizeToBeAddedToArray = sizeToBeAddedToArray + way.getClassIDs().size()-1;
+            }
+        }
+        double C = param;
+        double eps = 0.001;
+        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];
+        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures+1422];
+        int k = 0;
+
+        for (OSMWay way : wayList) {
+            //adding multiple vectors
+            int id;
+            ClassFeatures class_vector = new ClassFeatures();
+            class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+            id = 1422;
+            //pass id also: 1422 if using classes, 1 if not
+            GeometryFeatures geometryFeatures = new GeometryFeatures(id);
+            geometryFeatures.createGeometryFeatures(way);
+            id = geometryFeatures.getLastID();
+            //id after geometry, cases: all geometry features with mean-variance boolean intervals:
+            //id = 1526
+            if (USE_RELATION_FEATURES) {
+                RelationFeatures relationFeatures = new RelationFeatures(id);
+                relationFeatures.createRelationFeatures(way, relationList);
+                id = relationFeatures.getLastID();
+            } else {
+                id = geometryFeatures.getLastID();
+            }
+            //id 1531
+
+            TextualFeatures textualFeatures;
+            if (USE_TEXTUAL_FEATURES) {
+                textualFeatures = new TextualFeatures(id, namesList, languageDetector);
+                textualFeatures.createTextualFeatures(way);
+            }
+
+            List<FeatureNode> featureNodeList = way.getFeatureNodeList();
+            FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
+
+            if (!way.getClassIDs().isEmpty()) {
+                int i = 0;
+                for (FeatureNode featureNode : featureNodeList) {
+                    featureNodeArray[i] = featureNode;
+                    i++;
+                }
+                for (int classID : way.getClassIDs()) {
+                    trainingSetWithUnknown2[k] = featureNodeArray;
+                    GROUPS_ARRAY2[k] = classID;
+                    k++;
+                }
+            }
+        }
+
+        Problem problem = new Problem();
+        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;
+        problem.n = numberOfFeatures+1422;
+        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
+        problem.x = trainingSetWithUnknown2; // feature nodes
+        problem.y = GROUPS_ARRAY2; // target values
+        SolverType solver2 = SolverType.getById(2); //2 -- L2-regularized L2-loss support vector classification (primal)
+
+        Parameter parameter = new Parameter(solver2, C, eps);
+
+        long start = System.nanoTime();
+        System.out.println("training...");
+        PrintStream original = System.out;
+        System.setOut(new PrintStream(new OutputStream() {
+            @Override
+            public void write(int arg0) throws IOException {
+
+            }
+        }));
+
+
+        Model model = Linear.train(problem, parameter);
+        long end = System.nanoTime();
+        Long elapsedTime = end-start;
+        System.setOut(original);
+        System.out.println("training process completed in: " + NANOSECONDS.toSeconds(elapsedTime) + " seconds.");
+
+        //decide model path and naming and/or way of deleting/creating 1 or more models.
+
+        File modelFile = new File(modelDirectory.getAbsolutePath()+"/model_with_classes");
+
+
+        File customModelFile;
+        if (topKIsSelected) {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model" + "_c" + param + "_topK" + topK + ".1");
+        } else {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_maxF" + frequency + ".1");
+        }
+
+        if (customModelFile.exists()) {
+            customModelFile.delete();
+        }
+
+        if (modelFile.exists()) {
+            modelFile.delete();
+        }
+
+        try {
+            model.save(modelFile);
+            model.save(customModelFile);
+            System.out.println("model with classes saved at: " + modelFile);
+            System.out.println("custom model with classes saved at: " + modelFile);
+        } catch (IOException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    private static void clearDataset() {
+        for (OSMWay way : wayList) {
+            way.getFeatureNodeList().clear();
+        }
+    }
+
+    private void readTextualFromDefaultList(InputStream textualFileStream) {
+
+        TextualStatistics textualStatistics = new TextualStatistics();
+        textualStatistics.parseTextualList(textualFileStream);
+        namesList = textualStatistics.getTextualList();
+    }
+
+    @Override
+    protected void done() {
+        try {
+            System.out.println("Training process complete! - > " + get());
+            setProgress(100);
+        } catch (InterruptedException | ExecutionException ignore) {
+            System.out.println("Exception: " + ignore);
+        }
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent ae) {
+        //cancel button, end process after clearing Dataset
+    }
+
+    private static void writeTextualListToFile(String filePath, List<Map.Entry<String, Integer>> textualList) {
+        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8"))) {
+            for (Map.Entry<String, Integer> entry : textualList) {
+                writer.write(entry.getKey());
+                writer.newLine();
+            }
+        } catch (UnsupportedEncodingException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (FileNotFoundException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (IOException ex) {
+            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/Analyzer.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/Analyzer.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/Analyzer.java	(revision 32404)
@@ -0,0 +1,425 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.extractor;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.AbstractMap;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.lucene.analysis.de.GermanAnalyzer;
+import org.apache.lucene.analysis.el.GreekAnalyzer;
+import org.apache.lucene.analysis.en.EnglishAnalyzer;
+import org.apache.lucene.analysis.es.SpanishAnalyzer;
+import org.apache.lucene.analysis.fr.FrenchAnalyzer;
+import org.apache.lucene.analysis.hi.HindiAnalyzer;
+import org.apache.lucene.analysis.ru.RussianAnalyzer;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.analysis.tr.TurkishAnalyzer;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.util.Version;
+
+/**
+ * Analyzes textual information. Language detection, stop words removal, stemming based on language.
+ * Provides methods for retrieving the textual list by frequency and top-K terms.
+ * @author imis-nkarag
+ */
+
+public class Analyzer {
+
+    private final String osmFilePath;
+    private static final HashSet<String> stopWordsList = new HashSet<>(); //add greek list to same file
+    private ArrayList<Entry<String, Integer>> frequencies;
+    private final LanguageDetector languageDetector;
+
+    public Analyzer(String osmFilePath, LanguageDetector languageDetector) {
+        this.osmFilePath = osmFilePath;
+        this.languageDetector = languageDetector;
+    }
+
+    public void runAnalysis() {
+        //textual list
+        FrequenceExtractor frequenceExtractor = new FrequenceExtractor(osmFilePath);
+        frequenceExtractor.parseDocument();
+        Set<Map.Entry<String, Integer>> frequencyEntries = frequenceExtractor.getFrequency().entrySet();
+
+        //parse stop words
+        loadStopWords();
+
+        //send some samples
+        ArrayList<Map.Entry<String, Integer>> normalizedList = new ArrayList<>();
+        ArrayList<String> sampleList = new ArrayList<>();
+        int iters = 0;
+        for (Map.Entry<String, Integer> frequencyEntry : frequencyEntries) {
+            if (iters < 10) {
+                sampleList.add(frequencyEntry.getKey());
+                iters++;
+            }
+            //remove parenthesis etc here
+            if (!stopWordsList.contains(frequencyEntry.getKey())) {
+                String normalizedName = frequencyEntry.getKey().toLowerCase();
+                normalizedName = normalizedName.replaceAll("[-+.^:,?;'{}\"!()\\[\\]]", "");
+
+                normalizedList.add(new AbstractMap.SimpleEntry<>(normalizedName, frequencyEntry.getValue()));
+            }
+        }
+
+        Map<String, Integer> langs = new HashMap<>();
+        langs.put("en", 0);
+        langs.put("el", 0);
+        langs.put("de", 0);
+        langs.put("es", 0);
+        langs.put("ru", 0);
+        langs.put("hi", 0);
+        langs.put("zh", 0);
+        langs.put("tr", 0);
+        langs.put("fr", 0);
+
+        for (String word : sampleList) {
+            //System.out.println("to be detected: " + word);
+            if (!word.isEmpty()) {
+                String lang;
+                lang = languageDetector.detect(word);
+                switch (lang) {
+                case "en":
+                    //en++;
+                    langs.put("en", langs.get("en")+1);
+                    break;
+                case "el":
+                    //el++;
+                    langs.put("el", langs.get("el")+1);
+                    break;
+                case "de":
+                    //de++;
+                    langs.put("de", langs.get("de")+1);
+                    break;
+                case "es":
+                    //es++;
+                    langs.put("es", langs.get("es")+1);
+                    break;
+                case "ru":
+                    //ru++;
+                    langs.put("ru", langs.get("ru")+1);
+                    break;
+                case "fr":
+                    //fr++;
+                    langs.put("fr", langs.get("fr")+1);
+                    break;
+                case "zh":
+                    //zh++;
+                    langs.put("zh", langs.get("zh")+1);
+                    break;
+                case "tr":
+                    //tr++;
+                    langs.put("tr", langs.get("tr")+1);
+                    break;
+                case "hi":
+                    //hi++;
+                    langs.put("hi", langs.get("hi")+1);
+                    break;
+                    //other lang, no support yet
+                    //System.out.println("found other language, no support yet :(");
+                default:
+                    break;
+                }
+            }
+        }
+
+        int maxLangFreq = langs.get("en");
+        String dominantLanguage = "en";
+        for (Entry<String, Integer> lang : langs.entrySet()) {
+            if (lang.getValue() > maxLangFreq) {
+                maxLangFreq = lang.getValue();
+                dominantLanguage = lang.getKey();
+            }
+        }
+
+        switch (dominantLanguage) {
+        case "en":
+            normalizedList = stemEnglish(normalizedList);
+            break;
+        case "el":
+            normalizedList = stemGreek(normalizedList);
+            break;
+        case "de":
+            normalizedList = stemGerman(normalizedList);
+            break;
+        case "es":
+            normalizedList = stemSpanish(normalizedList);
+            break;
+        case "ru":
+            normalizedList = stemRussian(normalizedList);
+            break;
+        case "fr":
+            normalizedList = stemFrench(normalizedList);
+            break;
+        case "zh":
+            normalizedList = stemChinese(normalizedList);
+            break;
+        case "tr":
+            normalizedList = stemTurkish(normalizedList);
+            break;
+        case "hi":
+            normalizedList = stemHindi(normalizedList);
+            break;
+        default:
+            normalizedList = stemEnglish(normalizedList);
+            break;
+        }
+
+        Collections.sort(normalizedList, new Comparator<Map.Entry<String, Integer>>() {
+            @Override
+            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
+                return (o2.getValue()).compareTo(o1.getValue());
+            }
+        });
+        setFrequencies(normalizedList);
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemGreek(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer greekAnalyzer = new GreekAnalyzer(Version.LUCENE_36);
+        QueryParser greekParser = new QueryParser(Version.LUCENE_36, "", greekAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + greekParser.parse(entry.getKey()));
+                    String stemmedWord = greekParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemEnglish(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer englishAnalyzer = new EnglishAnalyzer(Version.LUCENE_36);
+        QueryParser englishParser = new QueryParser(Version.LUCENE_36, "", englishAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = englishParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemGerman(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer germanAnalyzer = new GermanAnalyzer(Version.LUCENE_36);
+        QueryParser germanParser = new QueryParser(Version.LUCENE_36, "", germanAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = germanParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemSpanish(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer spanishAnalyzer = new SpanishAnalyzer(Version.LUCENE_36);
+        QueryParser spanishParser = new QueryParser(Version.LUCENE_36, "", spanishAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = spanishParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemRussian(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer russianAnalyzer = new RussianAnalyzer(Version.LUCENE_36);
+        QueryParser russianParser = new QueryParser(Version.LUCENE_36, "", russianAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = russianParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemFrench(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer frenchAnalyzer = new FrenchAnalyzer(Version.LUCENE_36);
+        QueryParser frenchParser = new QueryParser(Version.LUCENE_36, "", frenchAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = frenchParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemChinese(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer chineseAnalyzer = new StandardAnalyzer(Version.LUCENE_36);
+        QueryParser chineseParser = new QueryParser(Version.LUCENE_36, "", chineseAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = chineseParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemTurkish(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer turkishAnalyzer = new TurkishAnalyzer(Version.LUCENE_36);
+        QueryParser turkishParser = new QueryParser(Version.LUCENE_36, "", turkishAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = turkishParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private static ArrayList<Map.Entry<String, Integer>> stemHindi(List<Map.Entry<String, Integer>> normalizedList) {
+        org.apache.lucene.analysis.Analyzer hindiAnalyzer = new HindiAnalyzer(Version.LUCENE_36);
+        QueryParser hindiParser = new QueryParser(Version.LUCENE_36, "", hindiAnalyzer);
+        ArrayList<Map.Entry<String, Integer>> stemmedList = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : normalizedList) {
+            if (!entry.getKey().isEmpty()) {
+                try {
+                    //System.out.println("result: " + englishParser.parse(entry.getKey()));
+                    String stemmedWord = hindiParser.parse(entry.getKey()).toString();
+                    SimpleEntry<String, Integer> stemmed = new SimpleEntry<>(stemmedWord, entry.getValue());
+                    if (!stemmedWord.equals("")) {
+                        stemmedList.add(stemmed);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+        return stemmedList;
+    }
+
+    private void loadStopWords() {
+        //parse stopwordsList
+        InputStream fstream = Analyzer.class.getResourceAsStream("/resources/files/stopWords.txt");
+
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(fstream))) {
+            String strLine;
+
+            while ((strLine = br.readLine()) != null) {
+                stopWordsList.add(strLine);
+            }
+
+        } catch (IOException ex) {
+            Logger.getLogger(Analyzer.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    private void setFrequencies(ArrayList<Map.Entry<String, Integer>> frequencies) {
+        this.frequencies = frequencies;
+    }
+
+    public List<Map.Entry<String, Integer>> getFrequencies() {
+        return Collections.unmodifiableList(frequencies);
+    }
+
+    public List<Map.Entry<String, Integer>> getTopKMostFrequent(int topK) {
+        //todo recheck
+        if (topK > frequencies.size()) {
+            return Collections.unmodifiableList(frequencies);
+        } else {
+            return frequencies.subList(0, topK);
+        }
+    }
+
+    public List<Map.Entry<String, Integer>> getWithFrequency(int minFrequency) {
+        ArrayList<Map.Entry<String, Integer>> withFrequency = new ArrayList<>();
+        for (Map.Entry<String, Integer> entry : frequencies) {
+            if (entry.getValue() > minFrequency) {
+                withFrequency.add(entry);
+            } else {
+                return withFrequency;
+            }
+        }
+        return withFrequency;
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/FrequenceExtractor.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/FrequenceExtractor.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/FrequenceExtractor.java	(revision 32404)
@@ -0,0 +1,202 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.extractor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMNode;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.tools.Utils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Parses OSM xml and extracts the frequencies of the name tag values.
+ *
+ * @author imis-nkarag
+ */
+
+public class FrequenceExtractor extends DefaultHandler {
+
+    private final List<OSMNode> nodeList; //will be populated with nodes
+    private final List<OSMRelation> relationList;
+    private final Map<String, OSMNode> nodesWithIDs; //map containing IDs as Strings and the corresponding OSMNode objects
+    private final List<OSMWay> wayList;  //populated with ways of the OSM file
+    private final String osmXmlFileName;
+    private OSMNode nodeTmp;
+    private OSMWay wayTmp;
+    private OSMRelation relationTmp;
+    private boolean inWay = false; //when parser is in a way node becomes true in order to track the parser position
+    private boolean inNode = false; //becomes true when the parser is in a simple node
+    private boolean inRelation = false; //becomes true when the parser is in a relarion node
+    private Map<String, Integer> frequency;
+
+    public FrequenceExtractor(String osmXmlFileName) {
+        this.osmXmlFileName = osmXmlFileName;
+        nodeList = new ArrayList<>();
+        wayList = new ArrayList<>();
+        relationList = new ArrayList<>();
+        nodesWithIDs = new HashMap<>();
+        frequency = new HashMap<>();
+        for (int i = 0; i < 100; i++) {
+            frequency.put("", 0);
+        }
+    }
+
+    public void parseDocument() {
+        Main.info("extracting frequencies...");
+        try {
+            Utils.newSafeSAXParser().parse(osmXmlFileName, this);
+        } catch (ParserConfigurationException | IOException | SAXException e) {
+            Main.error(e);
+        }
+    }
+
+    @Override
+    public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
+
+        // if current element is an OSMNode , create new node and populate with the appropriate values
+        if (elementName.equalsIgnoreCase("node")) {
+            nodeTmp = new OSMNode();
+            inNode = true;
+            inWay = false;
+            inRelation = false;
+
+        } else if (elementName.equalsIgnoreCase("way")) {
+            wayTmp = new OSMWay();
+            //wayTmp.setID(attributes.getValue("id"));
+            inWay = true;
+            inNode = false;
+            inRelation = false;
+        } else if (elementName.equalsIgnoreCase("relation")) {
+            relationTmp = new OSMRelation();
+            //relationTmp.setID(attributes.getValue("id"));
+            inRelation = true;
+            inWay = false;
+            inNode = false;
+        } else if (elementName.equalsIgnoreCase("nd")) {
+            //wayTmp.addNodeReference(attributes.getValue("ref"));
+
+        } else if (elementName.equalsIgnoreCase("tag")) {
+
+            if (inNode) {
+                //if the path is in an OSMNode set tagKey and value to the corresponding node
+                nodeTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+            } else if (inWay) {
+                //else if the path is in an OSM way set tagKey and value to the corresponding way
+                wayTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+            } else if (inRelation) {
+                //set the key-value pairs of relation tags
+                relationTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+            }
+
+        } else if (elementName.equalsIgnoreCase("member")) {
+            //relationTmp.addMemberReference(attributes.getValue("ref"));
+        }
+    }
+
+    @Override
+    public void endElement(String s, String s1, String element) throws SAXException {
+        // if end of node element, add to appropriate list
+        if (element.equalsIgnoreCase("node")) {
+            Map<String, String> tags = nodeTmp.getTagKeyValue();
+            if (tags.keySet().contains("name")) {
+                for (Map.Entry<String, String> tag : tags.entrySet()) {
+                    if (tag.getKey().equals("name")) {
+                        //split name value in each white space and store the values separetely. Count each occurance
+                        String name = tag.getValue();
+                        String[] SplitName = name.split("\\s+");
+
+                        for (String split : SplitName) {
+                            //put all splits with zero, at the constructor. put here the incremented values. for tomoro
+                            if (frequency.get(split) != null) {
+                                int k = frequency.get(split) +1;
+                                frequency.put(split, k);
+                            } else {
+                                frequency.put(split, 1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (element.equalsIgnoreCase("way")) {
+            //name frequency
+            Map<String, String> tags = wayTmp.getTagKeyValue();
+
+            if (tags.keySet().contains("name")) {
+                for (Map.Entry<String, String> tag : tags.entrySet()) {
+                    if (tag.getKey().equals("name")) {
+                        //split name value in each white space and store the values separetely. Count each occurance
+                        String name = tag.getValue();
+                        String[] SplitName = name.split("\\s+");
+                        for (String split : SplitName) {
+                            //put all splits with zero, at the constructor. put here the incremented values. for tomoro
+                            if (frequency.get(split) != null) {
+                                int k = frequency.get(split) +1;
+                                frequency.put(split, k);
+                            } else {
+                                frequency.put(split, 1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (element.equalsIgnoreCase("relation")) {
+            //name frequency
+            Map<String, String> tags = relationTmp.getTagKeyValue();
+
+            if (tags.keySet().contains("name")) {
+                for (Map.Entry<String, String> tag : tags.entrySet()) {
+                    if (tag.getKey().equals("name")) {
+                        //split name value in each white space and store the values separetely. Count each occurance
+                        String name = tag.getValue();
+                        String[] SplitName = name.split("\\s+");
+
+                        for (String split : SplitName) {
+                            //put all splits with zero, at the constructor. put here the incremented values. for tomoro
+                            if (frequency.get(split) != null) {
+                                int k = frequency.get(split) +1;
+                                frequency.put(split, k);
+                            } else {
+                                frequency.put(split, 1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public List<OSMNode> getNodeList() {
+        return nodeList;
+    }
+
+    public List<OSMWay> getWayList() {
+        return wayList;
+    }
+
+    public List<OSMRelation> getRelationList() {
+        return relationList;
+    }
+
+    public Map<String, OSMNode> getNodesWithIDs() {
+        return nodesWithIDs;
+    }
+
+    //frequency temp
+    public Map<String, Integer> getFrequency() {
+        return frequency;
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/LanguageDetector.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/LanguageDetector.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/LanguageDetector.java	(revision 32404)
@@ -0,0 +1,119 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.extractor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Utils;
+
+import com.cybozu.labs.langdetect.Detector;
+import com.cybozu.labs.langdetect.DetectorFactory;
+import com.cybozu.labs.langdetect.LangDetectException;
+
+/**
+ * Detects language of osm textual information
+ *
+ * @author imis-nkarag
+ */
+public final class LanguageDetector {
+
+    private static LanguageDetector languageDetector = null;
+
+    private LanguageDetector() {
+        //prevent instatiation
+    }
+
+    public static LanguageDetector getInstance(String languageProfilesPath) {
+        if (languageDetector == null) {
+            languageDetector = new LanguageDetector();
+            loadProfilesFromStream(languageProfilesPath);
+            //profilesLoaded = true;
+        }
+        return languageDetector;
+    }
+
+    public static void loadProfilesFromStream(String languageProfilesPath) { //create profiles directory in system from stream and load them
+
+        /*  supported languages
+            el:greek, en:english, de:german, fr:french, es:spanish, ru:russian, tr:turkish, zh-cn:chinese, hi:hindi
+         */
+        InputStream languageProfilesInputStreamEl = LanguageDetector.class.getResourceAsStream("/profiles/el");
+        InputStream languageProfilesInputStreamEn = LanguageDetector.class.getResourceAsStream("/profiles/en");
+        InputStream languageProfilesInputStreamDe = LanguageDetector.class.getResourceAsStream("/profiles/de");
+        InputStream languageProfilesInputStreamFr = LanguageDetector.class.getResourceAsStream("/profiles/fr");
+        InputStream languageProfilesInputStreamEs = LanguageDetector.class.getResourceAsStream("/profiles/es");
+        InputStream languageProfilesInputStreamRu = LanguageDetector.class.getResourceAsStream("/profiles/ru");
+        InputStream languageProfilesInputStreamTr = LanguageDetector.class.getResourceAsStream("/profiles/tr");
+        InputStream languageProfilesInputStreamZh = LanguageDetector.class.getResourceAsStream("/profiles/zh-cn");
+        InputStream languageProfilesInputStreamHi = LanguageDetector.class.getResourceAsStream("/profiles/hi");
+        //InputStream languageProfilesInputStream2 = LanguageDetector.class.getResourceAsStream("/resources/profiles/en");
+
+        if (!new File(languageProfilesPath).exists()) {
+            Utils.mkDirs(new File(languageProfilesPath));
+        }
+
+        File languageProfilesOutputFileEl = new File(languageProfilesPath + "/el");
+        File languageProfilesOutputFileEn = new File(languageProfilesPath + "/en");
+        File languageProfilesOutputFileDe = new File(languageProfilesPath + "/de");
+        File languageProfilesOutputFileFr = new File(languageProfilesPath + "/fr");
+        File languageProfilesOutputFileEs = new File(languageProfilesPath + "/es");
+        File languageProfilesOutputFileRu = new File(languageProfilesPath + "/ru");
+        File languageProfilesOutputFileTr = new File(languageProfilesPath + "/tr");
+        File languageProfilesOutputFileZh = new File(languageProfilesPath + "/zh-cn");
+        File languageProfilesOutputFileHi = new File(languageProfilesPath + "/hi");
+
+        try {
+            languageProfilesOutputFileEl.createNewFile();
+            languageProfilesOutputFileEn.createNewFile();
+            languageProfilesOutputFileDe.createNewFile();
+            languageProfilesOutputFileFr.createNewFile();
+            languageProfilesOutputFileEs.createNewFile();
+            languageProfilesOutputFileRu.createNewFile();
+            languageProfilesOutputFileTr.createNewFile();
+            languageProfilesOutputFileZh.createNewFile();
+            languageProfilesOutputFileHi.createNewFile();
+        } catch (IOException ex) {
+            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+            Main.error(ex);
+        }
+
+        try {
+            Files.copy(languageProfilesInputStreamEl, languageProfilesOutputFileEl.toPath());
+            Files.copy(languageProfilesInputStreamEn, languageProfilesOutputFileEn.toPath());
+            Files.copy(languageProfilesInputStreamDe, languageProfilesOutputFileDe.toPath());
+            Files.copy(languageProfilesInputStreamFr, languageProfilesOutputFileFr.toPath());
+            Files.copy(languageProfilesInputStreamEs, languageProfilesOutputFileEs.toPath());
+            Files.copy(languageProfilesInputStreamRu, languageProfilesOutputFileRu.toPath());
+            Files.copy(languageProfilesInputStreamTr, languageProfilesOutputFileTr.toPath());
+            Files.copy(languageProfilesInputStreamZh, languageProfilesOutputFileZh.toPath());
+            Files.copy(languageProfilesInputStreamHi, languageProfilesOutputFileHi.toPath());
+        } catch (IOException ex) {
+            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+            Main.error(ex);
+        }
+
+        try {
+            DetectorFactory.loadProfile(languageProfilesPath);
+        } catch (LangDetectException ex) {
+            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+            Main.error(ex);
+        }
+    }
+
+    public String detect(String text) {
+        try {
+            Detector detector = DetectorFactory.create();
+            detector.append(text);
+            return detector.detect();
+        } catch (LangDetectException ex) {
+            Logger.getLogger(LanguageDetector.class.getName()).log(Level.SEVERE, null, ex);
+            Main.error(ex);
+            return "en"; //default lang to return if anything goes wrong at detection
+        }
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/SampleModelsExtractor.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/SampleModelsExtractor.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/extractor/SampleModelsExtractor.java	(revision 32404)
@@ -0,0 +1,68 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.extractor;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author imis-nkarag
+ */
+public class SampleModelsExtractor {
+
+    public void extractSampleSVMmodel(String modelName, String modelPath) {
+        InputStream svmModelStream;
+        FileOutputStream outputStream = null;
+
+        File targetFile = new File(modelPath);
+
+        if (targetFile.exists()) {
+            return;
+        }
+        try {
+            targetFile.createNewFile();
+        } catch (IOException ex) {
+            Logger.getLogger(SampleModelsExtractor.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        System.out.println("trying to get stream.. for " + "/resources/files/" + modelName);
+        svmModelStream = SampleModelsExtractor.class.getResourceAsStream("/resources/files/" + modelName);
+
+        try {
+            outputStream = new FileOutputStream(targetFile);
+
+            int read = 0;
+            byte[] bytes = new byte[1024];
+
+            try {
+                while ((read = svmModelStream.read(bytes)) != -1) {
+                    outputStream.write(bytes, 0, read);
+                }
+            } catch (IOException ex) {
+                Logger.getLogger(SampleModelsExtractor.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        } catch (IOException ex) {
+            Logger.getLogger(SampleModelsExtractor.class.getName()).log(Level.SEVERE, null, ex);
+        } finally {
+            if (svmModelStream != null) {
+                try {
+                    svmModelStream.close();
+                } catch (IOException e) {
+                    Logger.getLogger(SampleModelsExtractor.class.getName()).log(Level.SEVERE, null, e);
+                }
+            }
+            if (outputStream != null) {
+                try {
+                    // outputStream.flush();
+                    outputStream.close();
+                } catch (IOException e) {
+                    Logger.getLogger(SampleModelsExtractor.class.getName()).log(Level.SEVERE, null, e);
+                }
+            }
+        }
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/ClassFeatures.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/ClassFeatures.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/ClassFeatures.java	(revision 32404)
@@ -0,0 +1,80 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.features;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+
+/**
+ * Constructs the class feature nodes for liblinear.
+ * @author imis-nkarag
+ */
+public class ClassFeatures {
+
+    private int directClassID = 0;
+
+    public void createClassFeatures(OSMWay wayNode, Map<String, String> mappings, Map<String, Integer> mappingsWithIDs,
+            Map<String, List<String>> indirectClasses, Map<String, Integer> indirectClassesIDs) {
+
+        //iteration for each way node in the wayList
+        Set<Integer> sortedIndirectIDs = new TreeSet<>();
+        Set<Integer> sortedDirectIDs = new TreeSet<>();
+        for (Map.Entry<String, String> wayTagKeyValue : wayNode.getTagKeyValue().entrySet()) {
+            //iteration for each tag (key-value) in the current way node
+
+            //concat key and value to use it later for checking
+            String key = wayTagKeyValue.getKey() + " " + wayTagKeyValue.getValue();
+
+            for (Map.Entry<String, String> tagMappedToClass : mappings.entrySet()) {
+                //entry of mappings is e.g "highway residential <-> ResidentialHighway"
+                //iteration to discover the wayNode class. This class's ID will be the start of the vector
+
+                if (key.equals(tagMappedToClass.getKey())) {
+                    String className = tagMappedToClass.getValue();
+                    directClassID = mappingsWithIDs.get(className);
+
+                    sortedDirectIDs.add(directClassID);
+
+                    //the direct class id is the last direct class that the instance is found to belong
+
+                    List<String> superClassesList = indirectClasses.get(className);
+
+                    if (superClassesList != null) { //check if the class has no superclasses
+
+                        for (String superClass: superClassesList) {
+
+                            Integer indirectID = indirectClassesIDs.get(superClass); //to save time here
+                            if (indirectID != null) { // there is a chance here that the ID is null,
+                                //cause the list of super Classes  might contain extra classes  with no ID
+                                //in the indirectClassesIDs map which is constructed from listHierarchyRootClasses method
+                                //at the OntologyParser.
+                                //so this condition check will remain for now
+
+                                if (!(sortedIndirectIDs.contains(indirectID))) {
+                                    sortedIndirectIDs.add(indirectID);
+                                    //wayNode.getIndexVector().put(indirectID, 1.0);
+                                }
+                                //the construction of the indirectClassVectorPortion has been moved below, sorted
+                                //indirectClassVectorPortion = indirectClassVectorPortion + indirectID + ":1 ";
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        wayNode.setClassIDs(sortedDirectIDs);
+        for (Integer dirID : sortedDirectIDs) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(dirID, 1));
+        }
+        for (Integer indID : sortedIndirectIDs) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(indID, 1));
+        }
+        wayNode.setClassID(directClassID);
+        //System.out.println("class: " + wayNode.getFeatureNodeList());
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/GeometryFeatures.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/GeometryFeatures.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/GeometryFeatures.java	(revision 32404)
@@ -0,0 +1,488 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.features;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+
+/**
+ * Constructs the geometry feature nodes for liblinear.
+ *
+ * @author imis-nkarag
+ */
+public class GeometryFeatures {
+
+    private int id; //= 1422; //pass this as a param from main
+    private final GeometryFactory geometryFactory = new GeometryFactory();
+    private static final int NUMBER_OF_AREA_FEATURES = 25;
+    private static final int NUMBER_OF_POINTS = 13;
+    private static final int NUMBER_OF_MEAN = 23; //for boolean intervals
+    private static final int NUMBER_OF_VARIANCE = 37; //for boolean intervals
+
+    public GeometryFeatures(int id) {
+        this.id = id;
+    }
+
+    public void createGeometryFeatures(OSMWay wayNode) {
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        ///////////////////  geometry Features ///////////////////
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // geometry type feature //
+        String geometryType = wayNode.getGeometry().getGeometryType();
+        switch (geometryType) {
+        //the IDs are unique for each geometry type
+        case "LineString":
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1));
+            id += 4;
+            break;
+        case "Polygon":
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+1, 1));
+            id += 4;
+            break;
+        case "LinearRing":
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+2, 1));
+            id += 4;
+            break;
+        case "Point":
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+3, 1));
+            id += 4;
+            break;
+        }
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // rectangle geometry shape feature //
+        //id 1426
+        if (wayNode.getGeometry().isRectangle()) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // number of points of geometry feature //
+        id++; //1427
+        int numberOfPoints = wayNode.getGeometry().getNumPoints();
+        numberOfPointsFeature(numberOfPoints, wayNode);
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // area of geometry feature //
+        //id 1440
+        double area = wayNode.getGeometry().getArea();
+
+        if (geometryType.equals("Polygon")) {
+
+            areaFeature(area, wayNode);
+            //the id increases by 25 in the areaFeature method
+        } else {
+            id += 25;
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // resembles to a circle feature //
+        //id 1465
+        if (geometryResemblesCircle(wayNode)) { //this method checks if the shape of the geometry resembles to a circle
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+        }
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // mean edge feature //
+
+        id++;
+        //TOGGLE COMMENT !! commenting out mean and variance to run the best case
+
+        Coordinate[] nodeGeometries = wayNode.getGeometry().getCoordinates();
+        List<Double> edgeLengths = new ArrayList<>();
+
+        if (!wayNode.getGeometry().getGeometryType().toUpperCase().equals("POINT")) {
+            for (int i = 0; i < nodeGeometries.length-1; i++) {
+                Coordinate[] nodePair = new Coordinate[2];
+                nodePair[0] = nodeGeometries[i];
+                nodePair[1] = nodeGeometries[i+1];
+                LineString tempGeom = geometryFactory.createLineString(nodePair);
+                edgeLengths.add(tempGeom.getLength());
+            }
+        } else {
+            edgeLengths.add(0.0);
+        }
+        double edgeSum = 0;
+        for (Double edge : edgeLengths) {
+            edgeSum = edgeSum + edge;
+        }
+        double mean = edgeSum/edgeLengths.size();
+
+        //intervals with boolean values for mean feature
+
+        handleMean(wayNode, mean);
+
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        // variance feature//
+        double sum = 0;
+        for (Double edge : edgeLengths) {
+            sum = sum + (edge-mean)*(edge-mean);
+        }
+
+        double normalizedVariance = (sum/edgeLengths.size())/(mean*mean); //normalized with square of mean value
+
+        handleVariance(wayNode, normalizedVariance);
+        setLastID(id);
+    }
+
+    private void handleMean(OSMWay wayNode, double mean) {
+        if (mean < 2) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 4) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+1, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 6) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+2, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 8) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+3, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 10) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+4, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 12) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+5, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 14) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+6, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 16) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+7, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 18) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+8, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 20) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+9, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 25) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+10, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 30) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+11, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 35) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+12, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 40) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+13, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 45) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+14, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 50) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+15, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 60) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+16, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 70) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+17, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 80) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+18, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 90) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+19, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 100) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+20, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else if (mean < 200) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+21, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        } else {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+22, 1.0));
+            id = id + NUMBER_OF_MEAN;
+        }
+    }
+
+    private void handleVariance(OSMWay wayNode, double normalizedVariance) {
+        if (normalizedVariance == 0) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.005) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+1, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.01) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+2, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.02) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+3, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.03) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+4, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.04) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+5, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.05) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+6, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.06) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+7, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.07) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+8, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.08) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+9, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.09) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+10, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.1) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+11, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.12) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+12, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.14) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+13, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.16) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+14, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.18) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+15, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.20) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+16, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.22) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+17, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.24) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+18, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.26) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+19, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.28) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+20, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.30) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+21, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.32) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+22, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.34) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+23, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.36) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+24, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.38) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+25, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.40) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+26, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.42) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+27, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.44) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+28, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.46) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+29, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.48) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+30, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.5) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+31, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.6) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+32, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.7) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+33, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.8) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+34, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 0.9) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+35, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else if (normalizedVariance < 1) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+36, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        } else {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+37, 1.0));
+            id = id + NUMBER_OF_VARIANCE;
+        }
+    }
+
+    private void numberOfPointsFeature(int numberOfPoints, OSMWay wayNode) {
+        //increase the id after the feature is found for the next portion of the vector.
+
+        if (numberOfPoints < 10) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 20) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+1, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 30) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+2, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 40) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+3, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 50) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+4, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 75) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+5, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 100) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+6, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 150) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+7, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 200) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+8, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 300) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+9, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 500) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+10, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else if (numberOfPoints < 1000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+11, 1.0));
+            id += NUMBER_OF_POINTS;
+        } else {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+12, 1.0));
+            id += NUMBER_OF_POINTS;
+        }
+    }
+
+    private void areaFeature(double area, OSMWay wayNode) {
+
+        if (area < 50) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 100) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+1, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 150) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+2, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 200) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+3, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 250) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+4, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 300) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+5, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 350) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+6, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 400) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+7, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 450) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+8, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 500) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+9, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 750) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+10, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 1000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+11, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 1250) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+12, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 1500) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+13, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 1750) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+14, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 2000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+15, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 2250) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+16, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 2500) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+17, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 2750) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+18, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 3000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+19, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 3500) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+20, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 4000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+21, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 5000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+22, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else if (area < 10000) {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+23, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        } else {
+            wayNode.getFeatureNodeList().add(new FeatureNode(id+24, 1.0));
+            id += NUMBER_OF_AREA_FEATURES;
+        }
+    }
+
+    private boolean geometryResemblesCircle(OSMWay way) {
+        Geometry wayGeometry = way.getGeometry();
+        boolean isCircle = false;
+        if (wayGeometry.getGeometryType().equals("Polygon") && wayGeometry.getNumPoints() >= 16) {
+
+            List<Geometry> points = way.getNodeGeometries();
+            Geometry firstPoint = points.get(0);
+            double radius = firstPoint.distance(wayGeometry.getCentroid());
+
+            // buffer around the distance of the first point to centroid
+            double radiusBufferSmaller = radius*0.6;
+            //the rest of the point-to-centroid distances will be compared with these
+            double radiusBufferGreater = radius*1.4;
+            isCircle = true;
+
+            for (Geometry point : points) {
+                double tempRadius = point.distance(wayGeometry.getCentroid());
+                boolean tempIsCircle = (radiusBufferSmaller <= tempRadius) && (tempRadius <= radiusBufferGreater);
+                isCircle = isCircle && tempIsCircle; //if any of the points give a false, the method will return false
+                //if (!isCircle) {break;}
+            }
+
+            double ratio = wayGeometry.getLength() / wayGeometry.getArea();
+            boolean tempIsCircle = ratio < 0.06; //arbitary value based on statistic measure of osm instances.
+            //The smaller this value, the closer this polygon resembles to a circle
+            isCircle = isCircle && tempIsCircle;
+        }
+        return isCircle;
+    }
+
+    private void setLastID(int lastID) {
+        this.id = lastID;
+    }
+
+    public int getLastID() {
+        return id + 1;
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/OSMClassification.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/OSMClassification.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/OSMClassification.java	(revision 32404)
@@ -0,0 +1,72 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.features;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+
+/**
+ * Defines the class/category of an OSM instance by its tags.
+ * @author imis-nkarag
+ */
+
+public class OSMClassification {
+
+    private int directClassID = 0;
+
+    public void calculateClasses(OSMWay wayNode, Map<String, String> mappings, Map<String, Integer> mappingsWithIDs,
+            Map<String, List<String>> indirectClasses, Map<String, Integer> indirectClassesIDs) {
+
+        Set<Integer> sortedIndirectIDs = new TreeSet<>();
+        Set<Integer> sortedDirectIDs = new TreeSet<>();
+        for (Map.Entry<String, String> wayTagKeyValue : wayNode.getTagKeyValue().entrySet()) {
+            //iteration for each tag (key-value) in the current way node
+
+            //concat key and value to use it later for checking
+            String key = wayTagKeyValue.getKey() + " " + wayTagKeyValue.getValue();
+
+            for (Map.Entry<String, String> tagMappedToClass : mappings.entrySet()) {
+                //entry of mappings is e.g "highway residential <-> ResidentialHighway"
+                //iteration to discover the wayNode class. This class's ID will be the start of the vector
+
+                if (key.equals(tagMappedToClass.getKey())) {
+                    String className = tagMappedToClass.getValue();
+                    directClassID = mappingsWithIDs.get(className);
+
+                    sortedDirectIDs.add(directClassID);
+
+                    //the direct class id is the last direct class that the instance is found to belong
+
+                    List<String> superClassesList = indirectClasses.get(className);
+
+                    if (superClassesList != null) { //check if the class has no superclasses
+
+                        for (String superClass: superClassesList) {
+
+                            Integer indirectID = indirectClassesIDs.get(superClass); //to save time here
+                            if (indirectID != null) { // there is a chance here that the ID is null,
+                                //cause the list of super Classes  might contain extra classes  with no ID
+                                //in the indirectClassesIDs map which is constructed from listHierarchyRootClasses method
+                                //at the OntologyParser.
+                                //so this condition check will remain for now
+
+                                if (!(sortedIndirectIDs.contains(indirectID))) {
+                                    sortedIndirectIDs.add(indirectID);
+                                    //wayNode.getIndexVector().put(indirectID, 1.0);
+                                }
+                                //the construction of the indirectClassVectorPortion has been moved below, sorted
+                                //indirectClassVectorPortion = indirectClassVectorPortion + indirectID + ":1 ";
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        wayNode.setClassIDs(sortedDirectIDs);
+        //System.out.println("OSMClassification, selected instance classes: " + sortedDirectIDs);
+        wayNode.setClassID(directClassID);
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/RelationFeatures.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/RelationFeatures.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/RelationFeatures.java	(revision 32404)
@@ -0,0 +1,61 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.features;
+
+import java.util.List;
+import java.util.Map;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+
+/**
+ * Constructs the relation features for liblinear.
+ *
+ * @author imis-nkarag
+ */
+
+public class RelationFeatures {
+    int id;
+
+    public RelationFeatures(int id) {
+        this.id = id;
+    }
+
+    public void createRelationFeatures(OSMWay wayNode, List<OSMRelation> relationList) {
+        id++; //this should be removed when using boolean intervals for mean and variance
+        boolean hasRelation = false;
+        for (OSMRelation relation : relationList) {
+            if (hasRelation) {
+                break;
+            }
+
+            if (relation.getMemberReferences().contains(wayNode.getID())) {
+                hasRelation = true;
+                Map<String, String> tags = relation.getTagKeyValue();
+
+                if (tags.containsKey("route")) {
+                    wayNode.getFeatureNodeList().add(new FeatureNode(id, 1.0));
+                } else if (tags.containsKey("multipolygon")) {
+                    wayNode.getFeatureNodeList().add(new FeatureNode(id+1, 1.0));
+                } else if (tags.containsKey("boundary")) {
+                    wayNode.getFeatureNodeList().add(new FeatureNode(id+2, 1.0));
+                } else if (tags.containsKey("restriction")) {
+                    wayNode.getFeatureNodeList().add(new FeatureNode(id+3, 1.0));
+                } else {
+                    //the instance may be a member of a relation, but the relation has no type or is incomplete.
+                    wayNode.getFeatureNodeList().add(new FeatureNode(id+4, 1.0));
+                }
+                id = id + 5;
+            }
+        }
+
+        if (!hasRelation) {
+            id = id + 5;
+        }
+    }
+
+    public int getLastID() {
+        return id;
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/TextualFeatures.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/TextualFeatures.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/features/TextualFeatures.java	(revision 32404)
@@ -0,0 +1,136 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.features;
+
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.lucene.analysis.el.GreekAnalyzer;
+import org.apache.lucene.analysis.en.EnglishAnalyzer;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.util.Version;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.plugins.osmrec.extractor.LanguageDetector;
+
+import com.cybozu.labs.langdetect.LangDetectException;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+
+/**
+ * Constructs the textual features from the given textual list.
+ *
+ * @author imis-nkarag
+ */
+
+public class TextualFeatures {
+
+    private int id;
+    private int numberOfFeatures;
+    private final List<String> textualList;
+    private static String language;
+    private final QueryParser greekParser;
+    private final QueryParser englishParser;
+    private final LanguageDetector languageDetector;
+
+    public TextualFeatures(int id, List<String> textualList, LanguageDetector languageDetector) {
+
+        this.id = id;
+        this.textualList = textualList;
+        this.languageDetector = languageDetector;
+        numberOfFeatures = textualList.size() + id;
+        GreekAnalyzer greekAnalyzer = new GreekAnalyzer(Version.LUCENE_36);
+        greekParser = new QueryParser(Version.LUCENE_36, "", greekAnalyzer);
+        EnglishAnalyzer englishAnalyzer = new EnglishAnalyzer(Version.LUCENE_36);
+        englishParser = new QueryParser(Version.LUCENE_36, "", englishAnalyzer);
+
+    }
+
+    public void createTextualFeatures(OSMWay wayNode) {
+        //namesList.indexOf(name) this index can be zero.
+        //In that case it conflicts the previous geometry id, so we increment id.
+
+        //idWords: populated with the ID that will be ginen as a feature, mapped with the word found.
+        //Chose to store the name for future use.
+        Map<Integer, String> idWords = new TreeMap<>();
+        Map<String, String> tags = wayNode.getTagKeyValue();
+        if (tags.keySet().contains("name")) {
+            String nameTag = tags.get("name"); //get the value of the name tag of the current node
+            String[] nameTagSplitList = nameTag.split("\\s");    //split the value to compare individually
+            //with the namesList
+            String lang = "";
+            try {
+                lang = detectLanguage(nameTag);
+            } catch (LangDetectException ex) {
+                Logger.getLogger(TextualFeatures.class.getName()).log(Level.SEVERE, null, ex);
+            }
+
+            for (String split : nameTagSplitList) {
+                try {
+                    //TOGGLE
+                    split = split.replaceAll("[-+.^:,?;'{}\"!()\\[\\]]", "");
+                    if (lang.equals("el")) {
+                        split = stemGreek(split);
+                    } else {
+                        split = stemEnglish(split);
+                    }
+
+                    if (textualList.contains(split)) {
+                        int currentID = textualList.indexOf(split) + id;
+                        idWords.put(currentID, split);
+                    }
+                } catch (ParseException ex) {
+                    Logger.getLogger(TextualFeatures.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+
+            for (Integer wordID : idWords.keySet()) {
+                wayNode.getFeatureNodeList().add(new FeatureNode(wordID, 1.0));
+                //System.out.println(wordID);
+            }
+            //System.out.println("until textual " + wayNode.getFeatureNodeList());
+        }
+    }
+
+    public int getLastID() {
+        return numberOfFeatures;
+    }
+
+    private String detectLanguage(String nameTag) throws LangDetectException {
+        //detect language
+
+        if (!nameTag.isEmpty()) {
+            language = languageDetector.detect(nameTag);
+            return language;
+        } else {
+            return "no_lang";
+        }
+    }
+
+    private String stemGreek(String word) throws ParseException {
+        String stemmedWord;
+
+        if (!word.isEmpty()) {
+            stemmedWord = greekParser.parse(word).toString();
+        } else {
+            return word;
+        }
+
+        return stemmedWord;
+    }
+
+    private String stemEnglish(String word) throws ParseException {
+
+        String stemmedWord;
+
+        if (!word.isEmpty()) {
+            stemmedWord = englishParser.parse(word).toString();
+        } else {
+            return word;
+        }
+
+        return stemmedWord;
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/Mapper.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/Mapper.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/Mapper.java	(revision 32404)
@@ -0,0 +1,84 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.parsers;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Scanner;
+
+/**
+ * MappingsParser takes the Map file which contains the LGD mappings and extracts information
+ * about the OSM tags and the ontology classes
+ * This info is used in the vector construction.
+ *
+ * @author imis-nkarag
+ */
+
+public class Mapper {
+    //private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(Mapper.class);
+    private final HashMap<String, String> mappings;
+    private final HashMap<String, Integer> mappingsWithIDs;
+    private final Map<Integer, String> idsWithMappings;
+
+    public Mapper() {
+
+        mappings = new LinkedHashMap<>();
+        mappingsWithIDs = new HashMap<>();
+        idsWithMappings = new HashMap<>();
+
+    }
+
+    public void parseFile(InputStream inps) throws FileNotFoundException {
+
+        Scanner input = new Scanner(inps); //the Map file contains lines of the mappings separated with the symbol "|"
+        //e.g. highway motorway | Motorway
+        //the key will be the string "highway motorway" and the value "Motorway"
+        while (input.hasNext()) {
+
+            String nextLine = input.nextLine();
+            String[] splitContent = nextLine.split("\\|", 2);   //split current line in two parts,
+            //separated by the "|" symbol
+            String key = splitContent[0];                      //this key will be mapped to a class
+            String value = splitContent[1];                    //this value is the mapped class
+            key = key.trim();
+            value = value.trim();
+            mappings.put(key, value);
+        }
+        constructMappingsWithIDs();
+        constructIDsWithMappings();
+        System.out.println("Mappings file parsed successfully!");
+        //LOG.info("Mappings file parsed successfully!");
+    }
+
+    private void constructMappingsWithIDs() {
+        Integer i = 1; //starting ID is 1: SVM multiclass does not accept 0 as a class ID
+        for (String ontologyClass : mappings.values()) {
+            mappingsWithIDs.put(ontologyClass, i);
+            i++;
+        }
+    }
+
+    public Map<String, Integer> getMappingsWithIDs() {
+        return Collections.unmodifiableMap(mappingsWithIDs);
+    }
+
+    public Map<String, String> getMappings() {
+        return Collections.unmodifiableMap(mappings);
+    }
+
+    private void constructIDsWithMappings() {
+        int i = 1; //starting ID is 1: SVM multiclass does not accept 0 as a class ID
+
+        for (String ontologyClass : mappings.values()) {
+            idsWithMappings.put(i, ontologyClass);
+            i++;
+        }
+    }
+
+    public Map<Integer, String> getIDsWithMappings() {
+        return Collections.unmodifiableMap(idsWithMappings);
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/OSMParser.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/OSMParser.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/OSMParser.java	(revision 32404)
@@ -0,0 +1,223 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.parsers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.geotools.geometry.jts.JTS;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.DefaultGeocentricCRS;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMNode;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.tools.Utils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+
+/**
+ * Parses OSM xml file and constructs additional nodes of the OSM map into appropriate objects with attributes.
+ *
+ * @author imis-nkarag
+ */
+public class OSMParser extends DefaultHandler {
+
+    //private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OSMParser.class);
+
+    //change from wgs84 to cartesian for later processing of the geometry
+    private static final CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
+    private static final CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
+    private final GeometryFactory geometryFactory = new GeometryFactory();
+    private static MathTransform transform = null;
+    private final List<OSMNode> nodeList; //will be populated with nodes
+    private final List<OSMRelation> relationList;
+    private final Map<String, OSMNode> nodesWithIDs; //map containing IDs as Strings and the corresponding OSMNode objects
+    private final List<OSMWay> wayList;  //populated with ways of the OSM file
+    private final String osmXmlFileName;
+    private OSMNode nodeTmp; //variable to hold the node object
+    private OSMWay wayTmp;   //variable to hold the way object
+    private OSMRelation relationTmp;
+    private boolean inWay = false; //when parser is in a way node becomes true in order to track the parser position
+    private boolean inNode = false; //becomes true when the parser is in a simple node
+    private boolean inRelation = false; //becomes true when the parser is in a relarion node
+
+    public OSMParser(String osmXmlFileName) {
+        this.osmXmlFileName = osmXmlFileName;
+        nodeList = new ArrayList<>();
+        wayList = new ArrayList<>();
+        relationList = new ArrayList<>();
+        nodesWithIDs = new HashMap<>();
+        try {
+            transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+        } catch (FactoryException ex) {
+            Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void parseDocument() {
+        try {
+            Utils.newSafeSAXParser().parse(osmXmlFileName, this);
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            Main.error(e);
+        }
+    }
+
+    @Override
+    public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {
+
+        // if current element is an OSMNode , create new node and populate with the appropriate values
+        if (elementName.equalsIgnoreCase("node")) {
+            nodeTmp = new OSMNode();
+            nodeTmp.setID(attributes.getValue("id"));
+            nodeTmp.setUser(attributes.getValue("user"));
+            //parse geometry
+            double longitude = Double.parseDouble(attributes.getValue("lon"));
+            double latitude = Double.parseDouble(attributes.getValue("lat"));
+
+            Coordinate targetGeometry = null;
+            Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
+            try {
+                targetGeometry = JTS.transform(sourceCoordinate, null, transform);
+            } catch (MismatchedDimensionException | TransformException ex) {
+                Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
+            }
+
+            //create geometry object
+            Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
+            nodeTmp.setGeometry(geom);
+            inNode = true;
+            inWay = false;
+            inRelation = false;
+
+        } else if (elementName.equalsIgnoreCase("way")) {
+            wayTmp = new OSMWay();
+            wayTmp.setID(attributes.getValue("id"));
+
+            if (attributes.getValue("user") != null) {
+                wayTmp.setUser(attributes.getValue("user"));
+            } else {
+                wayTmp.setUser("undefined");
+            }
+
+            inWay = true;
+            inNode = false;
+            inRelation = false;
+        } else if (elementName.equalsIgnoreCase("relation")) {
+            relationTmp = new OSMRelation();
+            relationTmp.setID(attributes.getValue("id"));
+            inRelation = true;
+            inWay = false;
+            inNode = false;
+        } else if (elementName.equalsIgnoreCase("nd")) {
+            wayTmp.addNodeReference(attributes.getValue("ref"));
+
+        } else if (elementName.equalsIgnoreCase("tag")) {
+
+            if (inNode) {
+                //if the path is in an OSMNode set tagKey and value to the corresponding node
+                nodeTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+            } else if (inWay) {
+                //else if the path is in an OSM way set tagKey and value to the corresponding way
+                wayTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+            } else if (inRelation) {
+                //set the key-value pairs of relation tags
+                relationTmp.setTagKeyValue(attributes.getValue("k"), attributes.getValue("v"));
+            }
+        } else if (elementName.equalsIgnoreCase("member")) {
+            relationTmp.addMemberReference(attributes.getValue("ref"));
+        }
+    }
+
+    @Override
+    public void endElement(String s, String s1, String element) throws SAXException {
+        // if end of node element, add to appropriate list
+        if (element.equalsIgnoreCase("node")) {
+            nodeList.add(nodeTmp);
+            nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
+        }
+
+        if (element.equalsIgnoreCase("way")) {
+
+            //construct the Way geometry from each node of the node references
+            List<String> references = wayTmp.getNodeReferences();
+
+            for (String entry: references) {
+                Geometry geometry = nodesWithIDs.get(entry).getGeometry(); //get the geometry of the node with ID=entry
+                wayTmp.addNodeGeometry(geometry); //add the node geometry in this way
+
+            }
+            Geometry geom = geometryFactory.buildGeometry(wayTmp.getNodeGeometries());
+
+            if ((wayTmp.getNumberOfNodes() > 3) &&
+                    wayTmp.getNodeGeometries().get(0).equals(wayTmp.getNodeGeometries()
+                            .get(wayTmp.getNodeGeometries().size()-1))) {
+                //checks if the beginning and ending node are the same and the number of nodes are more than 3.
+                //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
+
+                if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))) {
+                    //this is not a barrier nor a road, so construct a polygon geometry
+
+                    LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+                    Polygon poly = new Polygon(linear, null, geometryFactory);
+                    wayTmp.setGeometry(poly);
+                } else {
+                    //it is either a barrier or a road, so construct a linear ring geometry
+                    LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+                    wayTmp.setGeometry(linear);
+                }
+            } else if (wayTmp.getNumberOfNodes() > 1) {
+                //it is an open geometry with more than one nodes, make it linestring
+
+                LineString lineString = geometryFactory.createLineString(geom.getCoordinates());
+                wayTmp.setGeometry(lineString);
+            } else { //we assume all the rest geometries are points
+                //some ways happen to have only one point. Construct a  Point.
+                Point point = geometryFactory.createPoint(geom.getCoordinate());
+                wayTmp.setGeometry(point);
+            }
+            wayList.add(wayTmp);
+        }
+
+        if (element.equalsIgnoreCase("relation")) {
+            relationList.add(relationTmp);
+        }
+    }
+
+    public List<OSMNode> getNodeList() {
+        return nodeList;
+    }
+
+    public List<OSMWay> getWayList() {
+        return wayList;
+    }
+
+    public List<OSMRelation> getRelationList() {
+        return relationList;
+    }
+
+    public Map<String, OSMNode> getNodesWithIDs() {
+        return nodesWithIDs;
+    }
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/Ontology.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/Ontology.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/Ontology.java	(revision 32404)
@@ -0,0 +1,129 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.parsers;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Loads the ontology based on the owl.xml file.
+ * @author imis-nkarag
+ */
+
+import com.hp.hpl.jena.ontology.OntClass;
+import com.hp.hpl.jena.ontology.OntModel;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+
+/**
+ * Parses the ontology from the owl.xml file
+ * The owl file contains information about the ontology and hierarchy of the classes
+ * Provides methods for retrieving information about the ontology.
+ *
+ *
+ * @author imis-nkarag
+ */
+
+public class Ontology {
+    //private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(Ontology.class);
+
+    private OntModel ontologyModel;
+    private List<OntClass> listHierarchy;
+    private static final int additiveID = 1373;
+    private Map<String, List<String>> indirectClasses;
+    private final Map<String, Integer> indirectClassesIDs;
+    private final InputStream owlFile;
+
+    public Ontology(InputStream owlFile) {
+
+        this.owlFile = owlFile;
+        indirectClassesIDs = new HashMap<>();
+        indirectClasses = new HashMap<>();
+        listHierarchy = new ArrayList<>();
+    }
+
+    public void parseOntology() {
+        try {
+
+            //create the ontology model using the base
+            ontologyModel = ModelFactory.createOntologyModel();
+
+            org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.ERROR);
+            ontologyModel.read(owlFile, null);    //Hide RDFDefaultErrorHandler from terminal to keep clear output.
+            org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.INFO);
+
+            listHierarchy = ontologyModel.listHierarchyRootClasses().toList();
+            setListHierarchy(listHierarchy);
+
+            ExtendedIterator<OntClass> classes = ontologyModel.listClasses();
+            while (classes.hasNext()) {
+                String className;
+                OntClass obj = classes.next();
+
+                //compare localname with class name from map and call getSuperclass
+                if (obj.hasSubClass()) {
+
+                    for (Iterator<OntClass> i = obj.listSubClasses(true); i.hasNext();) {
+                        OntClass currentClass = i.next();
+
+                        List<OntClass> superClasses = currentClass.listSuperClasses().toList();
+                        List<String> superClassesStrings = new ArrayList<>();
+
+                        for (OntClass superClass : superClasses) {
+                            className = superClass.toString().replace("http://linkedgeodata.org/ontology/", "");
+                            superClassesStrings.add(className);
+                        }
+                        indirectClasses.put(currentClass.getLocalName(), superClassesStrings);
+                    }
+                }
+            }
+            createIndirectClassesWithIDs();
+            setIndirectClasses(indirectClasses);
+            setOntologyModel(ontologyModel);
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+        }
+    }
+
+    private void createIndirectClassesWithIDs() {
+        for (int i = 0; i < listHierarchy.size(); i++) {
+
+            String key = listHierarchy.get(i).toString().replace("http://linkedgeodata.org/ontology/", "");
+            //we add 1 to the ID because we want IDs beginning from 1. listHierarchy has index beginning from 0
+            indirectClassesIDs.put(key, i + additiveID); //the IDs start from 1373 to avoid duplicate IDs at the vectorConstructor
+        }
+    }
+
+    private void setOntologyModel(OntModel ontologyModel) {
+        this.ontologyModel = ontologyModel;
+    }
+
+    private void setIndirectClasses(Map<String, List<String>> indirectClasses) {
+        this.indirectClasses = indirectClasses;
+
+    }
+
+    private void setListHierarchy(List<OntClass> listHierarchy) {
+        this.listHierarchy = listHierarchy;
+    }
+
+    public OntModel getOntologyModel() {
+        return this.ontologyModel;
+    }
+
+    public Map<String, List<String>> getIndirectClasses() {
+        return this.indirectClasses;
+    }
+
+    public List<OntClass> getListHierarchy() {
+        return this.listHierarchy;
+    }
+
+    public Map<String, Integer> getIndirectClassesIDs() {
+        return this.indirectClassesIDs;
+    }
+
+}
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/TextualStatistics.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/TextualStatistics.java	(revision 32404)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/parsers/TextualStatistics.java	(revision 32404)
@@ -0,0 +1,37 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.osmrec.parsers;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * Provides functionality for parsing the names file
+ * This file contains name occurrences obtained from statistical measures on OSM data.
+ *
+ * @author imis-nkarag
+ */
+
+public class TextualStatistics {
+
+    //private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(TextualStatistics.class);
+    private List<String> textualList;
+
+    public void parseTextualList(InputStream textualFileStream) {
+        textualList = new ArrayList<>();
+
+        Scanner input = new Scanner(textualFileStream);
+        while (input.hasNext()) {
+            String nextLine = input.nextLine();
+            textualList.add(nextLine);
+        }
+        //LOG.info("Name occurences parsed successfully!");
+    }
+
+    public List<String> getTextualList() {
+        return Collections.unmodifiableList(textualList);
+    }
+}
+
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/HistoryParser.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/HistoryParser.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/HistoryParser.java	(revision 32404)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec.personalization;
 
@@ -25,6 +26,6 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.OsmApi;
-import org.openstreetmap.josm.plugins.container.OSMNode;
-import org.openstreetmap.josm.plugins.container.OSMWay;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMNode;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
 import org.openstreetmap.josm.tools.HttpClient;
 import org.openstreetmap.josm.tools.Utils;
@@ -43,5 +44,5 @@
 /**
  * Parses the history of an OSM user's changesets using OSM API.
- * 
+ *
  * @author imis-nkarag
  */
@@ -52,5 +53,5 @@
     private static final GeometryFactory geometryFactory = new GeometryFactory();
     private MathTransform transform;
-    private OSMNode nodeTmp;  
+    private OSMNode nodeTmp;
 
     private final List<OSMNode> nodeList;
@@ -64,5 +65,5 @@
      * @param username user name
      */
-    public HistoryParser(String username) {   
+    public HistoryParser(String username) {
         this.username = username;
         transform = null;
@@ -78,7 +79,7 @@
 
     public void historyParse(String timeInterval) {
-        
+
         HashSet<String> changesetIDsList = new HashSet<>();
-        
+
         try {
             String osmUrl = OSM_API + "changesets?display_name=" + username + "&time=" + timeInterval;
@@ -88,12 +89,12 @@
             Main.debug("changeset size "+ nodes.getLength());
             for (int i = 0; i < nodes.getLength(); i++) {
-            	Main.debug("attributes of " + i + "th changeset"); 
+                Main.debug("attributes of " + i + "th changeset");
                 String id = nodes.item(i).getAttributes().item(3).toString();
                 Main.debug("id:" + nodes.item(i).getAttributes().item(3));
                 id = stripQuotes(id);
-                changesetIDsList.add(id);                
-            }
-
-            for(String id : changesetIDsList){
+                changesetIDsList.add(id);
+            }
+
+            for (String id : changesetIDsList) {
                 getChangesetByID(id);
             }
@@ -108,9 +109,9 @@
             InputStream xml = HttpClient.create(new URL(changesetByIDURL)).connect().getContent();
             Node osmChange = Utils.parseSafeDOM(xml).getFirstChild();
-  
+
             //get all nodes first, in order to be able to call all nodes references and create the geometries
-            for(int i = 0; i < osmChange.getChildNodes().getLength(); i++){
+            for (int i = 0; i < osmChange.getChildNodes().getLength(); i++) {
                 String changeType = osmChange.getChildNodes().item(i).getNodeName();
-                if(!(changeType.equals("#text") || changeType.equals("delete"))){
+                if (!(changeType.equals("#text") || changeType.equals("delete"))) {
 
                     NodeList changeChilds = osmChange.getChildNodes().item(i).getChildNodes();
@@ -118,6 +119,6 @@
                     Node osmObject = changeChilds.item(1);
 
-                    if(osmObject.getNodeName().equals("node")){
-                        //node data 
+                    if (osmObject.getNodeName().equals("node")) {
+                        //node data
                         nodeTmp = new OSMNode();
                         nodeTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());
@@ -128,5 +129,5 @@
                         Coordinate targetGeometry = null;
                         Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
-                        try {    
+                        try {
                             targetGeometry = JTS.transform(sourceCoordinate, null, transform);
                         } catch (MismatchedDimensionException | TransformException ex) {
@@ -136,91 +137,86 @@
                         //create geometry object
                         Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-                        nodeTmp.setGeometry(geom);                    
+                        nodeTmp.setGeometry(geom);
 
                         nodeList.add(nodeTmp);
                         nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
-                    }                        
+                    }
                 }
             }
-        
-            for(int i = 0; i < osmChange.getChildNodes().getLength(); i++){
+
+            for (int i = 0; i < osmChange.getChildNodes().getLength(); i++) {
                 String changeType = osmChange.getChildNodes().item(i).getNodeName();
-                if(!(changeType.equals("#text") || changeType.equals("delete"))){
+                if (!(changeType.equals("#text") || changeType.equals("delete"))) {
                     NodeList changeChilds = osmChange.getChildNodes().item(i).getChildNodes();
 
                     Node osmObject = changeChilds.item(1);
-                    if(osmObject.getNodeName().equals("way")){
+                    if (osmObject.getNodeName().equals("way")) {
 
                         //get way data
                         wayTmp = new OSMWay();
-                        wayTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());  
-                        //osmObject.getChildNodes() <-extract tags, then set tags to osm object
+                        wayTmp.setID(osmObject.getAttributes().getNamedItem("id").getNodeValue());
+                        // extract tags, then set tags to osm object
                         Main.debug("\n\nWAY: " + wayTmp.getID());
-                        for(int l=0; l<osmObject.getChildNodes().getLength(); l++){
+                        for (int l = 0; l < osmObject.getChildNodes().getLength(); l++) {
                             String wayChild = osmObject.getChildNodes().item(l).getNodeName();
 
-                            if(wayChild.equals("tag")){
+                            if (wayChild.equals("tag")) {
                                 String key = osmObject.getChildNodes().item(l).getAttributes().getNamedItem("k").getNodeValue();
                                 String value = osmObject.getChildNodes().item(l).getAttributes().getNamedItem("v").getNodeValue();
                                 System.out.println("key: " + key + " value: " + value);
-                                wayTmp.setTagKeyValue(key,value);
-                            }
-                            else if(wayChild.equals("nd")){
+                                wayTmp.setTagKeyValue(key, value);
+                            } else if (wayChild.equals("nd")) {
                                 wayTmp.addNodeReference(osmObject.getChildNodes().item(l).getAttributes().getNamedItem("ref").getNodeValue());
                             }
                         }
-                        
+
                         //construct the Way geometry from each node of the node references
                         List<String> references = wayTmp.getNodeReferences();
 
                         for (String entry: references) {
-                           if(nodesWithIDs.containsKey(entry)){ 
+                            if (nodesWithIDs.containsKey(entry)) {
                                 Geometry geometry = nodesWithIDs.get(entry).getGeometry(); //get the geometry of the node with ID=entry
                                 wayTmp.addNodeGeometry(geometry); //add the node geometry in this way
-                           }
-                           else{
-                               Main.debug("nodes with ids, no entry " + entry);
-                               getNodeFromAPI(entry);
-                           }
+                            } else {
+                                Main.debug("nodes with ids, no entry " + entry);
+                                getNodeFromAPI(entry);
+                            }
                         }
 
                         Geometry geom = geometryFactory.buildGeometry(wayTmp.getNodeGeometries());
-                        if((wayTmp.getNodeGeometries().size()>3) && 
+                        if ((wayTmp.getNodeGeometries().size() > 3) &&
                                 wayTmp.getNodeGeometries().get(0).equals(wayTmp.getNodeGeometries()
-                                                                                    .get(wayTmp.getNodeGeometries().size()-1))){
-                        //checks if the beginning and ending node are the same and the number of nodes are more than 3. 
-                        //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
-
-                            if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))){
-                            //this is not a barrier nor a road, so construct a polygon geometry
-
-                            LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
-                            Polygon poly = new Polygon(linear, null, geometryFactory);
-                            wayTmp.setGeometry(poly);               
+                                        .get(wayTmp.getNodeGeometries().size()-1))) {
+                            //checks if the beginning and ending node are the same and the number of nodes are more than 3.
+                            //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
+
+                            if (!((wayTmp.getTagKeyValue().containsKey("barrier")) || wayTmp.getTagKeyValue().containsKey("highway"))) {
+                                //this is not a barrier nor a road, so construct a polygon geometry
+
+                                LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+                                Polygon poly = new Polygon(linear, null, geometryFactory);
+                                wayTmp.setGeometry(poly);
+                            } else {
+                                //it is either a barrier or a road, so construct a linear ring geometry
+                                LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
+                                wayTmp.setGeometry(linear);
                             }
-                            else {
-                            //it is either a barrier or a road, so construct a linear ring geometry 
-                                LinearRing linear = geometryFactory.createLinearRing(geom.getCoordinates());
-                                wayTmp.setGeometry(linear);  
-                            }
-                        }
-                        else if (wayTmp.getNodeGeometries().size() > 1){
-                        //it is an open geometry with more than one nodes, make it linestring 
+                        } else if (wayTmp.getNodeGeometries().size() > 1) {
+                            //it is an open geometry with more than one nodes, make it linestring
 
                             LineString lineString = geometryFactory.createLineString(geom.getCoordinates());
-                            wayTmp.setGeometry(lineString);               
-                        }
-                        else{ //we assume all the rest geometries are points
-                        //some ways happen to have only one point. Construct a  Point.
+                            wayTmp.setGeometry(lineString);
+                        } else { //we assume all the rest geometries are points
+                            //some ways happen to have only one point. Construct a  Point.
                             Point point = geometryFactory.createPoint(geom.getCoordinate());
                             wayTmp.setGeometry(point);
                         }
-                        wayList.add(wayTmp);    
-                    }   
+                        wayList.add(wayTmp);
+                    }
                 }
-            }                  
+            }
         } catch (IOException | ParserConfigurationException | SAXException ex) {
             Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
-        }   
+        }
     }
 
@@ -236,5 +232,5 @@
             String lat = nodes.item(0).getAttributes().getNamedItem("lat").getNodeValue();
             String lon = nodes.item(0).getAttributes().getNamedItem("lon").getNodeValue();
-            
+
             nodeTmp = new OSMNode();
             nodeTmp.setID(nodeID);
@@ -245,5 +241,5 @@
             Coordinate targetGeometry = null;
             Coordinate sourceCoordinate = new Coordinate(longitude, latitude);
-            try {    
+            try {
                 targetGeometry = JTS.transform(sourceCoordinate, null, transform);
             } catch (MismatchedDimensionException | TransformException ex) {
@@ -253,15 +249,15 @@
             //create geometry object
             Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
-            nodeTmp.setGeometry(geom);                    
+            nodeTmp.setGeometry(geom);
 
             nodeList.add(nodeTmp);
             nodesWithIDs.put(nodeTmp.getID(), nodeTmp);
-            
+
         } catch (IOException | ParserConfigurationException | SAXException ex) {
             Logger.getLogger(HistoryParser.class.getName()).log(Level.SEVERE, null, ex);
         }
     }
-    
-    public List<OSMWay> getWayList(){
+
+    public List<OSMWay> getWayList() {
         return wayList;
     }
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/TrainByUser.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/TrainByUser.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/TrainByUser.java	(revision 32404)
@@ -1,11 +1,7 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec.personalization;
 
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import de.bwaldvogel.liblinear.FeatureNode;
-import de.bwaldvogel.liblinear.Linear;
-import de.bwaldvogel.liblinear.Model;
-import de.bwaldvogel.liblinear.Parameter;
-import de.bwaldvogel.liblinear.Problem;
-import de.bwaldvogel.liblinear.SolverType;
+
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -29,36 +25,43 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
+
 import javax.swing.SwingWorker;
-import org.openstreetmap.josm.plugins.container.OSMRelation;
-import org.openstreetmap.josm.plugins.container.OSMWay;
-import org.openstreetmap.josm.plugins.extractor.Analyzer;
-import org.openstreetmap.josm.plugins.extractor.LanguageDetector;
-import org.openstreetmap.josm.plugins.features.ClassFeatures;
-import org.openstreetmap.josm.plugins.features.GeometryFeatures;
-import org.openstreetmap.josm.plugins.features.OSMClassification;
-import org.openstreetmap.josm.plugins.features.RelationFeatures;
-import org.openstreetmap.josm.plugins.features.TextualFeatures;
-import org.openstreetmap.josm.plugins.parsers.Mapper;
-import org.openstreetmap.josm.plugins.parsers.Ontology;
-import org.openstreetmap.josm.plugins.parsers.TextualStatistics;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMRelation;
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.plugins.osmrec.extractor.Analyzer;
+import org.openstreetmap.josm.plugins.osmrec.extractor.LanguageDetector;
+import org.openstreetmap.josm.plugins.osmrec.features.ClassFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.GeometryFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.OSMClassification;
+import org.openstreetmap.josm.plugins.osmrec.features.RelationFeatures;
+import org.openstreetmap.josm.plugins.osmrec.features.TextualFeatures;
+import org.openstreetmap.josm.plugins.osmrec.parsers.Mapper;
+import org.openstreetmap.josm.plugins.osmrec.parsers.Ontology;
+import org.openstreetmap.josm.plugins.osmrec.parsers.TextualStatistics;
+
+import de.bwaldvogel.liblinear.FeatureNode;
+import de.bwaldvogel.liblinear.Linear;
+import de.bwaldvogel.liblinear.Model;
+import de.bwaldvogel.liblinear.Parameter;
+import de.bwaldvogel.liblinear.Problem;
+import de.bwaldvogel.liblinear.SolverType;
 
 /**
  *  Trains a model by the history of given user.
- * 
+ *
  *  @author imis-nkarag
  */
-
-public class TrainByUser extends SwingWorker<Void, Void> implements ActionListener{
-    
+public class TrainByUser extends SwingWorker<Void, Void> implements ActionListener {
+
     private final String inputFilePath;
-    private static Map<String,String> mappings;
-    private static Map<String,Integer> mapperWithIDs;
+    private static Map<String, String> mappings;
+    private static Map<String, Integer> mapperWithIDs;
     private static List<OSMWay> wayList;
     private static List<OSMRelation> relationList;
-    
+
     private static Map<String, List<String>> indirectClasses;
     private static Map<String, Integer> indirectClassesWithIDs;
-    //private static List<OntClass> listHierarchy;
-    private static List<String> namesList;       
+    private static List<String> namesList;
     private int numberOfTrainingInstances;
     private final String modelDirectoryPath;
@@ -71,5 +74,4 @@
     private static double foldScore10 = 0;
     private static double bestScore = 0;
-    //int trainProgress = 0;
     private final boolean validateFlag;
     private final double cParameterFromUser;
@@ -78,5 +80,5 @@
     private final int frequency;
     private final boolean topKIsSelected;
-    private String textualListFilePath;    
+    private String textualListFilePath;
     private static final boolean USE_CLASS_FEATURES = false;
     private static final boolean USE_RELATION_FEATURES = false;
@@ -86,10 +88,9 @@
     private final String username;
     private final String inputFileName;
-        
-    public TrainByUser(String inputFilePath, String username, boolean validateFlag, double cParameterFromUser, 
+
+    public TrainByUser(String inputFilePath, String username, boolean validateFlag, double cParameterFromUser,
             int topK, int frequency, boolean topKIsSelected, LanguageDetector languageDetector, List<OSMWay> wayList) {
-        super();
-        TrainByUser.languageDetector = languageDetector;        
-        this.inputFilePath = inputFilePath; 
+        TrainByUser.languageDetector = languageDetector;
+        this.inputFilePath = inputFilePath;
         this.username = username;
         this.validateFlag = validateFlag;
@@ -99,71 +100,58 @@
         this.topKIsSelected = topKIsSelected;
         System.out.println("find parent directory, create osmrec dir for models: " + new File(inputFilePath).getParentFile());
-        
-        if(System.getProperty("os.name").contains("ux")){
+
+        if (System.getProperty("os.name").contains("ux")) {
             inputFileName = inputFilePath.substring(inputFilePath.lastIndexOf("/"));
-        }
-        else{
+        } else {
             inputFileName = inputFilePath.substring(inputFilePath.lastIndexOf("\\"));
         }
-        
+
         modelDirectoryPath = new File(inputFilePath).getParentFile() + "/OSMRec_models";
-        //textualDirectoryPath = new File(inputFilePath).getParentFile() + "/OSMRec_models/textualList.txt";
-        
+
         modelDirectory = new File(modelDirectoryPath);
-        
+
         if (!modelDirectory.exists()) {
             modelDirectory.mkdir();
             System.out.println("model directory created!");
-        }
-        else {
+        } else {
             System.out.println("directory already exists!");
-        }   
+        }
         TrainByUser.wayList = wayList;
     }
-        
+
     @Override
-    public Void doInBackground() throws Exception {         
+    public Void doInBackground() throws Exception {
         extractTextualList();
         parseFiles();
-        if(validateFlag){   
+        if (validateFlag) {
             firePropertyChange("progress", getProgress(), 5);
-            //setProgress(5);
             validateLoop();
             firePropertyChange("progress", getProgress(), 40);
-            //setProgress(40);
             System.out.println("Training model with the best c: " + bestConfParam);
             clearDataset();
             trainModel(bestConfParam);
             firePropertyChange("progress", getProgress(), 60);
-            //setProgress(80);
             clearDataset();
             trainModelWithClasses(bestConfParam);
             firePropertyChange("progress", getProgress(), 100);
             setProgress(100);
-        }
-        else{
-
-            //firePropertyChange("progress", getProgress(), 5);
-            //setProgress(5);
+        } else {
             clearDataset();
             firePropertyChange("progress", getProgress(), 10);
-            //setProgress(10);
             trainModel(cParameterFromUser);
-            //setProgress(60);   
             firePropertyChange("progress", getProgress(), 60);
             clearDataset();
             firePropertyChange("progress", getProgress(), 65);
-            //setProgress(65);
-            trainModelWithClasses(cParameterFromUser);          
-            
+            trainModelWithClasses(cParameterFromUser);
+
             firePropertyChange("progress", getProgress(), 100);
             setProgress(100);
             System.out.println("done.");
         }
-        System.out.println("Train by user process complete.");    
+        System.out.println("Train by user process complete.");
         return null;
     }
-    
-    private void extractTextualList(){
+
+    private void extractTextualList() {
         System.out.println("Running analysis..");
         //provide top-K
@@ -171,5 +159,5 @@
         //Keep terms with frequency higher than N
         //Use the remaining terms as training features
-        
+
         Analyzer anal = new Analyzer(inputFilePath, languageDetector);
         anal.runAnalysis();
@@ -177,20 +165,19 @@
         textualListFilePath = modelDirectory.getAbsolutePath()+"/textualList.txt";
         File textualFile = new File(textualListFilePath); //decide path of models
-        if(textualFile.exists()){
+        if (textualFile.exists()) {
             textualFile.delete();
-        }        
+        }
         try {
             textualFile.createNewFile();
         } catch (IOException ex) {
             Logger.getLogger(TrainByUser.class.getName()).log(Level.SEVERE, null, ex);
-        }           
-        
+        }
+
         //writeTextualListToFile(textualFilePath, anal.getTopKMostFrequent(15));
         List<Map.Entry<String, Integer>> textualList;
-        if(topKIsSelected){
+        if (topKIsSelected) {
             textualList = anal.getTopKMostFrequent(topK);
             System.out.println(textualList);
-        }
-        else{
+        } else {
             textualList = anal.getWithFrequency(frequency);
             System.out.println(textualList);
@@ -200,23 +187,19 @@
         System.out.println("textual list saved at location:\n" + textualListFilePath);
         //write list to file and let parser do the loading from the names file
-        
+
         //method read default list
         //method extract textual list - > the list will be already in memory, so the names parser doesn t have to be called
-        if(USE_CLASS_FEATURES){
+        if (USE_CLASS_FEATURES) {
             numberOfFeatures = 1422 + 105 + textualList.size();
-        }
-        else{          
+        } else {
             numberOfFeatures = 105 + textualList.size();
         }
-    }  
-    
+    }
+
     private void parseFiles() {
-       // File tagsToClassesFile = new File(tagsToClassesFilePath);        
-
-        //osmRecProperties.load(Train.class.getResourceAsStream("/resources/properties/osmRec.properties"));
         InputStream tagsToClassesMapping = TrainByUser.class.getResourceAsStream("/resources/files/Map");
 
         Mapper mapper = new Mapper();
-        try {   
+        try {
             mapper.parseFile(tagsToClassesMapping);
         } catch (FileNotFoundException ex) {
@@ -224,9 +207,8 @@
         }
         mappings = mapper.getMappings();
-        mapperWithIDs = mapper.getMappingsWithIDs(); 
-        //System.out.println("success. mappings empty? " + mappings.isEmpty());
-        
+        mapperWithIDs = mapper.getMappingsWithIDs();
+
         InputStream ontologyStream = TrainByUser.class.getResourceAsStream("/resources/files/owl.xml");
-        Ontology ontology = new Ontology(ontologyStream);            
+        Ontology ontology = new Ontology(ontologyStream);
 
         ontology.parseOntology();
@@ -234,8 +216,7 @@
         indirectClasses = ontology.getIndirectClasses();
         indirectClassesWithIDs = ontology.getIndirectClassesIDs();
-        //listHierarchy = ontology.getListHierarchy();        
-
-        //InputStream textualFileStream = TrainWorker.class.getResourceAsStream("/resources/files/names");     
-        InputStream textualFileStream = null;  
+
+        //InputStream textualFileStream = TrainWorker.class.getResourceAsStream("/resources/files/names");
+        InputStream textualFileStream = null;
         try {
             textualFileStream = new FileInputStream(new File(textualListFilePath));
@@ -243,29 +224,25 @@
             Logger.getLogger(TrainByUser.class.getName()).log(Level.SEVERE, null, ex);
         }
-        
-        readTextualFromDefaultList(textualFileStream);      
-        
+
+        readTextualFromDefaultList(textualFileStream);
+
         //osmParser.parseDocument();
         //relationList = osmParser.getRelationList();
         //wayList = osmParser.getWayList();
         numberOfTrainingInstances = wayList.size();
-        System.out.println("number of instances: " + numberOfTrainingInstances);   
-        System.out.println("end of parsing files."); 
-        if(numberOfTrainingInstances == 0){
-            System.out.println("This user has not edited the loaded area. Cannot train a model!");            
-        }        
-    }
-
-    private void validateLoop(){
-//        Double[] confParams = new Double[] {Math.pow(2, -10), Math.pow(2, -5),Math.pow(2, -3),Math.pow(2, -1),
-//            Math.pow(2, 0),Math.pow(2, 1),Math.pow(2, 2),Math.pow(2, 3),Math.pow(2, 4),Math.pow(2, 5),Math.pow(2, 6),
-//            Math.pow(2, 8),Math.pow(2, 10),Math.pow(2, 12),Math.pow(2, 14),Math.pow(2, 15),Math.pow(2, 16),Math.pow(2, 17)};
-        
-        Double[] confParams = new Double[] {Math.pow(2, -10),Math.pow(2, -10), Math.pow(2, -5),Math.pow(2, -3),Math.pow(2, -1),Math.pow(2, 0)};        
-                
+        System.out.println("number of instances: " + numberOfTrainingInstances);
+        System.out.println("end of parsing files.");
+        if (numberOfTrainingInstances == 0) {
+            System.out.println("This user has not edited the loaded area. Cannot train a model!");
+        }
+    }
+
+    private void validateLoop() {
+        Double[] confParams = new Double[] {
+                Math.pow(2, -10), Math.pow(2, -10), Math.pow(2, -5), Math.pow(2, -3), Math.pow(2, -1), Math.pow(2, 0)};
+
         double bestC = Math.pow(2, -10);
-        
-        for(Double param : confParams){
-            //setProgress(4*((5*(trainProgress++))/confParams.length)); 
+
+        for (Double param : confParams) {
             foldScore1 = 0;
             foldScore5 = 0;
@@ -273,10 +250,7 @@
             System.out.println("\n\n\nrunning for C = " + param);
             clearDataset();
-            System.out.println("fold1");            
-            //crossValidateFold(0, 3, 3, 4, false, param);
+            System.out.println("fold1");
             crossValidateFold(0, 4, 4, 5, false, param); //4-1
-            //setProgress(4*((5*(trainProgress++))/confParams.length)); 
-            //System.out.println((5*trainProgress)/confParams.length);
-            
+
             foldScore1 = foldScore1 + score1;
             foldScore5 = foldScore5 + score5;
@@ -284,9 +258,6 @@
             clearDataset();
             System.out.println("fold2");
-            //crossValidateFold(1, 4, 4, 5, false, param);
             crossValidateFold(1, 5, 0, 1, false, param);
-            //setProgress(4*((5*(trainProgress++))/confParams.length));
-            //System.out.println((5*trainProgress)/confParams.length);
-            
+
             foldScore1 = foldScore1 + score1;
             foldScore5 = foldScore5 + score5;
@@ -294,9 +265,6 @@
             clearDataset();
             System.out.println("fold3");
-            //crossValidateFold(2, 5, 0, 1, false, param);
             crossValidateFold(0, 5, 1, 2, true, param);
-            //setProgress(4*((5*(trainProgress++))/confParams.length));
-            //System.out.println((5*trainProgress)/confParams.length);
-            
+
             foldScore1 = foldScore1 + score1;
             foldScore5 = foldScore5 + score5;
@@ -304,9 +272,6 @@
             clearDataset();
             System.out.println("fold4");
-            //crossValidateFold(0, 5, 1, 2, true, param); 
             crossValidateFold(0, 5, 2, 3, true, param);
-            //setProgress(4*((5*(trainProgress++))/confParams.length));
-            //System.out.println((5*trainProgress)/confParams.length);
-            
+
             foldScore1 = foldScore1 + score1;
             foldScore5 = foldScore5 + score5;
@@ -314,72 +279,64 @@
             clearDataset();
             System.out.println("fold5");
-            //crossValidateFold(0, 5, 2, 3, true, param);
             crossValidateFold(0, 5, 3, 4, true, param);
-            //setProgress(4*((5*(trainProgress++))/confParams.length));
-            //System.out.println((5*trainProgress)/confParams.length);
-            
+
             foldScore1 = foldScore1 + score1;
             foldScore5 = foldScore5 + score5;
             foldScore10 = foldScore10 + score10;
             System.out.println("\n\nC=" + param + ", average score 1-5-10: " + foldScore1/5 +" "+ foldScore5/5 + " "+ foldScore10/5);
-            if(bestScore < foldScore1 ){
+            if (bestScore < foldScore1) {
                 bestScore = foldScore1;
                 bestC = param;
             }
-            
-        }
-        //System.out.println(4*((5*(trainProgress++))/confParams.length));
-        //setProgress(100);
+
+        }
         bestConfParam = bestC;
-        System.out.println("best c param= " + bestC + ", score: " + bestScore/5 );
-    }
-    
-    private void crossValidateFold(int a, int b, int c, int d, boolean skip, double param){
+        System.out.println("best c param= " + bestC + ", score: " + bestScore/5);
+    }
+
+    private void crossValidateFold(int a, int b, int c, int d, boolean skip, double param) {
         System.out.println("Starting cross validation");
         int testSize = wayList.size()/5;
 
-        List<OSMWay> trainList= new ArrayList<>();
-        for(int g = a*testSize; g<b*testSize; g++){  // 0~~1~~2~~3~~4~~5
-            if(skip){
-                if(g == (c)*testSize){g=(c+1)*testSize;}
-            
-            }
-            trainList.add(wayList.get(g)); 
-        }  
+        List<OSMWay> trainList = new ArrayList<>();
+        for (int g = a*testSize; g < b*testSize; g++) {  // 0~~1~~2~~3~~4~~5
+            if (skip) {
+                if (g == (c)*testSize) {
+                    g = (c+1)*testSize;
+                }
+            }
+            trainList.add(wayList.get(g));
+        }
 
         int wayListSizeWithoutUnclassified = trainList.size();
-        int u = 0;
         System.out.println("trainList size: " + wayListSizeWithoutUnclassified);
-        
+
         //set classes for each osm instance
-        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size 
-        for(OSMWay way : trainList){
+        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size
+        for (OSMWay way : trainList) {
 
             OSMClassification classifyInstances = new OSMClassification();
             classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
 
-            if(way.getClassIDs().isEmpty()){
+            if (way.getClassIDs().isEmpty()) {
                 wayListSizeWithoutUnclassified -= 1;
-                u++;
-            }
-            else {
+            } else {
                 sizeToBeAddedToArray = sizeToBeAddedToArray + way.getClassIDs().size()-1;
-            }                
-        } 
-        double C = param;        
+            }
+        }
+        double C = param;
         double eps = 0.001;
-        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];//new double[117558];//                
-        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures]; //working[3812];
-        int k =0;    
-        
-        for(OSMWay way : trainList){
-            //adding multiple vectors                     
-            int id;           
-            if(USE_CLASS_FEATURES){                
+        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];
+        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures];
+        int k = 0;
+
+        for (OSMWay way : trainList) {
+            //adding multiple vectors
+            int id;
+            if (USE_CLASS_FEATURES) {
                 ClassFeatures class_vector = new ClassFeatures();
                 class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
                 id = 1422;
-            }
-            else{
+            } else {
                 id = 1;
             }
@@ -390,60 +347,56 @@
             //id after geometry, cases: all geometry features with mean-variance boolean intervals:
             //id = 1526
-            if(USE_RELATION_FEATURES){
+            if (USE_RELATION_FEATURES) {
                 RelationFeatures relationFeatures = new RelationFeatures(id);
-                relationFeatures.createRelationFeatures(way, relationList);    
+                relationFeatures.createRelationFeatures(way, relationList);
                 id = relationFeatures.getLastID();
-            }
-            else {
+            } else {
                 id = geometryFeatures.getLastID();
             }
             //id 1531
-            
+
             TextualFeatures textualFeatures;
-            if(USE_TEXTUAL_FEATURES){
+            if (USE_TEXTUAL_FEATURES) {
                 textualFeatures = new TextualFeatures(id, namesList, languageDetector);
                 textualFeatures.createTextualFeatures(way);
             }
-           
+
             List<FeatureNode> featureNodeList = way.getFeatureNodeList();
             FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
-                        
-            if(!way.getClassIDs().isEmpty()){
-                int i =0;
-                for(FeatureNode featureNode : featureNodeList){
+
+            if (!way.getClassIDs().isEmpty()) {
+                int i = 0;
+                for (FeatureNode featureNode : featureNodeList) {
                     featureNodeArray[i] = featureNode;
                     i++;
-                }               
-                for(int classID : way.getClassIDs()){
+                }
+                for (int classID : way.getClassIDs()) {
                     trainingSetWithUnknown2[k] = featureNodeArray;
                     GROUPS_ARRAY2[k] = classID;
-                    k++;                    
-                }                                
-            }           
-        }
-        
-        //Linear.enableDebugOutput();
-        Problem problem = new Problem();  
-        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;//wayListSizeWithoutUnclassified;//wayList.size();
-        problem.n = numberOfFeatures; //(geometry 105 + textual        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
+                    k++;
+                }
+            }
+        }
+
+        Problem problem = new Problem();
+        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;
+        problem.n = numberOfFeatures;
+        //(geometry 105 + textual        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
         problem.x = trainingSetWithUnknown2; // feature nodes
         problem.y = GROUPS_ARRAY2; // target values
-        //SolverType solver = SolverType.MCSVM_CS; //Cramer and Singer for multiclass classification - equivalent of SVMlight
         SolverType solver2 = SolverType.getById(2); //2 -- L2-regularized L2-loss support vector classification (primal)
-  
+
         Parameter parameter = new Parameter(solver2, C, eps);
-        //System.out.println("param set ok");
-        //System.out.println("number of features: " + vc.getNumOfFeatures());       
-        
+
         long start = System.nanoTime();
         System.out.println("training...");
         PrintStream original = System.out;
         System.setOut(new PrintStream(new OutputStream() {
-           @Override
-           public void write(int arg0) throws IOException {
-                
-           }
+            @Override
+            public void write(int arg0) throws IOException {
+
+            }
         }));
-         
+
         Model model = Linear.train(problem, parameter);
         long end = System.nanoTime();
@@ -451,38 +404,35 @@
         System.setOut(original);
         System.out.println("training process completed in: " + NANOSECONDS.toSeconds(elapsedTime) + " seconds.");
-        //System.out.println("trained");
-        
-        //decide model path and naming and/or way of deleting/creating 1 or more models. 
-        //File inFile = new File(inputFilePath).getParentFile();
-        
+
+        //decide model path and naming and/or way of deleting/creating 1 or more models.
+
         File modelFile;
-        if(USE_CLASS_FEATURES){
+        if (USE_CLASS_FEATURES) {
             modelFile = new File(modelDirectory.getAbsolutePath()+"/user_" + username + "_model_with_classes_c=" + param);
-        }
-        else{
+        } else {
             modelFile = new File(modelDirectory.getAbsolutePath()+"/user_" + username + "_model_geometries_textual_c=" + param);
         }
-  
-        if(modelFile.exists()){
+
+        if (modelFile.exists()) {
             modelFile.delete();
-        }        
+        }
         try {
             //System.out.println("file created");
             model.save(modelFile);
-            //System.out.println("saved"); 
+            //System.out.println("saved");
         } catch (IOException ex) {
             Logger.getLogger(TrainByUser.class.getName()).log(Level.SEVERE, null, ex);
         }
 
-        //test set 
-        List<OSMWay> testList= new ArrayList<>();
-        for(int g = c*testSize; g<d*testSize; g++){
+        //test set
+        List<OSMWay> testList = new ArrayList<>();
+        for (int g = c*testSize; g < d*testSize; g++) {
             testList.add(wayList.get(g));
-            //liblinear test                       
+            //liblinear test
         }
         System.out.println("testList size: " + testList.size());
-        int succededInstances=0;
-        int succededInstances5=0;
-        int succededInstances10=0;
+        int succededInstances = 0;
+        int succededInstances5 = 0;
+        int succededInstances10 = 0;
         try {
             model = Model.load(modelFile);
@@ -493,35 +443,31 @@
         int[] labels = model.getLabels();
         Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
-        for(int h =0; h < model.getLabels().length; h++){
+        for (int h = 0; h < model.getLabels().length; h++) {
             mapLabelsToIDs.put(labels[h], h);
-            //System.out.println(h + "   <->    " + labels[h]);
-        }
-        
+        }
+
         int wayListSizeWithoutUnclassified2 = testList.size();
-        for(OSMWay way : testList){
+        for (OSMWay way : testList) {
 
             OSMClassification classifyInstances = new OSMClassification();
             classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-            if(way.getClassIDs().isEmpty()){
-                //System.out.println("found unclassified" + way.getClassIDs() + "class: " +way.getClassID());
+            if (way.getClassIDs().isEmpty()) {
                 wayListSizeWithoutUnclassified2 -= 1;
-                //u++;
-            }
-        }         
-        
+            }
+        }
+
         FeatureNode[] testInstance2;
-        for(OSMWay way : testList){
-            
+        for (OSMWay way : testList) {
+
             int id;
-            
-            if(USE_CLASS_FEATURES){                
+
+            if (USE_CLASS_FEATURES) {
                 ClassFeatures class_vector = new ClassFeatures();
                 class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
                 id = 1422;
-            }
-            else{
+            } else {
                 id = 1;
             }
-            
+
             //pass id also: 1422 if using classes, 1 if not
             GeometryFeatures geometryFeatures = new GeometryFeatures(id);
@@ -530,24 +476,15 @@
             //id after geometry, cases: all geometry features with mean-variance boolean intervals:
             //id = 1526
-            //System.out.println("id 1526 -> " + geometryFeatures.getLastID());
-            if(USE_RELATION_FEATURES){
+            if (USE_RELATION_FEATURES) {
                 RelationFeatures relationFeatures = new RelationFeatures(id);
-                relationFeatures.createRelationFeatures(way, relationList);       
+                relationFeatures.createRelationFeatures(way, relationList);
                 id = relationFeatures.getLastID();
-            }
-            else {
+            } else {
                 id = geometryFeatures.getLastID();
-                //System.out.println("geom feat " + id);
             }
             //id 1531
-            //System.out.println("id 1532 -> " + relationFeatures.getLastID());
-            if(USE_TEXTUAL_FEATURES){
+            if (USE_TEXTUAL_FEATURES) {
                 TextualFeatures textualFeatures = new TextualFeatures(id, namesList, languageDetector);
                 textualFeatures.createTextualFeatures(way);
-                //System.out.println("last textual id: " + textualFeatures.getLastID());
-                //System.out.println("full:  " + way.getFeatureNodeList());
-            }
-            else{
-                
             }
             List<FeatureNode> featureNodeList = way.getFeatureNodeList();
@@ -555,6 +492,6 @@
             FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
 
-            int i =0;
-            for(FeatureNode featureNode : featureNodeList){
+            int i = 0;
+            for (FeatureNode featureNode : featureNodeList) {
                 featureNodeArray[i] = featureNode;
                 i++;
@@ -562,6 +499,4 @@
 
             testInstance2 = featureNodeArray;
-            //double prediction = Linear.predict(model, testInstance2);
-            //System.out.println("test prediction: " + prediction);
             double[] scores = new double[modelLabelSize];
             Linear.predictValues(model, testInstance2, scores);
@@ -570,8 +505,8 @@
             //iter scores and find 10 max values with their indexes first. then ask those indexes from model.getlabels
             Map<Double, Integer> scoresValues = new HashMap<>();
-            for(int h = 0; h < scores.length; h++){
-                scoresValues.put(scores[h], h);                
+            for (int h = 0; h < scores.length; h++) {
+                scoresValues.put(scores[h], h);
                 //System.out.println(h + "   <->    " + scores[h]);
-            }          
+            }
 
             Arrays.sort(scores);
@@ -582,95 +517,86 @@
             //System.out.println("way labels: " + way.getClassIDs());
             //System.out.println("test prediction: " + prediction);
-            if(way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])])){
-                succededInstances++;              
-            }
-            if(
-                    
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])]) || 
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-2])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-3])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-4])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-5])])
-              ){
+            if (way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])])) {
+                succededInstances++;
+            }
+            if (
+
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-2])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-3])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-4])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-5])])
+                    ) {
                 succededInstances5++;
             }
-            if(
-                    
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])]) || 
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-2])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-3])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-4])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-5])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-6])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-7])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-8])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-9])]) ||
-                way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-10])])
-              ){
+            if (
+
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-1])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-2])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-3])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-4])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-5])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-6])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-7])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-8])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-9])]) ||
+                    way.getClassIDs().contains(labels[scoresValues.get(scores[scores.length-10])])
+                    ) {
                 succededInstances10++;
-            } 
-            //System.out.println("labels: " + Arrays.toString(model.getLabels()));
-            //System.out.println("label[0]: " + model.getLabels()[0]);            
-        }        
-        
+            }
+        }
+
         System.out.println("Succeeded " + succededInstances + " of " + testList.size() + " total (1 class prediction)");
-        double precision1 = succededInstances/(double)wayListSizeWithoutUnclassified2;
+        double precision1 = succededInstances/(double) wayListSizeWithoutUnclassified2;
         score1 = precision1;
         System.out.println(precision1);
-        
+
         System.out.println("Succeeded " + succededInstances5 + " of " + testList.size()+ " total (5 class prediction)");
-        double precision5 = succededInstances5/(double)wayListSizeWithoutUnclassified2;
+        double precision5 = succededInstances5/(double) wayListSizeWithoutUnclassified2;
         score5 = precision5;
         System.out.println(precision5);
-        
+
         System.out.println("Succeeded " + succededInstances10 + " of " + testList.size()+ " total (10 class prediction)");
-        double precision10 = succededInstances10/(double)wayListSizeWithoutUnclassified2;
+        double precision10 = succededInstances10/(double) wayListSizeWithoutUnclassified2;
         score10 = precision10;
-        System.out.println(precision10);               
-    }  
-    
-    private void trainModel(double param){
-        
+        System.out.println(precision10);
+    }
+
+    private void trainModel(double param) {
+
         int wayListSizeWithoutUnclassified = wayList.size();
-        int u = 0;
         System.out.println("trainList size: " + wayListSizeWithoutUnclassified);
-        if(wayListSizeWithoutUnclassified == 0){
+        if (wayListSizeWithoutUnclassified == 0) {
             System.out.println("aborting training process..");
             return;
         }
         //set classes for each osm instance
-        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size 
-
-        //System.out.println("starting classify instances");
-        for(OSMWay way : wayList){
-            //setProgress(trainProgress++);
+        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size
+
+        for (OSMWay way : wayList) {
             OSMClassification classifyInstances = new OSMClassification();
             classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
 
-            if(way.getClassIDs().isEmpty()){
+            if (way.getClassIDs().isEmpty()) {
                 wayListSizeWithoutUnclassified -= 1;
-                u++;
-            }
-            else {
+            } else {
                 sizeToBeAddedToArray = sizeToBeAddedToArray + way.getClassIDs().size()-1;
-            }                
-        } 
+            }
+        }
         //System.out.println("end classify instances");
-        double C = param;        
+        double C = param;
         double eps = 0.001;
-        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];//new double[117558];//                
-        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures]; //working[3812];
-        int k =0; 
-        
-        //setProgress(trainProgress+5);
-        for(OSMWay way : wayList){
-            //adding multiple vectors                     
-            int id;           
-            if(USE_CLASS_FEATURES){                
+        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];
+        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures];
+        int k = 0;
+
+        for (OSMWay way : wayList) {
+            //adding multiple vectors
+            int id;
+            if (USE_CLASS_FEATURES) {
                 ClassFeatures class_vector = new ClassFeatures();
                 class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
                 id = 1422;
-            }
-            else{
+            } else {
                 id = 1;
             }
@@ -681,62 +607,56 @@
             //id after geometry, cases: all geometry features with mean-variance boolean intervals:
             //id = 1526
-            if(USE_RELATION_FEATURES){
+            if (USE_RELATION_FEATURES) {
                 RelationFeatures relationFeatures = new RelationFeatures(id);
-                relationFeatures.createRelationFeatures(way, relationList);    
+                relationFeatures.createRelationFeatures(way, relationList);
                 id = relationFeatures.getLastID();
-            }
-            else {
+            } else {
                 id = geometryFeatures.getLastID();
             }
             //id 1531
-            
+
             TextualFeatures textualFeatures;
-            if(USE_TEXTUAL_FEATURES){
-                textualFeatures = new TextualFeatures(id, namesList,languageDetector);
+            if (USE_TEXTUAL_FEATURES) {
+                textualFeatures = new TextualFeatures(id, namesList, languageDetector);
                 textualFeatures.createTextualFeatures(way);
             }
-           
+
             List<FeatureNode> featureNodeList = way.getFeatureNodeList();
             FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
-                        
-            if(!way.getClassIDs().isEmpty()){
-                int i =0;
-                for(FeatureNode featureNode : featureNodeList){
+
+            if (!way.getClassIDs().isEmpty()) {
+                int i = 0;
+                for (FeatureNode featureNode : featureNodeList) {
                     featureNodeArray[i] = featureNode;
                     i++;
-                }               
-                for(int classID : way.getClassIDs()){
+                }
+                for (int classID : way.getClassIDs()) {
                     trainingSetWithUnknown2[k] = featureNodeArray;
                     GROUPS_ARRAY2[k] = classID;
-                    k++;                    
-                }                                
-            }           
-        } 
-        //System.out.println("feature construction completed.");
-        //Linear.enableDebugOutput();
-        Problem problem = new Problem();  
-        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;//wayListSizeWithoutUnclassified;//wayList.size();
-        problem.n = numberOfFeatures;//3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
+                    k++;
+                }
+            }
+        }
+        Problem problem = new Problem();
+        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;
+        problem.n = numberOfFeatures;
+        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
         problem.x = trainingSetWithUnknown2; // feature nodes
         problem.y = GROUPS_ARRAY2; // target values
-        //SolverType solver = SolverType.MCSVM_CS; //Cramer and Singer for multiclass classification - equivalent of SVMlight
         SolverType solver2 = SolverType.getById(2); //2 -- L2-regularized L2-loss support vector classification (primal)
-  
+
         Parameter parameter = new Parameter(solver2, C, eps);
-        //System.out.println("param set ok");
-        //System.out.println("number of features: " + vc.getNumOfFeatures());       
-        
+
         long start = System.nanoTime();
         System.out.println("training...");
         PrintStream original = System.out;
         System.setOut(new PrintStream(new OutputStream() {
-
-           @Override
-           public void write(int arg0) throws IOException {
-
-           }
-        }));     
-        
-        
+            @Override
+            public void write(int arg0) throws IOException {
+
+            }
+        }));
+
+
         Model model = Linear.train(problem, parameter);
         long end = System.nanoTime();
@@ -744,81 +664,67 @@
         System.setOut(original);
         System.out.println("training process completed in: " + NANOSECONDS.toSeconds(elapsedTime) + " seconds.");
-        //System.out.println("trained");
-        
-        //decide model path and naming and/or way of deleting/creating 1 or more models. 
-        //File inFile = new File(inputFilePath).getParentFile();
-        
+
+        //decide model path and naming and/or way of deleting/creating 1 or more models.
+
         File modelFile = new File(modelDirectory.getAbsolutePath()+"/best_model"); //decide path of models
-        
+
         File customModelFile;
-        if(topKIsSelected){
-            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_topK" + topK + "user" + username + ".0");
-        }
-        else{
-            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_maxF" + frequency + "user" + username + ".0");
-        }
-        
-        if(modelFile.exists()){
+        if (topKIsSelected) {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" +
+                    inputFileName + "_model_c" + param + "_topK" + topK + "user" + username + ".0");
+        } else {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" +
+                    inputFileName + "_model_c" + param + "_maxF" + frequency + "user" + username + ".0");
+        }
+
+        if (modelFile.exists()) {
             modelFile.delete();
-        }  
-        if(customModelFile.exists()){
+        }
+        if (customModelFile.exists()) {
             customModelFile.delete();
-        }         
+        }
         try {
-            //System.out.println("file created");
             model.save(modelFile);
             model.save(customModelFile);
-            System.out.println("model saved at: " + modelFile); 
+            System.out.println("model saved at: " + modelFile);
             System.out.println("custom model saved at: " + customModelFile);
         } catch (IOException ex) {
             Logger.getLogger(TrainByUser.class.getName()).log(Level.SEVERE, null, ex);
-        }        
-    }
-    
-    private void trainModelWithClasses(double param){
-        
+        }
+    }
+
+    private void trainModelWithClasses(double param) {
+
         int wayListSizeWithoutUnclassified = wayList.size();
-        int u = 0;
         System.out.println("trainList size: " + wayListSizeWithoutUnclassified);
-        
-        if(wayListSizeWithoutUnclassified == 0){
+
+        if (wayListSizeWithoutUnclassified == 0) {
             System.out.println("aborting training process with classes..");
             return;
         }
         //set classes for each osm instance
-        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size 
-        //int lalala = 0;
-        //setProgress(trainProgress-10);
-        for(OSMWay way : wayList){
-            //setProgress(trainProgress++);
+        int sizeToBeAddedToArray = 0; //this will be used to proper init the features array, adding the multiple vectors size
+        for (OSMWay way : wayList) {
             OSMClassification classifyInstances = new OSMClassification();
             classifyInstances.calculateClasses(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
 
-            if(way.getClassIDs().isEmpty()){
+            if (way.getClassIDs().isEmpty()) {
                 wayListSizeWithoutUnclassified -= 1;
-                u++;
-            }
-            else {
+            } else {
                 sizeToBeAddedToArray = sizeToBeAddedToArray + way.getClassIDs().size()-1;
-            }                
-        } 
-        double C = param;        
+            }
+        }
+        double C = param;
         double eps = 0.001;
-        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];//new double[117558];//                
-        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures+1422]; //working[3812];
-        int k =0; 
-        
-        //setProgress(trainProgress+5);
-        for(OSMWay way : wayList){
-            //adding multiple vectors                     
-            int id;           
-            //if(USE_CLASS_FEATURES){                
-                ClassFeatures class_vector = new ClassFeatures();
-                class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
-                id = 1422;
-//            }
-//            else{
-//                id = 1;
-//            }
+        double[] GROUPS_ARRAY2 = new double[wayListSizeWithoutUnclassified+sizeToBeAddedToArray];
+        FeatureNode[][] trainingSetWithUnknown2 = new FeatureNode[wayListSizeWithoutUnclassified+sizeToBeAddedToArray][numberOfFeatures+1422];
+        int k = 0;
+
+        for (OSMWay way : wayList) {
+            //adding multiple vectors
+            int id;
+            ClassFeatures class_vector = new ClassFeatures();
+            class_vector.createClassFeatures(way, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
+            id = 1422;
             //pass id also: 1422 if using classes, 1 if not
             GeometryFeatures geometryFeatures = new GeometryFeatures(id);
@@ -827,63 +733,56 @@
             //id after geometry, cases: all geometry features with mean-variance boolean intervals:
             //id = 1526
-            if(USE_RELATION_FEATURES){
+            if (USE_RELATION_FEATURES) {
                 RelationFeatures relationFeatures = new RelationFeatures(id);
-                relationFeatures.createRelationFeatures(way, relationList);    
+                relationFeatures.createRelationFeatures(way, relationList);
                 id = relationFeatures.getLastID();
-            }
-            else {
+            } else {
                 id = geometryFeatures.getLastID();
             }
             //id 1531
-            
+
             TextualFeatures textualFeatures;
-            if(USE_TEXTUAL_FEATURES){
-                textualFeatures = new TextualFeatures(id, namesList,languageDetector);
+            if (USE_TEXTUAL_FEATURES) {
+                textualFeatures = new TextualFeatures(id, namesList, languageDetector);
                 textualFeatures.createTextualFeatures(way);
             }
-           
+
             List<FeatureNode> featureNodeList = way.getFeatureNodeList();
             FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
-                        
-            if(!way.getClassIDs().isEmpty()){
-                int i =0;
-                for(FeatureNode featureNode : featureNodeList){
+
+            if (!way.getClassIDs().isEmpty()) {
+                int i = 0;
+                for (FeatureNode featureNode : featureNodeList) {
                     featureNodeArray[i] = featureNode;
                     i++;
-                }               
-                for(int classID : way.getClassIDs()){
-                    //lalala++;
+                }
+                for (int classID : way.getClassIDs()) {
                     trainingSetWithUnknown2[k] = featureNodeArray;
                     GROUPS_ARRAY2[k] = classID;
-                    k++;                    
-                }                                
-            }           
-        } 
-        
-        //Linear.enableDebugOutput();
-        Problem problem = new Problem();  
-        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;//wayListSizeWithoutUnclassified;//wayList.size();
-        problem.n = numberOfFeatures+1422;//3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
+                    k++;
+                }
+            }
+        }
+
+        Problem problem = new Problem();
+        problem.l = wayListSizeWithoutUnclassified+sizeToBeAddedToArray;
+        problem.n = numberOfFeatures+1422;
+        //3797; // number of features //the largest index of all features //3811;//3812 //1812 with classes
         problem.x = trainingSetWithUnknown2; // feature nodes
         problem.y = GROUPS_ARRAY2; // target values
-        //SolverType solver = SolverType.MCSVM_CS; //Cramer and Singer for multiclass classification - equivalent of SVMlight
         SolverType solver2 = SolverType.getById(2); //2 -- L2-regularized L2-loss support vector classification (primal)
-  
+
         Parameter parameter = new Parameter(solver2, C, eps);
-        //System.out.println("param set ok");
-        //System.out.println("number of features: " + vc.getNumOfFeatures());       
-        
+
         long start = System.nanoTime();
         System.out.println("training...");
         PrintStream original = System.out;
         System.setOut(new PrintStream(new OutputStream() {
-
-           @Override
-           public void write(int arg0) throws IOException {
-
-           }
-        }));     
-        
-        
+            @Override
+            public void write(int arg0) throws IOException {
+
+            }
+        }));
+
         Model model = Linear.train(problem, parameter);
         long end = System.nanoTime();
@@ -891,54 +790,50 @@
         System.setOut(original);
         System.out.println("training process completed in: " + NANOSECONDS.toSeconds(elapsedTime) + " seconds.");
-        //System.out.println("trained");
-        
-        //decide model path and naming and/or way of deleting/creating 1 or more models. 
-        //File inFile = new File(inputFilePath).getParentFile();
-        
-        File modelFile = new File(modelDirectory.getAbsolutePath()+"/model_with_classes"); 
+
+        //decide model path and naming and/or way of deleting/creating 1 or more models.
+
+        File modelFile = new File(modelDirectory.getAbsolutePath()+"/model_with_classes");
         File customModelFile;
-        if(topKIsSelected){
-            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_topK" + topK + "user" + username + ".1");
-        }
-        else{
-            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" + inputFileName + "_model_c" + param + "_maxF" + frequency + "user" + username + ".1");
-        }
-
-        if(customModelFile.exists()){
+        if (topKIsSelected) {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" +
+                    inputFileName + "_model_c" + param + "_topK" + topK + "user" + username + ".1");
+        } else {
+            customModelFile = new File(modelDirectory.getAbsolutePath()+"/" +
+                    inputFileName + "_model_c" + param + "_maxF" + frequency + "user" + username + ".1");
+        }
+
+        if (customModelFile.exists()) {
             customModelFile.delete();
-        }        
-        if(modelFile.exists()){
+        }
+        if (modelFile.exists()) {
             modelFile.delete();
-        }        
+        }
         try {
-            //System.out.println("file created");
             model.save(modelFile);
             model.save(customModelFile);
-            System.out.println("model with classes saved at: " + modelFile); 
+            System.out.println("model with classes saved at: " + modelFile);
             System.out.println("custom model with classes saved at: " + customModelFile);
         } catch (IOException ex) {
             Logger.getLogger(TrainByUser.class.getName()).log(Level.SEVERE, null, ex);
-        } 
-    }
-    
-    private static void clearDataset(){
-        for(OSMWay way : wayList){
+        }
+    }
+
+    private static void clearDataset() {
+        for (OSMWay way : wayList) {
             way.getFeatureNodeList().clear();
         }
-    }  
-    
+    }
+
     private void readTextualFromDefaultList(InputStream textualFileStream) {
-                 
+
         TextualStatistics textualStatistics = new TextualStatistics();
         textualStatistics.parseTextualList(textualFileStream);
         namesList = textualStatistics.getTextualList();
-  
-    }
-
-    private static void writeTextualListToFile(String filePath, List<Map.Entry<String, Integer>> textualList) 
-    {
-        
-        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8"))) {            
-            for(Map.Entry<String, Integer> entry : textualList){
+
+    }
+
+    private static void writeTextualListToFile(String filePath, List<Map.Entry<String, Integer>> textualList) {
+        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8"))) {
+            for (Map.Entry<String, Integer> entry : textualList) {
                 writer.write(entry.getKey());
                 writer.newLine();
@@ -951,7 +846,7 @@
         } catch (IOException ex) {
             Logger.getLogger(TrainByUser.class.getName()).log(Level.SEVERE, null, ex);
-        }       
-    }
-    
+        }
+    }
+
     @Override
     protected void done() {
@@ -960,13 +855,12 @@
             firePropertyChange("progress", getProgress(), 100);
             setProgress(100);
-        } 
-        catch (InterruptedException | ExecutionException ignore) {
+        } catch (InterruptedException | ExecutionException ignore) {
             System.out.println("Exception: " + ignore);
         }
-    }     
-    
+    }
+
     @Override
     public void actionPerformed(ActionEvent ae) {
         //cancel button, end process after clearing Dataset
-    }    
+    }
 }
Index: /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/UserDataExtractAndTrainWorker.java
===================================================================
--- /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/UserDataExtractAndTrainWorker.java	(revision 32403)
+++ /applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/personalization/UserDataExtractAndTrainWorker.java	(revision 32404)
@@ -1,2 +1,3 @@
+// License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.osmrec.personalization;
 
@@ -11,17 +12,19 @@
 import java.util.List;
 import java.util.TimeZone;
+
 import javax.swing.SwingWorker;
-import org.openstreetmap.josm.plugins.container.OSMWay;
-import org.openstreetmap.josm.plugins.extractor.LanguageDetector;
-import org.openstreetmap.josm.plugins.parsers.OSMParser;
+
+import org.openstreetmap.josm.plugins.osmrec.container.OSMWay;
+import org.openstreetmap.josm.plugins.osmrec.extractor.LanguageDetector;
+import org.openstreetmap.josm.plugins.osmrec.parsers.OSMParser;
 
 /**
  * Extracts user information about history edits or by area and initiates the training process based on that user.
- * 
+ *
  * @author imis-nkarag
  */
 
-public class UserDataExtractAndTrainWorker extends SwingWorker<Void, Void> implements ActionListener{
-    
+public class UserDataExtractAndTrainWorker extends SwingWorker<Void, Void> implements ActionListener {
+
     private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
     private static final ArrayList<String> timeIntervals = new ArrayList<>();
@@ -38,8 +41,8 @@
     private final LanguageDetector languageDetector;
     private int userTrainProgress = 0;
-    
-    public UserDataExtractAndTrainWorker(String inputFilePath, String username, Integer days, boolean byArea, boolean validateFlag, 
-            double cParameterFromUser, int topK, int frequency, boolean topKIsSelected, LanguageDetector languageDetector){
-       
+
+    public UserDataExtractAndTrainWorker(String inputFilePath, String username, Integer days, boolean byArea, boolean validateFlag,
+            double cParameterFromUser, int topK, int frequency, boolean topKIsSelected, LanguageDetector languageDetector) {
+
         this.inputFilePath = inputFilePath;
         this.username = username;
@@ -50,55 +53,50 @@
         this.topK = topK;
         this.frequency = frequency;
-        this.topKIsSelected = topKIsSelected; 
+        this.topKIsSelected = topKIsSelected;
         this.languageDetector = languageDetector;
-        
+
     }
-    
+
     @Override
     protected Void doInBackground() throws Exception {
-        
+
         System.out.println("UserDataExtractAndTrainWorker doInBackground initiating..");
-        if(byArea){
-           extractByArea(); 
+        if (byArea) {
+            extractByArea();
+        } else {
+            extractHistory();
         }
-        else{ 
-           extractHistory(); 
-        }
-       
-        TrainByUser trainByUser = new TrainByUser(inputFilePath, username, validateFlag, 
+
+        TrainByUser trainByUser = new TrainByUser(inputFilePath, username, validateFlag,
                 cParameterFromUser, topK, frequency, topKIsSelected, languageDetector, wayList);
 
         System.out.println("trainByUser executing..");
         trainByUser.addPropertyChangeListener(new PropertyChangeListener() {
-                            
-            @Override 
+
+            @Override
             public void propertyChange(PropertyChangeEvent evt) {
-                if("progress".equals(evt.getPropertyName())) {
+                if ("progress".equals(evt.getPropertyName())) {
                     int progress = (Integer) evt.getNewValue();
                     System.out.println("progress++ from property change listener, progress: " + progress);
                     setProgress(progress);
-                    
+
                 }
-            }                                                 
-        }); 
-        
-        
-        
-        
-        
+            }
+        });
+
         trainByUser.doInBackground();
         setProgress(100);
         return null;
     }
-    
+
     private void extractHistory() {
-        if(wayList != null){
+        if (wayList != null) {
             wayList.clear();
         }
-        
+
         produceTimeIntervals(days);
         HistoryParser historyParser = new HistoryParser(username);
-        
-        for(String time : timeIntervals){
+
+        for (String time : timeIntervals) {
             System.out.println("interval\n " + time);
             historyParser.historyParse(time);
@@ -106,37 +104,33 @@
         wayList = historyParser.getWayList();
     }
-    
+
     private void extractByArea() {
         System.out.println("Extracting by Area..");
 
-        if(wayList != null){
+        if (wayList != null) {
             wayList.clear();
         }
-        //System.out.println("wayList cleared.");
-        
+
         OSMParser osmParser = new OSMParser(inputFilePath);
         osmParser.parseDocument();
 
-        //System.out.println("OSMParser done.");
-        
         List<OSMWay> completeWayList = osmParser.getWayList();
         System.out.println("completeWayList size: " + completeWayList.size());
         System.out.println("populating wayList with edits from username: " + username);
-        for(OSMWay way : completeWayList){
+        for (OSMWay way : completeWayList) {
             //System.out.println("current way user: " + way.getUser());
-            if(way.getUser().equals(username)){
+            if (way.getUser().equals(username)) {
                 System.out.println("found user edit!");
                 wayList.add(way);
-            }            
-        } 
+            }
+        }
         System.out.println("weeding wayList by user done.");
-        if(wayList.isEmpty()){
+        if (wayList.isEmpty()) {
             System.out.println("User has not edited this Area. Try \"By time\" option.");
-        }
-        else{
+        } else {
             System.out.println("User has edited " + wayList.size() + " OSM entities in this area.");
         }
-    }   
-    
+    }
+
     private void produceTimeIntervals(Integer days) {
 
@@ -144,28 +138,27 @@
         sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
 
-        Date currentDate = new Date();        
+        Date currentDate = new Date();
         Calendar cal = Calendar.getInstance();
 
         cal.setTime(currentDate);
         String currentTimeString = sdf.format(currentDate);
-        
+
         cal.add(Calendar.DATE, -days); //starting date
         Date startingTime = cal.getTime();
-        
+
         String startingTimeString = sdf.format(startingTime);
-        //System.out.println("starting date: " + startingTimeString);
-        //add to list 
-        
+        //add to list
+
         String nextIntervalTime = startingTimeString;
-        
-        //do, while date is before current date,after the addition of the 10 days        
+
+        //do, while date is before current date,after the addition of the 10 days
         do {
             cal.add(Calendar.DATE, 10);
-            
+
             Date intervalTime = cal.getTime();
             String intervalTimeString = sdf.format(intervalTime);
-            String timeOsmApiArgument = nextIntervalTime + "," + intervalTimeString;        
-            
-            if(cal.getTime().after(currentDate)){
+            String timeOsmApiArgument = nextIntervalTime + "," + intervalTimeString;
+
+            if (cal.getTime().after(currentDate)) {
                 //add the offset of remaining days as last interval
                 timeOsmApiArgument = nextIntervalTime + "," + currentTimeString;
@@ -173,11 +166,10 @@
                 System.out.println(timeOsmApiArgument);
                 break;
-            }
-            else{
+            } else {
                 timeIntervals.add(timeOsmApiArgument);
             }
             nextIntervalTime = intervalTimeString;
             System.out.println(" ti: " + timeOsmApiArgument);
-        } while(cal.getTime().before(currentDate));
+        } while (cal.getTime().before(currentDate));
     }
 
@@ -185,8 +177,8 @@
     public void actionPerformed(ActionEvent ae) {
         //this.firePropertyChange("progress", userTrainProgress, userTrainProgress+10);
-//        if(userTrainProgress <100){
-//            setProgress(userTrainProgress+10);
-//        }
-        
+        //        if (userTrainProgress <100) {
+        //            setProgress(userTrainProgress+10);
+        //        }
+
     }
 }
