Index: applications/editors/josm/plugins/czechaddress/build.xml
===================================================================
--- applications/editors/josm/plugins/czechaddress/build.xml	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/build.xml	(revision 15461)
@@ -26,64 +26,24 @@
         <!-- compile the plugin -->
         <javac srcdir="src"
+               sourcepath=""
                classpath="${josm.jar}"
                destdir="${plugin.build.dir}"
-               debug="true"/>
+               debug="true">
 
-        <!-- create the manifest -->
-        <manifest file="${plugin.build.dir}/${plugin.basepackage.dir}/MANIFEST.MF">
-            <attribute name="Author" value="Radomír Černoch"/>
-            <attribute name="Plugin-Description" value="Creating and handling address nodes and buildings within Czech Republic."/>
-            <attribute name="Plugin-Mainversion" value="1607"/>
-            <attribute name="Plugin-Version" value="0.1.1"/>
-            <attribute name="Plugin-Class" value="${plugin.basepackage}.CzechAddressPlugin"/>
-        </manifest>
+            <include name="**/Status*.java"/>
+            <include name="**/StringUtils.java"/>
+            <include name="**/NotNull*.java"/>
+            <include name="**/addressdatabase/*.java"/>
+            <include name="**/proposal*/*.java"/>
+            <include name="**/intelligence/Reasoner*.java"/>
+            <include name="**/intelligence/Match.java"/>
+        </javac>
 
-        <!-- include the images -->
-        <copy todir="${plugin.build.dir}/images">
-            <fileset dir="images"/>
-        </copy>
     </target>
 
-    <target name="dist"
-            depends="compile"
-            description="Create the .jar file for distribution">
-        <mkdir dir="${plugin.dist.dir}"/>
-        <jar destfile="${plugin.jar}"
-             basedir="${plugin.build.dir}"
-             manifest="${plugin.build.dir}/${plugin.basepackage.dir}/MANIFEST.MF"/>
-    </target>
-
-    <target name="doc" description="Create Javadoc API documentation">
-        <ant antfile="build.xml" target="doc" dir="${josm.base}"/>
-        <mkdir dir="${plugin.javadoc.dir}"/>
-        <javadoc sourcepath="src"
-                 packagenames="*"
-                 destdir="${plugin.javadoc.dir}"
-                 use="true"
-                 charset="UTF-8">
-            <doctitle><![CDATA[Czech Address JOSM plugin]]></doctitle>
-            <bottom><![CDATA[<i>Licenced under GPLv3. Bugreports should be sent to
-                    <a href='mailto:radomir.cernoch@gmail.com'>Radomír Černoch</a></i>]]>
-            </bottom>
-            <!--<tag name="todo" scope="all" description="To do:"/>-->
-            <link href="http://java.sun.com/j2se/1.5.0/docs/api/"/>
-            <link href="http://developer.java.sun.com/developer/products/xml/docs/api/"/>
-            <!--<link href="file://${user.home}/devel/core/doc"/>-->
-        </javadoc>
-    </target>
-
-    <target name="install" depends="dist">
-        <property environment="env"/>
-        <condition property="josm.plugins.dir"
-                   value="${env.APPDATA}/JOSM/plugins"
-                   else="${user.home}/.josm/plugins">
-            <and><os family="windows"/></and>
-        </condition>
-        <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>
-    </target>
 
     <!-- Before running "run" target, please "ant dist" the JOSM. -->
     <target name="run" depends="compile">
-        <java classname="JOSM" fork="true">
+        <java classname="org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner">
             <jvmarg value="-Xmx1024m"/>
             <jvmarg value="-Xdebug"/>
@@ -97,6 +57,9 @@
                 <pathelement path="${java.class.path}"/>
             </classpath>
-        <!--<arg value="/home/radek/Desktop/Hustopeče.osm"/>-->
         </java>
+        <exec executable="xsltproc" output="log.html">
+            <arg value="log.xsl"/>
+            <arg value="log.xml"/>
+        </exec>
     </target>
 
Index: applications/editors/josm/plugins/czechaddress/log.xsl
===================================================================
--- applications/editors/josm/plugins/czechaddress/log.xsl	(revision 15461)
+++ applications/editors/josm/plugins/czechaddress/log.xsl	(revision 15461)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:template match="/">
+  <html>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <body>
+    <table border="1">
+      <tr bgcolor="#9acd32">
+        <th>Date</th>
+        <th>Level</th>
+        <th>Message</th>
+        <th>Method</th>
+        <th>Param</th>
+      </tr>
+      <xsl:for-each select="log/record">
+      <tr>
+        <td><font size="-3"><xsl:value-of select="date"/></font></td>
+        <xsl:choose>
+            <xsl:when test="level = 'FINEST'">
+                <td><font color='#AAAAAA'><xsl:value-of select="level"/></font></td>
+                <td><xsl:value-of select="message"/></td>
+            </xsl:when>
+            <xsl:when test="level = 'FINER'">
+                <td><font color='#999999'><xsl:value-of select="level"/></font></td>
+                <td><xsl:value-of select="message"/></td>
+            </xsl:when>
+            <xsl:when test="level = 'FINE'">
+                <td><font color='#444444'><xsl:value-of select="level"/></font></td>
+                <td><xsl:value-of select="message"/></td>
+            </xsl:when>
+            <xsl:when test="level = 'INFO'">
+                <td><font color='black'><b><xsl:value-of select="level"/></b></font></td>
+                <td><b><xsl:value-of select="message"/></b></td>
+            </xsl:when>
+            <xsl:when test="level = 'WARNING'">
+                <td><font color='red'><b><xsl:value-of select="level"/></b></font></td>
+                <td><b><xsl:value-of select="message"/></b></td>
+            </xsl:when>
+            <xsl:otherwise>
+                <td><xsl:value-of select="level"/></td>
+            </xsl:otherwise>
+        </xsl:choose>
+        <td><tt><xsl:value-of select="method"/></tt></td>
+        <td><xsl:value-of select="param"/></td>
+      </tr>
+      </xsl:for-each>
+    </table>
+  </body>
+  </html>
+</xsl:template>
+</xsl:stylesheet>
+
+
Index: applications/editors/josm/plugins/czechaddress/logger.dtd
===================================================================
--- applications/editors/josm/plugins/czechaddress/logger.dtd	(revision 15461)
+++ applications/editors/josm/plugins/czechaddress/logger.dtd	(revision 15461)
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Authors: Chris Taylor, Ceki Gulcu. -->
+
+<!-- Version: 1.2 -->
+
+<!-- A configuration element consists of optional renderer
+elements,appender elements, categories and an optional root
+element. -->
+
+<!ELEMENT log4j:configuration (renderer*, appender*,plugin*, (category|logger)*,root?,
+                               (categoryFactory|loggerFactory)?)>
+
+<!-- The "threshold" attribute takes a level value below which -->
+<!-- all logging statements are disabled. -->
+
+<!-- Setting the "debug" enable the printing of internal log4j logging   -->
+<!-- statements.                                                         -->
+
+<!-- By default, debug attribute is "null", meaning that we not do touch -->
+<!-- internal log4j logging settings. The "null" value for the threshold -->
+<!-- attribute can be misleading. The threshold field of a repository	 -->
+<!-- cannot be set to null. The "null" value for the threshold attribute -->
+<!-- simply means don't touch the threshold field, the threshold field   --> 
+<!-- keeps its old value.                                                -->
+     
+<!ATTLIST log4j:configuration
+  xmlns:log4j              CDATA #FIXED "http://jakarta.apache.org/log4j/" 
+  threshold                (all|trace|debug|info|warn|error|fatal|off|null) "null"
+  debug                    (true|false|null)  "null"
+  reset                    (true|false) "false"
+>
+
+<!-- renderer elements allow the user to customize the conversion of  -->
+<!-- message objects to String.                                       -->
+
+<!ELEMENT renderer EMPTY>
+<!ATTLIST renderer
+  renderedClass  CDATA #REQUIRED
+  renderingClass CDATA #REQUIRED
+>
+
+<!-- Appenders must have a name and a class. -->
+<!-- Appenders may contain an error handler, a layout, optional parameters -->
+<!-- and filters. They may also reference (or include) other appenders. -->
+<!ELEMENT appender (errorHandler?, param*,
+      rollingPolicy?, triggeringPolicy?, connectionSource?,
+      layout?, filter*, appender-ref*)>
+<!ATTLIST appender
+  name 		CDATA 	#REQUIRED
+  class 	CDATA	#REQUIRED
+>
+
+<!ELEMENT layout (param*)>
+<!ATTLIST layout
+  class		CDATA	#REQUIRED
+>
+
+<!ELEMENT filter (param*)>
+<!ATTLIST filter
+  class		CDATA	#REQUIRED
+>
+
+<!-- ErrorHandlers can be of any class. They can admit any number of -->
+<!-- parameters. -->
+
+<!ELEMENT errorHandler (param*, root-ref?, logger-ref*,  appender-ref?)> 
+<!ATTLIST errorHandler
+   class        CDATA   #REQUIRED 
+>
+
+<!ELEMENT root-ref EMPTY>
+
+<!ELEMENT logger-ref EMPTY>
+<!ATTLIST logger-ref
+  ref CDATA #REQUIRED
+>
+
+<!ELEMENT param EMPTY>
+<!ATTLIST param
+  name		CDATA   #REQUIRED
+  value		CDATA	#REQUIRED
+>
+
+
+<!-- The priority class is org.apache.log4j.Level by default -->
+<!ELEMENT priority (param*)>
+<!ATTLIST priority
+  class   CDATA	#IMPLIED
+  value	  CDATA #REQUIRED
+>
+
+<!-- The level class is org.apache.log4j.Level by default -->
+<!ELEMENT level (param*)>
+<!ATTLIST level
+  class   CDATA	#IMPLIED
+  value	  CDATA #REQUIRED
+>
+
+
+<!-- If no level element is specified, then the configurator MUST not -->
+<!-- touch the level of the named category. -->
+<!ELEMENT category (param*,(priority|level)?,appender-ref*)>
+<!ATTLIST category
+  class         CDATA   #IMPLIED
+  name		CDATA	#REQUIRED
+  additivity	(true|false) "true"  
+>
+
+<!-- If no level element is specified, then the configurator MUST not -->
+<!-- touch the level of the named logger. -->
+<!ELEMENT logger (level?,appender-ref*)>
+<!ATTLIST logger
+  name		CDATA	#REQUIRED
+  additivity	(true|false) "true"  
+>
+
+
+<!ELEMENT categoryFactory (param*)>
+<!ATTLIST categoryFactory 
+   class        CDATA #REQUIRED>
+
+<!ELEMENT loggerFactory (param*)>
+<!ATTLIST loggerFactory
+   class        CDATA #REQUIRED>
+
+<!ELEMENT appender-ref EMPTY>
+<!ATTLIST appender-ref
+  ref CDATA #REQUIRED
+>
+
+<!-- plugins must have a name and class and can have optional parameters -->
+<!ELEMENT plugin (param*, connectionSource?)>
+<!ATTLIST plugin
+  name 		CDATA 	   #REQUIRED
+  class 	CDATA  #REQUIRED
+>
+
+<!ELEMENT connectionSource (dataSource?, param*)>
+<!ATTLIST connectionSource
+  class        CDATA  #REQUIRED
+>
+
+<!ELEMENT dataSource (param*)>
+<!ATTLIST dataSource
+  class        CDATA  #REQUIRED
+>
+
+<!ELEMENT triggeringPolicy ((param|filter)*)>
+<!ATTLIST triggeringPolicy
+  name 		CDATA  #IMPLIED
+  class 	CDATA  #REQUIRED
+>
+
+<!ELEMENT rollingPolicy (param*)>
+<!ATTLIST rollingPolicy
+  name 		CDATA  #IMPLIED
+  class 	CDATA  #REQUIRED
+>
+
+
+<!-- If no priority element is specified, then the configurator MUST not -->
+<!-- touch the priority of root. -->
+<!-- The root category always exists and cannot be subclassed. -->
+<!ELEMENT root (param*, (priority|level)?, appender-ref*)>
+
+
+<!-- ==================================================================== -->
+<!--                       A logging event                                -->
+<!-- ==================================================================== -->
+<!ELEMENT log4j:eventSet (log4j:event*)>
+<!ATTLIST log4j:eventSet
+  xmlns:log4j             CDATA #FIXED "http://jakarta.apache.org/log4j/" 
+  version                (1.1|1.2) "1.2" 
+  includesLocationInfo   (true|false) "true"
+>
+
+
+
+<!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?, 
+                       log4j:locationInfo?, log4j:properties?) >
+
+<!-- The timestamp format is application dependent. -->
+<!ATTLIST log4j:event
+    logger     CDATA #REQUIRED
+    level      CDATA #REQUIRED
+    thread     CDATA #REQUIRED
+    timestamp  CDATA #REQUIRED
+    time       CDATA #IMPLIED
+>
+
+<!ELEMENT log4j:message (#PCDATA)>
+<!ELEMENT log4j:NDC (#PCDATA)>
+
+<!ELEMENT log4j:throwable (#PCDATA)>
+
+<!ELEMENT log4j:locationInfo EMPTY>
+<!ATTLIST log4j:locationInfo
+  class  CDATA	#REQUIRED
+  method CDATA	#REQUIRED
+  file   CDATA	#REQUIRED
+  line   CDATA	#REQUIRED
+>
+
+<!ELEMENT log4j:properties (log4j:data*)>
+
+<!ELEMENT log4j:data EMPTY>
+<!ATTLIST log4j:data
+  name   CDATA	#REQUIRED
+  value  CDATA	#REQUIRED
+>
Index: applications/editors/josm/plugins/czechaddress/nbproject/project.xml
===================================================================
--- applications/editors/josm/plugins/czechaddress/nbproject/project.xml	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/nbproject/project.xml	(revision 15461)
@@ -46,9 +46,10 @@
                     <target>compile</target>
                 </action>
-                <action name="debug">
-                    <script>nbproject/ide-targets.xml</script>
-                    <target>debug-nb</target>
-                </action>
             </ide-actions>
+            <export>
+                <type>folder</type>
+                <location>build</location>
+                <build-target>compile</build-target>
+            </export>
             <view>
                 <items>
@@ -71,5 +72,4 @@
                     <ide-action name="javadoc"/>
                     <ide-action name="run"/>
-                    <ide-action name="debug"/>
                 </context-menu>
             </view>
@@ -80,4 +80,5 @@
                 <package-root>src</package-root>
                 <classpath mode="compile">../../core/build:../../core/src:tests/junit-4.5.jar</classpath>
+                <built-to>build</built-to>
                 <javadoc-built-to>doc</javadoc-built-to>
                 <source-level>1.5</source-level>
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/CzechAddressPlugin.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/CzechAddressPlugin.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/CzechAddressPlugin.java	(revision 15461)
@@ -27,5 +27,6 @@
 import org.openstreetmap.josm.plugins.czechaddress.actions.ModifierAction;
 import org.openstreetmap.josm.plugins.czechaddress.actions.SplitAreaByEmptyWayAction;
-import org.openstreetmap.josm.plugins.czechaddress.gui.DatabaseModifier;
+import org.openstreetmap.josm.plugins.czechaddress.gui.Inspector;
+import org.openstreetmap.josm.plugins.czechaddress.gui.Renamer;
 import org.openstreetmap.josm.plugins.czechaddress.gui.FactoryDialog;
 import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
@@ -46,10 +47,13 @@
             new ArrayList<AbstractButton>();
 
-    static private Reasoner mainReasoner = null;
-    static private Database mainDatabase = null;
+    static public Reasoner reasoner = null;
+    static public Database database = null;
 
-    public SelectionMonitor        selectionMonitor = null;
-    static public FactoryDialog    factoryDialog    = null;
-    static public ConflictResolver conflictResolver = null;
+    static public FactoryDialog     factoryDialog    = null;
+    static public ConflictResolver  conflictResolver = null;
+
+    static public Renamer   renamer  = null;
+    static public Inspector inspector = null;
+
 
     static private String pluginDir = null;
@@ -58,19 +62,19 @@
 
         pluginDir = getPluginDir();
+        addStatusListener(this);
 
-        factoryDialog    = FactoryDialog.getInstance();
+        factoryDialog    = new FactoryDialog();
         conflictResolver = new ConflictResolver();
 
-        addStatusListener(this);
-        addStatusListener(conflictResolver);
-
+        
         MainMenu.add(Main.main.menu.toolsMenu, new SplitAreaByEmptyWayAction());
 
+
         // Prepare for filling the database.
-        mainDatabase = new Database();
+        database = new Database();
         final MvcrParser parser = new MvcrParser();
         //parser.setFilter(null, null, null, "");
         //parser.setFilter("HUSTOPEČE", "HUSTOPEČE", null, null);
-        parser.setTargetDatabase(mainDatabase);
+        parser.setTargetDatabase(database);
         parser.setStorageDir(pluginDir);
 
@@ -80,5 +84,5 @@
             try {
                parser.fillDatabase();
-               broadcastStatusChanged(StatusListener.MESSAGE_DATABASE_LOADED);
+               broadcastStatusChange(StatusListener.MESSAGE_DATABASE_LOADED);
             } catch (DatabaseLoadException dle) {
                dle.printStackTrace();
@@ -95,19 +99,9 @@
     public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
 
-        super.mapFrameInitialized(oldFrame, newFrame);
-
         if (newFrame == null)
             return;
         
-        newFrame.addToggleDialog(FactoryDialog.getInstance());
+        newFrame.addToggleDialog(factoryDialog);
         newFrame.addMapMode(new IconToggleButton(new FactoryAction(newFrame)));
-    }
-
-    public static Reasoner getReasoner() {
-        return mainReasoner;
-    }
-
-    public static Database getDatabase() {
-        return mainDatabase;
     }
 
@@ -121,14 +115,14 @@
 
         // Update database according to the map
-        (new DatabaseModifier()).setVisible(true);
+        (new Renamer()).setVisible(true);
+        (new Inspector()).setVisible(true);
 
         // And add them to the reasoner.
-        mainReasoner = new Reasoner(pool);
-        mainReasoner.addPrimitives(Main.ds.allPrimitives());
+        reasoner = new Reasoner(pool);
+        reasoner.addPrimitives(Main.ds.allPrimitives());
     }
 
     static private ElementWithStreets location = null;
-
-    static public ElementWithStreets getLocation() {
+    static public  ElementWithStreets getLocation() {
         if (location == null)
             changeLocation();
@@ -142,27 +136,5 @@
         if (newLocation != null && newLocation != location) {
             location = newLocation;
-
-            /*
-            // Parse the database once more to get the streets and houses.
-            MvcrParser     parser   = new MvcrParser();
-            ParentResolver resolver = new ParentResolver(location);
-
-            parser.setFilter(resolver.parentRegion == null ? null : resolver.parentRegion.getName(),
-                             resolver.parentViToCi == null ? null : resolver.parentViToCi.getName(),
-                             resolver.parentSuburb == null ? null : resolver.parentSuburb.getName(),
-                             resolver.parentStreet == null ? null : resolver.parentStreet.getName());
-
-            parser.setTargetDatabase(mainDatabase);
-            parser.setStorageDir(pluginDir);
-            try {
-                parser.fillDatabase();
-            } catch (DatabaseLoadException dle) {
-               dle.printStackTrace();
-               System.err.println("CzechAddress: " +
-                            "Selhalo načtení databáze. A teď se budou dít divy...");
-            }*/
-
-            broadcastStatusChanged(StatusListener.MESSAGE_LOCATION_CHANGED);
-            initReasoner();
+            broadcastStatusChange(MESSAGE_LOCATION_CHANGED);
         }
     }
@@ -182,5 +154,5 @@
     }
 
-    static public void broadcastStatusChanged(int statusMessage) {
+    static public void broadcastStatusChange(int statusMessage) {
         for (StatusListener l : listeners)
             l.pluginStatusChanged(statusMessage);
@@ -188,5 +160,5 @@
 
     public void pluginStatusChanged(int message) {
-        if (message == StatusListener.MESSAGE_DATABASE_LOADED) {
+        if (message == MESSAGE_DATABASE_LOADED) {
             czechMenu = Main.main.menu.addMenu("Adresy", KeyEvent.VK_A, 4);
             menuItems.add(MainMenu.add(czechMenu, new PointManipulatorAction()));
@@ -198,4 +170,10 @@
         }
 
+        if (message == MESSAGE_LOCATION_CHANGED) {
+            initReasoner();
+            return;
+        }
+
+
         // SelectionMonitor cannot be used because of synchronization problems.
         /*if (message == MESSAGE_REASONER_REASONED) {
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StatusListener.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StatusListener.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StatusListener.java	(revision 15461)
@@ -3,5 +3,4 @@
 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Database;
-import org.openstreetmap.josm.plugins.czechaddress.parser.DatabaseParser;
 import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
 
@@ -67,5 +66,4 @@
      *
      * @see CzechAddressPlugin
-     * @see DatabaseParser
      * @see Database
      */
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StringUtils.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StringUtils.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StringUtils.java	(revision 15461)
@@ -43,6 +43,5 @@
 
     public static String latLonToString(LatLon position) {
-        assert position != null;
-        //if (position == null) return "";
+        if (position == null) return "";
 
         return "(lat: " + coordinateToString(position.lat())
@@ -83,3 +82,38 @@
     }
 
+    /**
+     * Capitalizes the given string (first letter of every word upper-case,
+     * others lower-case). Czech grammar rules are more or less obeyed.
+     *
+     * <p><b>TODO:</b> This should be moved somewhere else.</p>
+     *
+     * @param s string to be capitalized
+     * @return capitaized string
+     */
+    public static String capitalize(String s) {
+
+        if (s == null)
+            return s;
+
+        String result = "";
+
+        char last = ' ';
+        for (char ch : s.toCharArray()) {
+            if ((last >= 'a') && (last <= 'ž') ||
+                (last >= 'A') && (last <= 'Ž'))
+                ch = Character.toLowerCase(ch);
+            else
+                ch = Character.toTitleCase(ch);
+
+            last = ch;
+            result = result + ch;
+        }
+
+        String[] noCapitalize = { "Nad", "Pod", "U", "Na" };
+        for (String noc : noCapitalize)
+            result = result.replaceAll(" "+noc+" ", " "+noc.toLowerCase()+" ");
+
+        return result;
+    }
+
 }
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/FactoryAction.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/FactoryAction.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/FactoryAction.java	(revision 15461)
@@ -11,5 +11,4 @@
 import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;
 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House;
-import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
 import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalContainer;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -54,13 +53,12 @@
         Main.map.mapView.addMouseListener(this);
 
-        Reasoner r = CzechAddressPlugin.getReasoner();
-
-        if (r == null) {
+        if (CzechAddressPlugin.reasoner == null) {
             exitMode();
             return;
         }
 
-        FactoryDialog d = FactoryDialog.getInstance();
-        if (r.translate(d.getSelectedHouse()) != null)
+        // Switch to next unassigned house.
+        FactoryDialog d = CzechAddressPlugin.factoryDialog;
+        if (CzechAddressPlugin.reasoner.translate(d.getSelectedHouse()) != null)
             d.selectNextUnmatchedHouseByCheckBox();
     }
@@ -88,5 +86,5 @@
 
         // Get the currently selected House in the FactoryDialog.
-        House house = FactoryDialog.getInstance().getSelectedHouse();
+        House house = CzechAddressPlugin.factoryDialog.getSelectedHouse();
         if (house == null)
             return; // TODO: Some meaningful messageBox would be useful.
@@ -99,13 +97,10 @@
         container.applyAll();
 
-        // Notify reasoner about this newly added node.
-        CzechAddressPlugin.getReasoner().overwriteMatch(house, newNode);
-
         // And make the new node selected.
         Main.ds.addPrimitive(newNode);
         Main.ds.setSelected(newNode);
 
-        // And do not forget to select next House in the list.
-        FactoryDialog.getInstance().selectNextUnmatchedHouseByCheckBox();
+        CzechAddressPlugin.reasoner.overwriteMatch(house, newNode);
+        CzechAddressPlugin.factoryDialog.selectNextUnmatchedHouseByCheckBox();
     }
 }
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/ModifierAction.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/ModifierAction.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/ModifierAction.java	(revision 15461)
@@ -9,5 +9,5 @@
 import java.awt.event.KeyEvent;
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.plugins.czechaddress.gui.DatabaseModifier;
+import org.openstreetmap.josm.plugins.czechaddress.gui.Renamer;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -17,6 +17,4 @@
  */
 public class ModifierAction extends JosmAction {
-
-//    DatabaseModifier modifier = null;
 
     public ModifierAction() {
@@ -31,5 +29,5 @@
 
     public void actionPerformed(ActionEvent e) {
-        (new DatabaseModifier()).setVisible(true);
+        (new Renamer()).setVisible(true);
     }
 }
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/AddressElement.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/AddressElement.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/AddressElement.java	(revision 15461)
@@ -31,13 +31,9 @@
     /**
      * Constructor setting the name of this element.
-     *
-     * <p><b>TODO:</b> The name is capitalized during the assignment,
-     * because the database contains all names IN CAPITALS. However
-     * this should not be done here, but in the {@link DatabaseParser}.</p>
      */
     public AddressElement (String name) {
         if (name == null)
             throw new NullPointerException("You must specify the name of this AddressElement");
-        this.name = capitalize(name);
+        this.name = name;
     }
 
@@ -166,39 +162,4 @@
 
     /**
-     * Capitalizes the given string (first letter of every word upper-case,
-     * others lower-case). Czech grammar rules are more or less obeyed.
-     *
-     * <p><b>TODO:</b> This should be moved somewhere else.</p>
-     * 
-     * @param s string to be capitalized
-     * @return capitaized string
-     */
-    protected static String capitalize(String s) {
-
-        if (s == null)
-            return s;
-
-        String result = "";
-
-        char last = ' ';
-        for (char ch : s.toCharArray()) {
-            if ((last >= 'a') && (last <= 'ž') ||
-                (last >= 'A') && (last <= 'Ž'))
-                ch = Character.toLowerCase(ch);
-            else
-                ch = Character.toTitleCase(ch);
-
-            last = ch;
-            result = result + ch;
-        }
-
-        String[] noCapitalize = { "Nad", "Pod", "U", "Na" };
-        for (String noc : noCapitalize)
-            result = result.replaceAll(" "+noc+" ", " "+noc.toLowerCase()+" ");
-
-        return result;
-    }
-    
-    /**
      * Compute differences between two strings.
      *
@@ -248,4 +209,8 @@
     public List<Proposal> getDiff(OsmPrimitive prim) {
         return null;
+    }
+
+    public boolean isMatchable(OsmPrimitive prim) {
+        return false;
     }
 
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/House.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/House.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/House.java	(revision 15461)
@@ -204,4 +204,13 @@
     }
 
-
+    public boolean isMatchable(OsmPrimitive prim) {
+        
+        for (String key : prim.keySet()) {
+            String value = prim.get(key);
+            if (value != null && value.startsWith("addr:"))
+                return true;
+        }
+
+        return false;
+    }
 }
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/Region.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/Region.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/Region.java	(revision 15461)
@@ -69,6 +69,6 @@
     public Region(String name, String nuts3name, String nuts4name) {
         super(name);
-        if (nuts3name != null) this.nuts3name = capitalize(nuts3name);
-        if (nuts4name != null) this.nuts4name = capitalize(nuts4name);
+        if (nuts3name != null) this.nuts3name = nuts3name;
+        if (nuts4name != null) this.nuts4name = nuts4name;
     }
     
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/StringUtils.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/StringUtils.java	(revision 15412)
+++ 	(revision )
@@ -1,17 +1,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-package org.openstreetmap.josm.plugins.czechaddress.addressdatabase;
-
-import org.openstreetmap.josm.data.coor.LatLon;
-
-/**
- *
- * @author radek
- */
-public class StringUtils {
-
-
-}
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/ConflictResolver.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/ConflictResolver.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/ConflictResolver.java	(revision 15461)
@@ -258,5 +258,5 @@
              if (best != null) best.qualityChanged();
 
-             List<Match> competitors = r.getConflicts((OsmPrimitive) selMainObj);
+             List<Match> competitors = r.conflicts((OsmPrimitive) selMainObj);
              if (competitors != null) for (Match competitor : competitors)
                  competitor.qualityChanged();
@@ -271,5 +271,5 @@
             if (best != null) best.qualityChanged();
 
-            List<Match> competitors = r.getConflicts((AddressElement) selMainObj);
+            List<Match> competitors = r.conflicts((AddressElement) selMainObj);
             if (competitors != null) for (Match competitor : competitors)
                  competitor.qualityChanged();
@@ -333,5 +333,5 @@
 
                 if (parent instanceof AddressElement)
-                    return r.getConflicts((AddressElement) parent).get(index).prim;
+                    return r.conflicts((AddressElement) parent).get(index).prim;
 
             } catch (Exception e) {  }
@@ -347,5 +347,5 @@
 
                 if (parent instanceof AddressElement)
-                    return r.getConflicts((AddressElement) parent).size();
+                    return r.conflicts((AddressElement) parent).size();
                 
             } catch (Exception exp) { }
@@ -361,5 +361,5 @@
 
                 if (parent instanceof AddressElement)
-                    return r.getConflicts((AddressElement) parent).indexOf(child);
+                    return r.conflicts((AddressElement) parent).indexOf(child);
                 
             } catch (Exception exp) { }
@@ -383,5 +383,5 @@
 
                 if (parent instanceof OsmPrimitive)
-                    return r.getConflicts((OsmPrimitive) parent).get(index).elem;
+                    return r.getConflictsconflictsve) parent).get(index).elem;
                 
             } catch (Exception exp) { }
@@ -397,5 +397,5 @@
                     return r.getPrimitivesInConflict().size();
                 if (parent instanceof OsmPrimitive)
-                    return r.getConflicts((OsmPrimitive) parent).size();
+                    return r.getConflictsconflictsve) parent).size();
 
             } catch (Exception exp) { }
@@ -412,5 +412,5 @@
 
                 } else if (parent instanceof OsmPrimitive)
-                    return r.getConflicts((OsmPrimitive) parent).indexOf(child);
+                    return r.getConflictsconflictsve) parent).indexOf(child);
                 
             } catch (Exception exp) { }
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/DatabaseModifier.form
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/DatabaseModifier.form	(revision 15412)
+++ 	(revision )
@@ -1,99 +1,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
-  <Properties>
-    <Property name="defaultCloseOperation" type="int" value="2"/>
-  </Properties>
-  <SyntheticProperties>
-    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
-  </SyntheticProperties>
-  <AuxValues>
-    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
-    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
-    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
-    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
-    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
-    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,58,0,0,1,-36"/>
-  </AuxValues>
-
-  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
-    <Property name="columns" type="int" value="0"/>
-    <Property name="rows" type="int" value="1"/>
-  </Layout>
-  <SubComponents>
-    <Container class="javax.swing.JPanel" name="mainPanel">
-
-      <Layout>
-        <DimensionLayout dim="0">
-          <Group type="103" groupAlignment="0" attributes="0">
-              <Component id="tabbedPane" alignment="0" pref="476" max="32767" attributes="0"/>
-          </Group>
-        </DimensionLayout>
-        <DimensionLayout dim="1">
-          <Group type="103" groupAlignment="0" attributes="0">
-              <Group type="102" alignment="0" attributes="0">
-                  <Component id="tabbedPane" min="-2" pref="289" max="-2" attributes="0"/>
-                  <EmptySpace pref="25" max="32767" attributes="0"/>
-              </Group>
-          </Group>
-        </DimensionLayout>
-      </Layout>
-      <SubComponents>
-        <Container class="javax.swing.JTabbedPane" name="tabbedPane">
-
-          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
-          <SubComponents>
-            <Container class="javax.swing.JScrollPane" name="streetScrollPane">
-              <AuxValues>
-                <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
-              </AuxValues>
-              <Constraints>
-                <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
-                  <JTabbedPaneConstraints tabName="Ulice">
-                    <Property name="tabTitle" type="java.lang.String" value="Ulice"/>
-                  </JTabbedPaneConstraints>
-                </Constraint>
-              </Constraints>
-
-              <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
-              <SubComponents>
-                <Component class="javax.swing.JTable" name="streetTable">
-                  <Properties>
-                    <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
-                      <Table columnCount="2" rowCount="4">
-                        <Column editable="false" title="P&#x16f;vodn&#xed; n&#xe1;zev" type="java.lang.Object"/>
-                        <Column editable="true" title="N&#xe1;vrh z mapy" type="java.lang.String"/>
-                      </Table>
-                    </Property>
-                    <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
-                      <TableColumnModel selectionModel="2">
-                        <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
-                          <Title/>
-                          <Editor/>
-                          <Renderer/>
-                        </Column>
-                        <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="false">
-                          <Title/>
-                          <Editor/>
-                          <Renderer/>
-                        </Column>
-                      </TableColumnModel>
-                    </Property>
-                    <Property name="columnSelectionAllowed" type="boolean" value="true"/>
-                    <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
-                      <TableHeader reorderingAllowed="true" resizingAllowed="true"/>
-                    </Property>
-                  </Properties>
-                </Component>
-              </SubComponents>
-            </Container>
-          </SubComponents>
-        </Container>
-      </SubComponents>
-    </Container>
-  </SubComponents>
-</Form>
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/DatabaseModifier.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/DatabaseModifier.java	(revision 15412)
+++ 	(revision )
@@ -1,222 +1,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-
-/*
- * DatabaseModifier.java
- *
- * Created on 24.5.2009, 18:03:35
- */
-
-package org.openstreetmap.josm.plugins.czechaddress.gui;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.util.ArrayList;
-import java.util.List;
-import javax.swing.JTable;
-import javax.swing.event.TableModelListener;
-import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.TableModel;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.ExtendedDialog;
-import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;
-import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
-import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
-import org.openstreetmap.josm.plugins.czechaddress.intelligence.Capitalizator;
-
-/**
- *
- * @author radek
- */
-public class DatabaseModifier extends ExtendedDialog {
-
-    StreetModel<Street> streetModel = new StreetModel<Street>();
-
-    /** Creates new form DatabaseModifier */
-    public DatabaseModifier() {
-
-        super(Main.parent, "Upravit databázi",
-                                      new String[] { "OK", "Zrušit"}, true);
-        initComponents();
-
-        Capitalizator cap = new Capitalizator(
-                                Main.ds.allPrimitives(),
-                                CzechAddressPlugin.getLocation().getStreets());
-
-        for (Street capStreet : cap.getCapitalised()) {
-            assert cap.translate(capStreet).get("name") != null : capStreet;
-
-            String elemName = capStreet.getName();
-            String primName = cap.translate(capStreet).get("name");
-
-            if (!elemName.equals(primName)) {
-                streetModel.elems.add(capStreet);
-                streetModel.names.add(primName);
-            }
-        }
-
-        streetTable.setModel(streetModel);
-        streetTable.setDefaultRenderer( AddressElement.class,
-                                        new AddressElementRenderer());
-
-        // And finalize initializing the form.
-        setupDialog(mainPanel, new String[] { "ok.png", "cancel.png" });
-    }
-
-    @Override
-    protected void buttonAction(ActionEvent evt) {
-        super.buttonAction(evt);
-
-        if (getValue() == 1) {
-            assert streetModel.elems.size() == streetModel.names.size();
-            
-            for(int i=0; i<streetModel.elems.size(); i++)
-                streetModel.elems.get(i).setName(streetModel.names.get(i));
-        }
-
-        setVisible(false);
-    }
-
-    /** This method is called from within the constructor to
-     * initialize the form.
-     * WARNING: Do NOT modify this code. The content of this method is
-     * always regenerated by the Form Editor.
-     */
-    @SuppressWarnings("unchecked")
-    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
-    private void initComponents() {
-
-        mainPanel = new javax.swing.JPanel();
-        tabbedPane = new javax.swing.JTabbedPane();
-        streetScrollPane = new javax.swing.JScrollPane();
-        streetTable = new javax.swing.JTable();
-
-        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
-        getContentPane().setLayout(new java.awt.GridLayout(1, 0));
-
-        streetTable.setModel(new javax.swing.table.DefaultTableModel(
-            new Object [][] {
-                {null, null},
-                {null, null},
-                {null, null},
-                {null, null}
-            },
-            new String [] {
-                "Původní název", "Návrh z mapy"
-            }
-        ) {
-            Class[] types = new Class [] {
-                java.lang.Object.class, java.lang.String.class
-            };
-            boolean[] canEdit = new boolean [] {
-                false, true
-            };
-
-            public Class getColumnClass(int columnIndex) {
-                return types [columnIndex];
-            }
-
-            public boolean isCellEditable(int rowIndex, int columnIndex) {
-                return canEdit [columnIndex];
-            }
-        });
-        streetTable.setColumnSelectionAllowed(true);
-        streetScrollPane.setViewportView(streetTable);
-        streetTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
-        streetTable.getColumnModel().getColumn(1).setResizable(false);
-
-        tabbedPane.addTab("Ulice", streetScrollPane);
-
-        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
-        mainPanel.setLayout(mainPanelLayout);
-        mainPanelLayout.setHorizontalGroup(
-            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)
-        );
-        mainPanelLayout.setVerticalGroup(
-            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(mainPanelLayout.createSequentialGroup()
-                .addComponent(tabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 289, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addContainerGap(25, Short.MAX_VALUE))
-        );
-
-        getContentPane().add(mainPanel);
-
-        pack();
-    }// </editor-fold>//GEN-END:initComponents
-
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    private javax.swing.JPanel mainPanel;
-    private javax.swing.JScrollPane streetScrollPane;
-    private javax.swing.JTable streetTable;
-    private javax.swing.JTabbedPane tabbedPane;
-    // End of variables declaration//GEN-END:variables
-
-    private class AddressElementRenderer extends DefaultTableCellRenderer {
-
-        public AddressElementRenderer() {}
-
-        @Override
-        protected void setValue(Object value) {
-            super.setValue(value);
-
-            if (value instanceof AddressElement)
-                setText(((AddressElement) value).getName() );
-        }
-    }
-
-    private class StreetModel<Element> implements TableModel {
-
-        List<Element> elems = new ArrayList<Element>();
-        List<String>  names = new ArrayList<String>();
-
-        public int getRowCount() {
-            assert elems.size() == names.size();
-            return elems.size();
-        }
-
-        public int getColumnCount() {
-            return 2;
-        }
-
-        public String getColumnName(int columnIndex) {
-            if (columnIndex == 0) return "Původní název";
-            if (columnIndex == 1) return "Navržený název";
-            assert false : columnIndex;
-            return null;
-        }
-
-        public Class<?> getColumnClass(int columnIndex) {
-            if (columnIndex == 0) return AddressElement.class;
-            if (columnIndex == 1) return String.class;
-            assert false : columnIndex;
-            return null;
-        }
-
-        public boolean isCellEditable(int rowIndex, int columnIndex) {
-            return columnIndex == 1;
-        }
-
-        public Object getValueAt(int rowIndex, int columnIndex) {
-            if (columnIndex == 0) return elems.get(rowIndex);
-            if (columnIndex == 1) return names.get(rowIndex);
-            assert false : columnIndex;
-            return null;
-        }
-
-        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
-            assert columnIndex == 1;
-            names.set(rowIndex, (String) aValue);
-        }
-
-        public void addTableModelListener(TableModelListener l) {
-            
-        }
-
-        public void removeTableModelListener(TableModelListener l) {
-            
-        }
-    }
-}
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.form
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.form	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.form	(revision 15461)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
-<Form version="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
@@ -26,5 +26,5 @@
           <Group type="103" groupAlignment="0" attributes="0">
               <Group type="102" attributes="0">
-                  <Component id="streetComboBox" pref="50" max="32767" attributes="0"/>
+                  <Component id="streetComboBox" pref="92" max="32767" attributes="0"/>
                   <EmptySpace max="-2" attributes="0"/>
                   <Component id="relocateButton" min="-2" max="-2" attributes="0"/>
@@ -33,5 +33,5 @@
               </Group>
               <Group type="102" alignment="0" attributes="0">
-                  <Component id="keepOddityCheckBox" pref="282" max="32767" attributes="0"/>
+                  <Component id="keepOddityCheckBox" pref="278" max="32767" attributes="0"/>
                   <EmptySpace max="-2" attributes="0"/>
               </Group>
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.java	(revision 15461)
@@ -37,12 +37,4 @@
         implements SelectionChangedListener, StatusListener {
 
-    private static FactoryDialog singleton = null;
-    public static FactoryDialog getInstance() {
-        if (singleton == null)
-            singleton = new FactoryDialog();
-        return singleton;
-    }
-
-
     HouseListModel  houseModel  = new HouseListModel();
     StreetListModel streetModel = new StreetListModel();
@@ -65,5 +57,5 @@
         add(mainPanel);
 
-        // Register to all listeners
+        // Register to all messages
         CzechAddressPlugin.addStatusListener(this);
 
@@ -94,5 +86,4 @@
             keepOddityCheckBox.setEnabled(true);
             return;
-
         }
         
@@ -115,5 +106,5 @@
 
     public boolean existsAvailableHouse() {
-        Reasoner r = CzechAddressPlugin.getReasoner();
+        Reasoner r = CzechAddressPlugin.reasoner;
 
         int i = houseList.getSelectedIndex();
@@ -136,5 +127,4 @@
     public void selectNextUnmatchedHouse() {
 
-        Reasoner r = CzechAddressPlugin.getReasoner();
         int index = houseList.getSelectedIndex();
 
@@ -142,5 +132,5 @@
         Object current;
         while ( (current = houseModel.getElementAt(index)) != null
-                && r.translate((House) current) != null)
+              && CzechAddressPlugin.reasoner.translate((House) current) != null)
             index++;
 
@@ -326,5 +316,5 @@
     private void houseListClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_houseListClicked
         if (evt.getClickCount() == 2 && evt.getButton() == MouseEvent.BUTTON1) {
-            Reasoner r = CzechAddressPlugin.getReasoner();
+            Reasoner r = CzechAddressPlugin.reasoner;
 
             if (r.translate(getSelectedHouse()) != null) {
@@ -347,5 +337,5 @@
 
     private void ensureConsistencyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ensureConsistencyButtonActionPerformed
-        CzechAddressPlugin.getReasoner().ensureConsistency();
+        CzechAddressPlugin.reasoner.ensureConsistency();
 }//GEN-LAST:event_ensureConsistencyButtonActionPerformed
 
@@ -405,5 +395,5 @@
             if (boldFont == null) boldFont = getFont().deriveFont(Font.BOLD);
 
-            Reasoner r = CzechAddressPlugin.getReasoner();
+            Reasoner r = CzechAddressPlugin.reasoner;
 
             if (value instanceof House) {
@@ -413,5 +403,5 @@
                 setFont(plainFont);
 
-                if ( r.getConflicts(house) != null)
+                if ( r.conflicts(house) != null)
                     setIcon(envelopeExclIcon);
                 else if ( r.translate(house) == null) {
@@ -457,5 +447,5 @@
 
         public void rebuild() {
-            Reasoner r = CzechAddressPlugin.getReasoner();
+            Reasoner r = CzechAddressPlugin.reasoner;
             if (r == null) return;
 
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/PointManipulatorDialog.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/PointManipulatorDialog.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/PointManipulatorDialog.java	(revision 15461)
@@ -368,5 +368,5 @@
                 if (match.elem instanceof House) {
                     setIcon(envelopeStarIcon);
-                    if ( r.getConflicts(match.elem) != null )
+                    if ( r.conflicts(match.elem) != null )
                         setIcon(envelopeExclIcon);
                     else if ( r.translate(match.elem) != null)
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.form
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.form	(revision 15461)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.form	(revision 15461)
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,58,0,0,1,-36"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridLayout">
+    <Property name="columns" type="int" value="0"/>
+    <Property name="rows" type="int" value="1"/>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="mainPanel">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Component id="tabbedPane" alignment="0" pref="476" max="32767" attributes="0"/>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <Component id="tabbedPane" min="-2" pref="289" max="-2" attributes="0"/>
+                  <EmptySpace pref="25" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Container class="javax.swing.JTabbedPane" name="tabbedPane">
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
+          <SubComponents>
+            <Container class="javax.swing.JScrollPane" name="streetScrollPane">
+              <AuxValues>
+                <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+              </AuxValues>
+              <Constraints>
+                <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout$JTabbedPaneConstraintsDescription">
+                  <JTabbedPaneConstraints tabName="Ulice">
+                    <Property name="tabTitle" type="java.lang.String" value="Ulice"/>
+                  </JTabbedPaneConstraints>
+                </Constraint>
+              </Constraints>
+
+              <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+              <SubComponents>
+                <Component class="javax.swing.JTable" name="streetTable">
+                  <Properties>
+                    <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
+                      <Table columnCount="2" rowCount="4">
+                        <Column editable="false" title="P&#x16f;vodn&#xed; n&#xe1;zev" type="java.lang.Object"/>
+                        <Column editable="true" title="N&#xe1;vrh z mapy" type="java.lang.String"/>
+                      </Table>
+                    </Property>
+                    <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
+                      <TableColumnModel selectionModel="2">
+                        <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
+                          <Title/>
+                          <Editor/>
+                          <Renderer/>
+                        </Column>
+                        <Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="false">
+                          <Title/>
+                          <Editor/>
+                          <Renderer/>
+                        </Column>
+                      </TableColumnModel>
+                    </Property>
+                    <Property name="columnSelectionAllowed" type="boolean" value="true"/>
+                    <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
+                      <TableHeader reorderingAllowed="true" resizingAllowed="true"/>
+                    </Property>
+                  </Properties>
+                </Component>
+              </SubComponents>
+            </Container>
+          </SubComponents>
+        </Container>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.java	(revision 15461)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.java	(revision 15461)
@@ -0,0 +1,222 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/*
+ * Renamer.java
+ *
+ * Created on 24.5.2009, 18:03:35
+ */
+
+package org.openstreetmap.josm.plugins.czechaddress.gui;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.JTable;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableModel;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
+import org.openstreetmap.josm.plugins.czechaddress.intelligence.Capitalizator;
+
+/**
+ *
+ * @author radek
+ */
+public class Renamer extends ExtendedDialog {
+
+    StreetModel<Street> streetModel = new StreetModel<Street>();
+
+    /** Creates new form Renamer */
+    public Renamer() {
+
+        super(Main.parent, "Upravit databázi",
+                                      new String[] { "OK", "Zrušit"}, true);
+        initComponents();
+
+        Capitalizator cap = new Capitalizator(
+                                Main.ds.allPrimitives(),
+                                CzechAddressPlugin.getLocation().getStreets());
+
+        for (Street capStreet : cap.getCapitalised()) {
+            assert cap.translate(capStreet).get("name") != null : capStreet;
+
+            String elemName = capStreet.getName();
+            String primName = cap.translate(capStreet).get("name");
+
+            if (!elemName.equals(primName)) {
+                streetModel.elems.add(capStreet);
+                streetModel.names.add(primName);
+            }
+        }
+
+        streetTable.setModel(streetModel);
+        streetTable.setDefaultRenderer( AddressElement.class,
+                                        new AddressElementRenderer());
+
+        // And finalize initializing the form.
+        setupDialog(mainPanel, new String[] { "ok.png", "cancel.png" });
+    }
+
+    @Override
+    protected void buttonAction(ActionEvent evt) {
+        super.buttonAction(evt);
+
+        if (getValue() == 1) {
+            assert streetModel.elems.size() == streetModel.names.size();
+            
+            for(int i=0; i<streetModel.elems.size(); i++)
+                streetModel.elems.get(i).setName(streetModel.names.get(i));
+        }
+
+        setVisible(false);
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        mainPanel = new javax.swing.JPanel();
+        tabbedPane = new javax.swing.JTabbedPane();
+        streetScrollPane = new javax.swing.JScrollPane();
+        streetTable = new javax.swing.JTable();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+        getContentPane().setLayout(new java.awt.GridLayout(1, 0));
+
+        streetTable.setModel(new javax.swing.table.DefaultTableModel(
+            new Object [][] {
+                {null, null},
+                {null, null},
+                {null, null},
+                {null, null}
+            },
+            new String [] {
+                "Původní název", "Návrh z mapy"
+            }
+        ) {
+            Class[] types = new Class [] {
+                java.lang.Object.class, java.lang.String.class
+            };
+            boolean[] canEdit = new boolean [] {
+                false, true
+            };
+
+            public Class getColumnClass(int columnIndex) {
+                return types [columnIndex];
+            }
+
+            public boolean isCellEditable(int rowIndex, int columnIndex) {
+                return canEdit [columnIndex];
+            }
+        });
+        streetTable.setColumnSelectionAllowed(true);
+        streetScrollPane.setViewportView(streetTable);
+        streetTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+        streetTable.getColumnModel().getColumn(1).setResizable(false);
+
+        tabbedPane.addTab("Ulice", streetScrollPane);
+
+        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
+        mainPanel.setLayout(mainPanelLayout);
+        mainPanelLayout.setHorizontalGroup(
+            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(tabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)
+        );
+        mainPanelLayout.setVerticalGroup(
+            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(mainPanelLayout.createSequentialGroup()
+                .addComponent(tabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 289, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(25, Short.MAX_VALUE))
+        );
+
+        getContentPane().add(mainPanel);
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JPanel mainPanel;
+    private javax.swing.JScrollPane streetScrollPane;
+    private javax.swing.JTable streetTable;
+    private javax.swing.JTabbedPane tabbedPane;
+    // End of variables declaration//GEN-END:variables
+
+    private class AddressElementRenderer extends DefaultTableCellRenderer {
+
+        public AddressElementRenderer() {}
+
+        @Override
+        protected void setValue(Object value) {
+            super.setValue(value);
+
+            if (value instanceof AddressElement)
+                setText(((AddressElement) value).getName() );
+        }
+    }
+
+    private class StreetModel<Element> implements TableModel {
+
+        List<Element> elems = new ArrayList<Element>();
+        List<String>  names = new ArrayList<String>();
+
+        public int getRowCount() {
+            assert elems.size() == names.size();
+            return elems.size();
+        }
+
+        public int getColumnCount() {
+            return 2;
+        }
+
+        public String getColumnName(int columnIndex) {
+            if (columnIndex == 0) return "Původní název";
+            if (columnIndex == 1) return "Navržený název";
+            assert false : columnIndex;
+            return null;
+        }
+
+        public Class<?> getColumnClass(int columnIndex) {
+            if (columnIndex == 0) return AddressElement.class;
+            if (columnIndex == 1) return String.class;
+            assert false : columnIndex;
+            return null;
+        }
+
+        public boolean isCellEditable(int rowIndex, int columnIndex) {
+            return columnIndex == 1;
+        }
+
+        public Object getValueAt(int rowIndex, int columnIndex) {
+            if (columnIndex == 0) return elems.get(rowIndex);
+            if (columnIndex == 1) return names.get(rowIndex);
+            assert false : columnIndex;
+            return null;
+        }
+
+        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+            assert columnIndex == 1;
+            names.set(rowIndex, (String) aValue);
+        }
+
+        public void addTableModelListener(TableModelListener l) {
+            
+        }
+
+        public void removeTableModelListener(TableModelListener l) {
+            
+        }
+    }
+}
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/UniversalTreeRenderer.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/UniversalTreeRenderer.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/UniversalTreeRenderer.java	(revision 15461)
@@ -65,9 +65,9 @@
 
 
-        if (value instanceof House) {
+        if (value instanceof House && r != null) {
             House house = (House) value;
 
             setIcon(envelopeNormIcon);
-            if ( r.getConflicts(house) != null )
+            if ( r.conflicts(house) != null )
                 setIcon(envelopeExclIcon);
             else if ( r.translate(house) == null)
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Match.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Match.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Match.java	(revision 15461)
@@ -2,5 +2,6 @@
 
 import java.util.List;
-import org.openstreetmap.josm.data.osm.Node;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
@@ -20,9 +21,10 @@
     public static final int MATCH_NOMATCH   = 0;
     
-    public int quality;
+    public int qVal;
     public OsmPrimitive prim;
     public AddressElement elem;
 
     public String checkSum;
+    public static Logger logger = Logger.getLogger("Match");
 
     public Match(AddressElement element, OsmPrimitive primitive,
@@ -30,17 +32,10 @@
         
         assert primitive != null;
-        assert element != null;
-        assert qualityFactor <= MATCH_OVERWRITE;
-        assert qualityFactor > MATCH_NOMATCH
-             : "MATCH_NOMATCH represents no relation."
-             + "It's pointless to waste memory for it.";
-
+        assert element   != null;
         assert !primitive.deleted;
 
         prim = primitive;
         elem = element;
-        quality = qualityFactor;
-
-        checkSum = toString();
+        qVal = qualityFactor;
     }
 
@@ -53,4 +48,8 @@
 
         int quality = element.getMatchQuality(primitive);
+
+        logger.log(Level.FINE, "asked to create match",
+                               new Object[] {element, primitive, quality});
+
         if (quality > MATCH_NOMATCH)
             return new Match(element, primitive, quality);
@@ -58,28 +57,30 @@
         return null;
     }
+/*
+    public boolean setQ(int desiredQ) {
+        int oldQ = evalQ();
+        qVal = desiredQ;
+        int newQ = evalQ();
 
-    public boolean qualityChanged() {
-        int newQuality
-        = prim.deleted ? MATCH_NOMATCH
-                       : quality == MATCH_OVERWRITE ? MATCH_OVERWRITE
-                                                    : elem.getMatchQuality(prim);
-        if (prim instanceof Node) {
-            Node node = (Node) prim;
-            if (node.coor == null || node.eastNorth == null) {
-                newQuality = MATCH_NOMATCH;
-                System.out.println("Suspicious node, ignoring it: " + AddressElement.getName(node));
-            }
-        }
-            
+        if (oldQ != newQ)
+            logger.log(Level.INFO, "changing match value: " + oldQ + " --> " + newQ
+                                 + " (desired value is " + desiredQ + ")", this);
+        return oldQ != evalQ();
+    }
+*/
+    public static int evalQ(OsmPrimitive prim, AddressElement elem, Integer oldQ) {
         
-        boolean difference = newQuality != quality;
-        quality = newQuality;
+        if (prim.deleted)
+            return MATCH_NOMATCH;
 
-        return difference;
+        if (oldQ == MATCH_OVERWRITE)
+            return MATCH_OVERWRITE;
+
+        return elem.getMatchQuality(prim);
     }
 
     @Override
     public String toString() {
-        return "{Match: q=" + String.valueOf(quality)
+        return "{Match: q=" + String.valueOf(qVal)
                    + "; elem='" + elem.toString()
                    +"'; prim='" + AddressElement.getName(prim) + "'}";
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Reasoner.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Reasoner.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Reasoner.java	(revision 15461)
@@ -1,16 +1,17 @@
 package org.openstreetmap.josm.plugins.czechaddress.intelligence;
 
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.FileHandler;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;
-import org.openstreetmap.josm.plugins.czechaddress.NotNullList;
-import org.openstreetmap.josm.plugins.czechaddress.StatusListener;
 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House;
-import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalContainer;
-import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalDatabase;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
 
 /**
@@ -34,657 +35,342 @@
 public class Reasoner {
 
-    /** A database of all matches, which are not in a conflict. */
-    private NotNullList<Match> matches = new NotNullList<Match>();
-
-    /** A list of {@link Match}es, which are in a conflict. */
-    private NotNullList<Match> conflicts = new NotNullList<Match>();
-
-    /** A list of {@link House}s, which have not yet been matched to any
-     * {@link OsmPrimitive} without a conflict. */
-    private ArrayList<AddressElement> elemPool = new ArrayList<AddressElement>();
-
-    /** A list of {@link OsmPrimitive}s, for which there was no suitable match. */
-    private List<OsmPrimitive> notMatchable = new ArrayList<OsmPrimitive>();
-
-    private HashMap<OsmPrimitive,   Match> primMatchHashIndex
-      = new HashMap<OsmPrimitive,   Match>();
-    private HashMap<AddressElement, Match> elemMatchHashIndex
-      = new HashMap<AddressElement, Match>();
-
-    private List<OsmPrimitive>   primConflictListIndex = new ArrayList<OsmPrimitive>();
-    private List<AddressElement> elemConflictListIndex = new ArrayList<AddressElement>();
-    private HashMap<OsmPrimitive,   List<Match>> primConflictHashIndex
-      = new HashMap<OsmPrimitive,   List<Match>>();
-    private HashMap<AddressElement, List<Match>> elemConflictHashIndex
-      = new HashMap<AddressElement, List<Match>>();
-
-
-    /**
-     * Default constructor, which initializes the pool of
-     * {@link AddressElement}s to be used for matching.
-     */
-    public Reasoner(ArrayList<AddressElement> elementPool) {
-        elemPool = elementPool;
-    }    
-    
-    /**
-     * Adds a single new primitive to the database, finds corresponding
-     * {@link House} for it and seeks for potential conflicts.
-     * 
-     * <p>If you intend to add a list of new primitives, {@link addPrimitives}
-     * will be faster, because conflicts are traced after adding all the
-     * primitives and not after every single one.</p>
-     *
-     * <p>Moreover there is one substantial difference discussed in
-     * {@link addPrimitives()}.</p>
-     *
-     * @param newPrimitive new primitive to be added
-     */
-    public synchronized void addPrimitive(OsmPrimitive newPrimitive) {
-
-        int firstNewIndex = matches.size();
-
-        matchPrimitive(newPrimitive);
+    /* A list of {@link OsmPrimitive}s, for which there was no suitable match. */
+    //private List<OsmPrimitive> notMatchable = new ArrayList<OsmPrimitive>();
+
+    private     Map<OsmPrimitive, AddressElement> primBestIndex
+      = new HashMap<OsmPrimitive, AddressElement> ();
+    private     Map<AddressElement, OsmPrimitive> elemBestIndex
+      = new HashMap<AddressElement, OsmPrimitive> ();
+
+    private     Map<OsmPrimitive,   Map<AddressElement, Integer>> primMatchIndex
+      = new HashMap<OsmPrimitive,   Map<AddressElement, Integer>> ();
+    private     Map<AddressElement, Map<OsmPrimitive,   Integer>> elemMatchIndex
+      = new HashMap<AddressElement, Map<OsmPrimitive,   Integer>> ();
+
+    private Set<OsmPrimitive>   primToUpdate = new HashSet<OsmPrimitive>();
+    private Set<AddressElement> elemToUpdate = new HashSet<AddressElement>();
+//  private Map<Object,Integer> statusBefore = new HashMap<Object,Integer>();
+
+    public Logger logger = Logger.getLogger("Reasoner");
+
+    public static final int STATUS_UNKNOWN = 0;
+    public static final int STATUS_CONFLICT = 1;
+    public static final int STATUS_MATCH = 2;
+
+    private Reasoner() {}
+    private static Reasoner singleton = null;
+    public  static Reasoner getInstance() {
+        if (singleton == null)
+            singleton = new Reasoner();
+        return singleton;
+    }
+
+    public void reset() {
+        primToUpdate.clear();
+        elemToUpdate.clear();
+
+        primMatchIndex.clear();
+        elemMatchIndex.clear();
+        primBestIndex.clear();
+        primBestIndex.clear();
+    }
+
+    private AddressElement getBest(OsmPrimitive prim) {
+
+        Map<AddressElement, Integer> matches = primMatchIndex.get(prim);
+        if (matches == null) return null;
+
+        AddressElement bestE = null;
+        int bestQ = Match.MATCH_NOMATCH;
+
+        for (AddressElement elem : matches.keySet()) {
+            if (matches.get(elem) == bestQ)
+                bestE = null;
+
+            if (matches.get(elem) > bestQ) {
+                bestQ = matches.get(elem);
+                bestE = elem;
+            }
+        }
+
+        return bestE;
+    }
+
+    private OsmPrimitive getBest(AddressElement prim) {
+
+        Map<OsmPrimitive, Integer> matches = elemMatchIndex.get(prim);
+        if (matches == null) return null;
+
+        OsmPrimitive bestE = null;
+        int bestQ = Match.MATCH_NOMATCH;
+
+        for (OsmPrimitive elem : matches.keySet()) {
+            if (matches.get(elem) == bestQ)
+                bestE = null;
+
+            if (matches.get(elem) > bestQ) {
+                bestQ = matches.get(elem);
+                bestE = elem;
+            }
+        }
+
+        return bestE;
+    }
+
+    public void openTransaction() {
+        assert primToUpdate.size() == 0;
+        assert elemToUpdate.size() == 0;
+    }
+
+    public void closeTransaction() {
+
+        Set<Object> changes = new HashSet<Object>();
+
+        for (OsmPrimitive prim : primToUpdate) {
+            AddressElement bestMatch = getBest(prim);
+
+            if (primBestIndex.get(prim) != bestMatch) {
+                if (bestMatch == null) {
+                    logger.log(Level.INFO, "primitive has no longer best match",
+                            AddressElement.getName(prim));
+                    primBestIndex.remove(prim);
+                } else {
+                    logger.log(Level.INFO, "primitive has a new best match",
+                            "prim=„" + AddressElement.getName(prim) + "“ → " +
+                            "elem=„" + bestMatch + "“");
+                    primBestIndex.put(prim, bestMatch);
+                }
+                changes.add(prim);
+            }
+        }
+        primToUpdate.clear();
+
+
+        for (AddressElement elem : elemToUpdate) {
+            OsmPrimitive bestMatch = getBest(elem);
+
+            if (elemBestIndex.get(elem) != bestMatch) {
+                if (bestMatch == null) {
+                    logger.log(Level.INFO, "element has no longer best match", elem);
+                    elemBestIndex.remove(elem);
+                } else {
+                    logger.log(Level.INFO, "element has a new best match",
+                            "elem=„" + elem + "“ → " +
+                            "prim=„" + AddressElement.getName(bestMatch) + "“");
+                    elemBestIndex.put(elem, bestMatch);
+                }
+                changes.add(elem);
+            }
+        }
+        elemToUpdate.clear();
+
+        for (Object change : changes) {
+            if (change instanceof OsmPrimitive)
+                for (ReasonerListener listener : listeners)
+                    listener.primitiveChanged((OsmPrimitive) change);
+
+            if (change instanceof AddressElement)
+                for (ReasonerListener listener : listeners)
+                    listener.elementChanged((AddressElement) change);
+        }
+    }
+
+    private Set<ReasonerListener> listeners = new HashSet<ReasonerListener>();
+
+    public void reconsider(OsmPrimitive prim, AddressElement elem) {
+
+        int oldQ = getQ(prim, elem);
+        int newQ = Match.evalQ(prim, elem, oldQ);
+
+        if (oldQ != newQ) {
+            logger.log(Level.INFO, "reconsidering match",
+                    "q=" + String.valueOf(oldQ) + "→" + String.valueOf(newQ) + "; " +
+                    "elem=„" + elem + "“; " +
+                    "prim=„" + AddressElement.getName(prim) + "“");
+            putQ(prim, elem, newQ);
+
+            primToUpdate.add(prim);
+            elemToUpdate.add(elem);
+        }
+    }
+
+    public void consider(OsmPrimitive prim) {
+        logger.log(Level.FINE, "considering primitive", AddressElement.getName(prim));
+
+        Map<AddressElement, Integer> matches = primMatchIndex.get(prim);
+        if (matches == null) {
+            logger.log(Level.INFO, "new primitive detected", AddressElement.getName(prim));
+            matches = new HashMap<AddressElement, Integer>();
+            primMatchIndex.put(prim, matches);
+        }
+
+        for (AddressElement elem : elemMatchIndex.keySet())
+            reconsider(prim, elem);
+    }
+
+    public void consider(AddressElement elem) {
+        logger.log(Level.FINE, "considering element", elem);
+
+        Map<OsmPrimitive, Integer> matches = elemMatchIndex.get(elem);
+        if (matches == null) {
+            logger.log(Level.INFO, "new element detected", elem);
+            matches = new HashMap<OsmPrimitive, Integer>();
+            elemMatchIndex.put(elem, matches);
+        }
+
+        for (OsmPrimitive prim : primMatchIndex.keySet())
+            reconsider(prim, elem);
+    }
+
+    /*private int getStatus(OsmPrimitive prim) {
+        if (primMatchIndex.get(prim) == null)   return STATUS_UNKNOWN;
+        if (primMatchIndex.get(prim).size()==0) return STATUS_UNKNOWN;
+        if (translate(prim) != null)            return STATUS_MATCH;
+        return STATUS_CONFLICT;
+    }
+
+    private int getStatus(AddressElement elem) {
+        if (elemMatchIndex.get(elem) == null)   return STATUS_UNKNOWN;
+        if (elemMatchIndex.get(elem).size()==0) return STATUS_UNKNOWN;
+        if (translate(elem) != null)            return STATUS_MATCH;
+        return STATUS_CONFLICT;
+    }*/
+
+    public int getQ(OsmPrimitive prim, AddressElement elem) {
+        if (primMatchIndex.get(prim) == null) return 0;
+        if (elemMatchIndex.get(elem) == null) return 0;
+
+        assert primMatchIndex.get(prim).get(elem) == elemMatchIndex.get(elem).get(prim);
+
+        if (primMatchIndex.get(prim).get(elem) == null)
+            return 0;
+        else
+            return primMatchIndex.get(prim).get(elem);
+    }
+
+    public void putQ(OsmPrimitive prim, AddressElement elem, int qVal) {
         
-        ensureConsistency(firstNewIndex);
-    }
-
-    /**
-     * Adds new primitives to the database, finds suitable {@link House}s for
-     * them and afterwards seeks for potential conflicts.
-     *
-     * <p><b>NOTE:</b> Adding primitives through {@code addPrimitives()} has
-     * different effect from adding primitives one by one through
-     * {@code addPrimitive()}.</p>
-     * 
-     * <p>The preffered way of handling this is to add a large bunch of elements
-     * from the database via {@code addPrimitives()}, because the possible
-     * conflicts are between all possible element-primitive combinations.
-     * For adding single node by user, {@code addPrimitives()} is the preferred
-     * way, because immediatelly after the matching the best suitable element
-     * is removed from the element pool and it cannot be matched to any other
-     * primitive.</p>
-     */
-    public synchronized void addPrimitives(Collection<OsmPrimitive> newPrimitives) {
-
-        int firstNewIndex = matches.size();
-
-        for (OsmPrimitive primitive : newPrimitives)
-            matchPrimitive(primitive);
-
-        ensureConsistency(firstNewIndex);
-    }
-
-    /**
-     * Removes the given primitive from the database and cancels all conflicts
-     * which can be solved by this removal.
-     */
-    public synchronized void removePrimitive(OsmPrimitive primitive) {
-
-        // TODO: Implement the removal of a primitive
-    }
-
-    /**
-     * Forcibly matches given house to given primitive.
-     *
-     * <p>This can be useful in cases, where the user manually resolves
-     * a conflict by stating that this particular combination of
-     * house-primitive it the correct one.</p>
-     *
-     * <p>The quality is set to {@link Match}{@code .MATCH_OVERWRITE}.</p>
-     */
-    public synchronized void overwriteMatch(AddressElement elem, OsmPrimitive prim) {
-
-        int firstNewIndex = matches.size();
-
-        matches.add(new Match(elem, prim, Match.MATCH_OVERWRITE));
-        matchesDirty = true;
-
-        reconsider(elem);
-        reconsider(prim);
-
-        ensureConsistency(firstNewIndex);
-    }
-
-    /**
-     * Returns all elements available for matching.
-     */
-    public List<AddressElement> getElementPool() {
-        return elemPool;
-    }
-
-    /** Returns all primitives, which have not been assigned any element during
-     * the matching. */
-    public List<OsmPrimitive> getNotMatchable() {
-        return notMatchable;
-    }
-
-    public List<Match> getAllMatches() {
-
-        return matches;
-    }
-
-    public Match findMatch(OsmPrimitive prim) {
-        return primMatchHashIndex.get(prim);
-    }
-
-    public Match findMatch(AddressElement elem) {
-        return primMatchHashIndex.get(elem);
-    }
-
-    /**
-     * Finds given primitive in list of {@code  matches} and returns
-     * the corresponding element.
-     * 
-     * <p>If the primitive is not found, {@code null} is returned.</p>
-     */
+        if (qVal == Match.MATCH_NOMATCH) {
+            primMatchIndex.get(prim).remove(elem);
+            elemMatchIndex.get(elem).remove(prim);
+
+            if (primMatchIndex.get(prim).size() == 0)
+                primMatchIndex.put(prim, null);
+            if (elemMatchIndex.get(elem).size() == 0)
+                elemMatchIndex.put(elem, null);
+
+        } else {
+            primMatchIndex.get(prim).put(elem, qVal);
+            elemMatchIndex.get(elem).put(prim, qVal);
+        }
+    }
+
     public AddressElement translate(OsmPrimitive prim) {
-        Match m = primMatchHashIndex.get(prim);
-        if (m == null) return null;
-        return m.elem;
-    }
-
-    /**
-     * Finds given element in list of {@code matches} and returns the corresponding
-     * primitive.
-     *
-     * <p>If the element is not found, {@code null} is returned.</p>
-     */
+        AddressElement elem = primBestIndex.get(prim);
+        if (elemBestIndex.get(elem) == prim)
+            return elem;
+        return null;
+    }
+
     public OsmPrimitive translate(AddressElement elem) {
-        Match m = elemMatchHashIndex.get(elem);
-        if (m == null) return null;
-        return m.prim;
-    }
-
-    /**
-     * Returns a list all conflicts corresponding to the given {@link AddressElement}.
-     */
-    public List<Match> getConflicts(AddressElement elem) {
-        return elemConflictHashIndex.get(elem);
-    }
-
-    /**
-     * Returns a list all conflicts corresponding to the given {@link OsmPrimitive}.
-     */
-    public List<Match> getConflicts(OsmPrimitive prim) {
-        return primConflictHashIndex.get(prim);
-    }
-
-    /**
-     * Returns a sorted list of all elements in conflict.
-     */
-    public List<AddressElement> getElementsInConflict() {
-        return elemConflictListIndex;
-    }
-
-    /**
-     * Returns a sorted list of all primitives in conflict.
-     */
-    public List<OsmPrimitive> getPrimitivesInConflict() {
-        return primConflictListIndex;
-    }
-
-    /**
-     * Returns the list of all conflicts.
-     */
-    public List<Match> getAllConflicts() {
-        return conflicts;
-    }
-
-    /**
-     * Goes through all matches and returns proposals for changing
-     * every primitive (if it differs from the matched element).
-     */
-    public ProposalDatabase getProposals() {
-
-        ProposalDatabase proposals = new ProposalDatabase();
-
-        for (Match match : matches) {
+        OsmPrimitive prim = elemBestIndex.get(elem);
+        if (primBestIndex.get(prim) == elem)
+            return prim;
+        return null;
+    }
+
+    public Set<AddressElement> conflicts(OsmPrimitive prim) {
+
+        Set<AddressElement> result = new HashSet<AddressElement>();
+        result.addAll(primMatchIndex.get(prim).keySet());
+        
+        AddressElement match = translate(prim);
+        if (match != null)
+            result.remove(match);
+
+        return result;
+    }
+
+    public Set<OsmPrimitive> conflicts(AddressElement elem) {
+
+        Set<OsmPrimitive> result = new HashSet<OsmPrimitive>();
+        result.addAll(elemMatchIndex.get(elem).keySet());
+
+        OsmPrimitive match = translate(elem);
+        if (match != null)
+            result.remove(match);
+
+        return result;
+    }
+
+    public static void main(String[] args) {
+        try {
+
+            Reasoner r = new Reasoner();
+
+            Handler  h = new FileHandler("log.xml");
+
+            r.logger.addHandler(h);
+            r.logger.setLevel(Level.ALL);
             
-            ProposalContainer proposalContainer
-                    = new ProposalContainer(match.prim);
+            Match.logger.addHandler(h);
+            Match.logger.setLevel(Level.ALL);
+
+
+            Street s1 = new Street("Jarní");
+            Street s2 = new Street("Letní");
+
+            House h1 = new House("240", "1"); s1.addHouse(h1); r.consider(h1);
+            House h2 = new House("241", "2"); s1.addHouse(h2); r.consider(h2);
+            House h3 = new House("241", "3"); s1.addHouse(h3); r.consider(h3);
+            House h4 = new House("242", "4"); s1.addHouse(h4); r.consider(h4);
+
+            House i1 = new House("42",  "1"); s2.addHouse(i1); r.consider(i1);
+            House i2 = new House("45",  "2"); s2.addHouse(i2); r.consider(i2);
+            House i3 = new House("61",  "3"); s2.addHouse(i3); r.consider(i3);
+            House i4 = new House("240", "4"); s2.addHouse(i4); r.consider(i4);
+
+
             
-            proposalContainer.addProposals(match.getDiff());
-
-            if (proposalContainer.getProposals().size() > 0)
-                proposals.addContainer(proposalContainer);
-        }
-
-        return proposals;
-    }
-
-    /**
-     * Finds suitable {@code Match}es in the pool of {@link AddressElement}s.
-     *
-     * @param primitive the primitive to be matched with elements of
-     * {@code elemPool}.
-     * @return the list of all matches, whose <i>quality</i> &gt;
-     * {@link Match}{@code .MATCH_NOMATCH}.
-     */
-    public NotNullList<Match> getMatchesForPrimitive(OsmPrimitive primitive) {
-
-        NotNullList<Match> result = new NotNullList<Match>();
-        
-        for (AddressElement elem : elemPool)
-            result.add(Match.createMatch(elem, primitive));
-        return result;
-    }
-
-    /**
-     * Method for adding matches for a single primitive into the resoner.
-     *
-     * <p>This method uses {@code getMatchesForPrimitive()} for getting the
-     * list of suitable matches for the given primitive. Then it selects
-     * <u>all</u> matches with the highest {@code quality} and adds them
-     * into the {@code matches} list.
-     */
-    protected void matchPrimitive(OsmPrimitive prim) {
-        boolean assertions = false;
-        assert  assertions = true;
-
-        if (prim.deleted) return;
-
-        NotNullList<Match> suitable = getMatchesForPrimitive(prim);
-        NotNullList<Match> toDelete = new NotNullList<Match>(suitable.size());
-
-        for (Match match1 : suitable)
-            for (Match match2 : suitable)
-                if (   match1        != match2
-                    && match1.quality > match2.quality) {
-                    toDelete.add(match2);
-                    if (assertions)
-                        System.out.println("Reasoner: Dominated match: " + match2.toString());
-                }
-
-        suitable.removeAll(toDelete);
-
-        // Make sure we reconsider all elements.
-        for (Match match : matches) {
-            reconsider(match.elem);
-            reconsider(match.prim);
-        }
-
-        if (suitable.size() > 0) {
-            matches.addAll(suitable);
-            matchesDirty = true;
-        } else
-            notMatchable.add(prim);
-    }
-
-//==============================================================================
-//  MESSAGE HANDLING SYSTEM
-//==============================================================================
-
-    /**
-     * Should be true whenever {@code matches} have changed, but the
-     * {@link StatusListener}{@code .MESSAGE_MATCHES_CHANGED} message has
-     * not yet been sent.
-     */
-    protected boolean matchesDirty = false;
-
-    /**
-     * Should be true whenever {@code conflicts} have changed, but the
-     * {@link StatusListener}{@code .MESSAGE_CONFLICT_CHANGED} message has
-     * not yet been sent.
-     */
-    protected boolean conflictsDirty = false;
-
-    /**
-     * Broadcasts information about the changes of reasoner status.
-     *
-     * <p>If the {@code matchesDirty} or {@code conflictsDirty} flag is
-     * {@link true}, this method informs all listeners about the change
-     * of plugin's status.</p>
-     */
-    protected void handleDirt() {
-
-        if (matchesDirty || conflictsDirty)
-            regenerateIndexes();
-
-        if (matchesDirty) CzechAddressPlugin.broadcastStatusChanged(
-                StatusListener.MESSAGE_MATCHES_CHANGED);
-
-        if (conflictsDirty) CzechAddressPlugin.broadcastStatusChanged(
-                StatusListener.MESSAGE_CONFLICT_CHANGED);
-
-        matchesDirty = conflictsDirty = false;
-    }
-
-//==============================================================================
-//  CONSISTENCY CHECKING
-//==============================================================================
-
-    /**
-     * Should be called after modifying <b>anything</b> to put reasoner into
-     * consistent state.
-     *
-     * <p>This method should be called at the end of every public method,
-     * which changes anything in the reasoner.</p>
-     */
-    public void ensureConsistency() {
-        ensureConsistency(0);
-    }
-
-    /**
-     * Should be called after modifying <b>anything</b> to put reasoner into
-     * consistent state.
-     *
-     * <p>This method should be called at the end of every public method,
-     * which changes anything in the reasoner.</p>
-     *
-     * <p>Checking every match with every match is computationally inefficient.
-     * Therefore by specifying {@code startElementIndex > 0}, we can
-     * reduce this cost by checking <i>every match</i> with <i>every match,
-     * whose index is greater than {@code startElementIndex}.</p>
-     */
-    public void ensureConsistency(int startElementIndex) {
-        startElementIndex = 0;
-
-        NotNullList<Match> toDel = new NotNullList<Match>(10);
-        for (Match match1 : matches) for (Match match2 : matches) {
-
-            if (match1 == match2) continue;
-
-            if (match1.prim == match2.prim && match1.quality > match2.quality) {
-                System.out.println("Reasoner: Redundancy clean: " + match2);
-                toDel.add(match2);
-                matchesDirty = true;
-            }
-
-            if (match1.prim == match2.prim && match1.quality >= match2.quality
-             && match1.elem == match2.elem && !toDel.contains(match1)) {
-                System.out.println("Reasoner: Hyper redundancy: " + match2);
-                toDel.add(match2);
-                matchesDirty = true;
-            }
-        }
-        matches.removeAll(toDel);
-
-        toDel.clear();
-        for (Match conflict1 : conflicts) for (Match conflict2 : conflicts) {
-
-            if (conflict1 == conflict2) continue;
-
-            if (conflict1.prim == conflict2.prim
-             && conflict1.elem == conflict2.elem && !toDel.contains(conflict1)) {
-                System.out.println("Reasoner: Confl redundancy: " + conflict2);
-                toDel.add(conflict2);
-                conflictsDirty = true;
-            }
-        }
-        conflicts.removeAll(toDel);
-
-        for (Match match : matches)
-            for (Match conflict : conflicts) {
-                assert match      != conflict;
-                assert match.prim != conflict.prim;
-            }
-
-
-
-        if (handleDeletedPrimitivesSlowButSafe())
-            startElementIndex = 0;
-        handleInconsistentMatches(startElementIndex);
-        handleDirt();
-
-        CzechAddressPlugin.broadcastStatusChanged(
-                                    StatusListener.MESSAGE_REASONER_REASONED);
-    }
-
-    /**
-     * Finds conflicts in the {@code matches} list and moves them to
-     * {@code conflicts} list.
-     */
-    protected void handleInconsistentMatches(int startElementIndex) {
-        boolean assertions = false;
-        assert  assertions = true;
-
-
-        // Move all conflicting matches into 'conflicts' array.
-        int pos1 = 0;
-        while (pos1 < matches.size()) {
-
-            int pos2 = Math.max(pos1 + 1, startElementIndex);
-            while (pos2 < matches.size()) {
-
-                Match item1 = matches.get(pos1);
-                Match item2 = matches.get(pos2);
-
-                if ((item1.elem == item2.elem) || (item1.prim == item2.prim)) {
-
-                    if (assertions) {
-                        System.out.println("1. match in conflict: " + item2);
-                        System.out.println("2. match in conflict: " + item1);
-                    }
-
-                    if (item1.quality >= item2.quality) {
-                        if (assertions)
-                            System.out.println("1. match moved to 'conflicts'.");
-                        matches.remove(pos2);
-                        conflicts.add(item2);
-                        matchesDirty = conflictsDirty = true;
-                        pos2--;
-                    }
-
-                    if (item1.quality <= item2.quality) {
-                        if (assertions) {
-                            System.out.println("2. match moved to 'conflicts'.");
-                            System.out.println("----------------------------------------------------------------------");
-                        }
-                        matches.remove(pos1);
-                        conflicts.add(item1);
-                        matchesDirty = conflictsDirty = true;
-                        pos1--;
-                        break;
-                    }
-
-                    if (assertions)
-                        System.out.println("----------------------------------------------------------------------");
-                }
-
-                pos2++;
-            }
-            pos1++;
-        }
-    }
-
-    /**
-     * Seeks and handles primitives, which have been deleted.
-     *
-     * <p>If a primitive has been deleted, the first immediate action is to
-     * remove it from the {@code matches} and {@code conflicts} lists.
-     * However there might be another conflict, which was caused by the
-     * deleted primitive. This method finds such conflicts and
-     * moves them back to {@code matches} list to
-     * be reconsideres later.</p>
-     */
-    protected boolean handleDeletedPrimitives() {
-
-        boolean somethingChanged = false;
-        NotNullList<OsmPrimitive> blockers = new NotNullList<OsmPrimitive>();
-
-        // Firstly create a list of all primitives, which were deleted.
-        for (Match match : matches)
-            if (match.prim.deleted)
-                blockers.add(match.prim);
-
-        for (Match conflict : conflicts)
-            if (conflict.prim.deleted)
-                blockers.add(conflict.prim);
-
-        // Now for every deleted primitive...
-        int i=0;
-        while (i < blockers.size()) {
-            OsmPrimitive blocker = blockers.get(i);
-
-            // ... remove its' entries in the 'matches' ...
-            if (primMatchHashIndex.get(blocker) != null) {
-                Match toRemove = primMatchHashIndex.get(blocker);
-                matches.remove(toRemove);
-                primMatchHashIndex.remove(toRemove.prim);
-                elemMatchHashIndex.remove(toRemove.elem);
-                somethingChanged = matchesDirty = true;
-            }
-
-            // ... and reconsider all 'conflicts', which may have been caused
-            // by the deleted primitive. We must do it recursively...
-
-            // Every conflict, which has the 'blocker' as a primitive
-            if (primConflictHashIndex.get(blocker) != null) {
-                for (Match match : primConflictHashIndex.get(blocker)) {
-                    // Find the correspoding element and find all primitives,
-                    // which are mapped to this element.
-                    if (elemConflictHashIndex.get(match.elem) != null) {
-                        for (Match novy : elemConflictHashIndex.get(match.elem)) {
-                            // If this primitive has not yet been handled, do it!
-                            if (!blockers.contains(novy.prim))
-                                blockers.add(novy.prim);
-                            // And move the conflict back to 'matches' for reconsideration.
-                            if (!novy.prim.deleted && !matches.contains(novy)) {
-                                matches.add(novy);
-                                somethingChanged = matchesDirty = true;
-                            }
-                        }
-                        // Finally remove the reconsidered conflicts...
-                        conflicts.removeAll(elemConflictHashIndex.get(match.elem));
-                        elemConflictHashIndex.remove(match.elem);
-                        elemConflictListIndex.remove(match.elem);
-                        somethingChanged = conflictsDirty = true;
-                    }
-                    // [move the conflict back to 'matches' for reconsideration]
-                    if (!match.prim.deleted && !matches.contains(match)) {
-                        matches.add(match);
-                        somethingChanged = matchesDirty = true;
-                    }
-                }
-                // ...and once again remove reconsidered conflicts.
-                conflicts.removeAll(primConflictHashIndex.get(blocker));
-                primConflictHashIndex.remove(blocker);
-                primConflictListIndex.remove(blocker);
-                somethingChanged = conflictsDirty = true;
-            }
-            i++;
-        }
-
-        return somethingChanged;
-    }
-
-    /**
-     * Seeks and handles primitives, which have been deleted.
-     *
-     * <p>Slower, but safer counterpart of {@code handleDeletedPrimitives))}.</p>
-     */
-    protected boolean handleDeletedPrimitivesSlowButSafe() {
-
-        boolean fire = false;
-
-        for (Match match : matches)
-            fire |= match.qualityChanged();
-
-        for (Match conflict : conflicts)
-            fire |= conflict.qualityChanged();
-
-        if (fire) {
-            matches.addAll(conflicts);
-            conflicts.clear();
-            matchesDirty = conflictsDirty = true;
-
-            int i=0;
-            while (i<matches.size()) {
-                Match match = matches.get(i);
-                if (match.quality <= Match.MATCH_NOMATCH) {
-                    System.out.println("Reasoner: Deleting " + matches.get(i));
-                    matches.remove(i);
-
-                    assert fire;
-                    assert !matches.contains(match);
-                } else
-                    i++;
-            }
-        }
-
-        return fire;
-    }
-
-    protected void reconsider(OsmPrimitive prim) {
-
-        List<Match> reconsider;
-
-        reconsider = getConflicts(prim);
-        if (reconsider != null) {
-            matches.addAll(reconsider);
-            conflicts.removeAll(reconsider);
-            matchesDirty = conflictsDirty = true;
-        }
-    }
-
-    protected void reconsider(AddressElement elem) {
-
-        List<Match> reconsider;
-
-        reconsider = getConflicts(elem);
-        if (reconsider != null) {
-            matches.addAll(reconsider);
-            conflicts.removeAll(reconsider);
-            matchesDirty = conflictsDirty = true;
-        }
-    }
-
-    /**
-     * Recreates all {@code *Index} fields if this reasoner.
-     */
-    protected void regenerateIndexes() {
-        boolean assertions = false;
-        assert  assertions = true;
-
-        elemMatchHashIndex.clear();
-        primMatchHashIndex.clear();
-        elemConflictHashIndex.clear();
-        primConflictHashIndex.clear();
-        elemConflictListIndex.clear();
-        primConflictListIndex.clear();
-
-        for (Match match : matches) {
-            elemMatchHashIndex.put(match.elem, match);
-            primMatchHashIndex.put(match.prim, match);
-        }
-
-        for (Match conflict : conflicts) {
-
-            List<Match> elemConflicts = elemConflictHashIndex.get(conflict.elem);
-            if (elemConflicts == null) {
-                elemConflicts = new ArrayList<Match>();
-                elemConflictHashIndex.put(conflict.elem, elemConflicts);
-            }
-            elemConflicts.add(conflict);
-
-            List<Match> primConflicts = primConflictHashIndex.get(conflict.prim);
-            if (primConflicts == null) {
-                primConflicts = new ArrayList<Match>();
-                primConflictHashIndex.put(conflict.prim, primConflicts);
-            }
-            primConflicts.add(conflict);
-        }
-
-        for (AddressElement elem : elemConflictHashIndex.keySet())
-            elemConflictListIndex.add(elem);
-
-        for (OsmPrimitive prim : primConflictHashIndex.keySet())
-            primConflictListIndex.add(prim);
-
-        assert elemConflictHashIndex.size() == elemConflictListIndex.size();
-        assert primConflictHashIndex.size() == primConflictListIndex.size();
-
-        for (AddressElement elem : elemConflictListIndex)
-            assert elemConflictHashIndex.get(elem) != null;
-        for (OsmPrimitive prim : primConflictListIndex)
-            assert primConflictHashIndex.get(prim) != null;
-
-        if (assertions) {
-            System.out.println("Spárovaných dvojic: " + String.valueOf(matches.size()));
-            System.out.println("Konfliktů (celkem): " + String.valueOf(conflicts.size())
-                    + "; " + String.valueOf(elemConflictListIndex.size())
-                    + "+"  + String.valueOf(primConflictListIndex.size())
-                    + " elementů+primitiv");
+            Node n1 = new Node(1);
+            n1.put("addr:street", "Jarní");
+            n1.put("addr:alternatenumber", "242");
+
+            r.openTransaction();
+            r.consider(n1);
+            r.closeTransaction();
+            assert r.translate(n1) == h4;
+            assert r.conflicts(n1).size() == 0;
+
+
+
+            Node n2 = new Node(2);
+            n2.put("addr:alternatenumber", "240");
+            r.openTransaction();
+            r.consider(n2);
+            r.closeTransaction();
+            assert r.translate(n2) == null;
+            assert r.conflicts(n2).contains(h1);
+            assert r.conflicts(n2).contains(i4);
+
+            n2.put("addr:street", "Letní");
+            n2.put("addr:housenumber", "4");
+            r.openTransaction();
+            r.consider(n2);
+            r.closeTransaction();
+            assert r.translate(n2) == i4;
+            assert r.conflicts(n2).contains(h1);
+
+
+            n2.deleted = true;
+            r.openTransaction();
+            r.consider(n2);
+            r.closeTransaction();
+
+            assert r.translate(n2) == null;
+            
+        } catch (Exception ex) {
+            
+            ex.printStackTrace();
         }
     }
Index: applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/parser/MvcrParser.java
===================================================================
--- applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/parser/MvcrParser.java	(revision 15412)
+++ applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/parser/MvcrParser.java	(revision 15461)
@@ -1,5 +1,6 @@
 package org.openstreetmap.josm.plugins.czechaddress.parser;
 
-import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.*;
+import static org.openstreetmap.josm.plugins.czechaddress.StringUtils.capitalize;
+
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -7,8 +8,13 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
-
-
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.plugins.czechaddress.DatabaseLoadException;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithHouses;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithStreets;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Region;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Suburb;
+import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ViToCi;
 import org.xml.sax.Attributes;
 import org.xml.sax.Locator;
@@ -48,7 +54,7 @@
             if (curRegion == null) {*/
                 curRegion = new Region(
-                    attributes.getValue("nazev"),
-                    attributes.getValue("kraj"),
-                    attributes.getValue("okres"));
+                    capitalize(attributes.getValue("nazev")),
+                    capitalize(attributes.getValue("kraj")),
+                    capitalize(attributes.getValue("okres")));
 
                 target.regions.add(curRegion);
@@ -60,5 +66,5 @@
             return;
 
-        // ========== PARSING ViToCI ========== //
+        // ========== PARSING ViToCi ========== //
         if (name.equals("obec")) {
 
@@ -69,5 +75,5 @@
             //curViToCi = curRegion.findViToCi(attributes.getValue("nazev"));
             //if (curViToCi == null) {
-                curViToCi = new ViToCi(attributes.getValue("nazev"));
+                curViToCi = new ViToCi(capitalize(attributes.getValue("nazev")));
             //    System.out.println("Parser: " + curViToCi);
                 curRegion.addViToCi(curViToCi);
@@ -86,5 +92,5 @@
             //curSuburb = curViToCi.findSuburb(attributes.getValue("nazev"));
             //if (curSuburb == null) {
-                curSuburb = new Suburb(attributes.getValue("nazev"));
+                curSuburb = new Suburb(capitalize(attributes.getValue("nazev")));
             //    System.out.println("Parser: " + curSuburb);
                 curViToCi.addSuburb(curSuburb);
@@ -105,5 +111,5 @@
             //curStreet = topElem.findStreet(attributes.getValue("nazev"));
             //if (curStreet == null) {
-                curStreet = new Street(attributes.getValue("nazev"));
+                curStreet = new Street(capitalize(attributes.getValue("nazev")));
             //    System.out.println("Parser: " + curStreet);
                 topElem.addStreet(curStreet);
