Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressEditContainer.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressEditContainer.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressEditContainer.java	(revision 24023)
@@ -227,8 +227,18 @@
 			// Assignment failed: Street is not known (yet) -> add to 'unresolved' list 
 			shadowUnresolvedAddresses.add(aNode);
+			
+			if ("BaDaubringen".equals(aNode.getCity())) {
+				@SuppressWarnings("unused")
+				int x = 0;
+			}
 		}
 
 		if (!aNode.isComplete()) {
 			shadowIncompleteAddresses.add(aNode);
+			
+			if ("BaDaubringen".equals(aNode.getCity())) {
+				@SuppressWarnings("unused")
+				int x = 0;
+			}
 		}
 	}
@@ -451,5 +461,5 @@
 			if (assignAddressToStreet(node)) {
 				resolvedAddresses.add(node);
-			}
+			} 
 		}
 		
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressFinderThread.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressFinderThread.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressFinderThread.java	(revision 24023)
@@ -35,4 +35,5 @@
 public class AddressFinderThread extends PleaseWaitRunnable implements Visitor {
 	private List<AddressNode> addressesToGuess;
+	private List<IProgressMonitorFinishedListener> finishListeners = new ArrayList<IProgressMonitorFinishedListener>();
 	private double minDist;
 	private AddressNode curAddressNode;
@@ -57,5 +58,5 @@
 	}
 
-	public List<AddressNode> getAddressEditContainer() {
+	public List<AddressNode> getAddressesToGuess() {
 		return addressesToGuess;
 	}
@@ -65,4 +66,30 @@
 	public boolean isRunning() {
 		return isRunning;
+	}
+	
+	/**
+	 * Adds a finish listener.
+	 *
+	 * @param l the listener to add
+	 */
+	public void addFinishListener(IProgressMonitorFinishedListener l) {
+		finishListeners.add(l);
+	}
+	
+	/**
+	 * Removes a finish listener.
+	 *
+	 * @param l the listener to remove
+	 */
+	public void removeFinishListener(IProgressMonitorFinishedListener l) {
+		finishListeners.remove(l);
+	}
+
+	protected void fireFinished() {
+		for (IProgressMonitorFinishedListener l : finishListeners) {
+			l.finished();
+		}
+		// this event is fired only once, then we disconnect all listeners
+		finishListeners.clear();
 	}
 
@@ -173,4 +200,6 @@
 					break;
 				}
+				
+				progressMonitor.subTask(tr("Guess values for ") + aNode);
 
 				// visit osm data
@@ -186,12 +215,4 @@
 				}
 				
-				// we found something
-				if (nearestName != null) {
-					progressMonitor.subTask(String.format("%s: %s (%4.1f m)", tr("Guess"), nearestName, minDist));
-					aNode.setGuessedStreetName(nearestName);
-					nearestName = null;
-				} else {
-					System.out.println("Did not find a street for " + aNode);
-				}
 				// report progress
 				progressMonitor.worked(1);				
@@ -199,4 +220,5 @@
 		} finally {
 			isRunning = false;
+			fireFinished();
 		}
 	}
@@ -227,7 +249,4 @@
 					minDist = dist;
 					currentValue = TagUtils.getNameValue(w);				
-					
-					System.out.println(String.format("New guess (way) for tag %s (%4.2f m): %s (%s)", 
-							getTag(), minDist, currentValue, aNode.toString()));
 					aNode.setGuessedValue(getTag(), currentValue);
 				}
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressNode.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressNode.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/AddressNode.java	(revision 24023)
@@ -21,5 +21,8 @@
 	public static final String MISSING_TAG = "?";
 	
+	/** The dictionary containing guessed values. */
 	private HashMap<String, String> guessedValues = new HashMap<String, String>();
+	/** The dictionary containing indirect values. */
+	private HashMap<String, String> derivedValues = new HashMap<String, String>();
 
 	public AddressNode(OsmPrimitive osmObject) {
@@ -33,4 +36,9 @@
 	public void setOsmObject(OsmPrimitive osmObject) {
 		super.setOsmObject(osmObject);
+		
+		String streetNameViaRel = OsmUtils.getAssociatedStreet(this.osmObject);
+		if (!StringUtils.isNullOrEmpty(streetNameViaRel)) {
+			setDerivedValue(TagUtils.ADDR_STREET_TAG, streetNameViaRel);
+		}
 	}
 	
@@ -42,5 +50,6 @@
 		return 	TagUtils.hasAddrCityTag(osmObject) && TagUtils.hasAddrCountryTag(osmObject) &&
 				TagUtils.hasAddrHousenumberTag(osmObject) && TagUtils.hasAddrPostcodeTag(osmObject) &&
-				TagUtils.hasAddrStateTag(osmObject) && TagUtils.hasAddrStreetTag(osmObject);
+				TagUtils.hasAddrStateTag(osmObject) && 
+				(TagUtils.hasAddrStreetTag(osmObject) || hasDerivedValue(TagUtils.ADDR_STREET_TAG));
 	}
 	
@@ -64,26 +73,18 @@
 		if (osmObject == null) return MISSING_TAG;
 		
-		if (!osmObject.hasKey(tag)) {
-			// object does not have this tag -> check for guess
-			if (hasGuessedValue(tag)) {
-				return "*" + getGuessedValue(tag);
-			} else {
-				// give up
-				return MISSING_TAG;
-			}
-		} else { // get existing tag value
-			String val = osmObject.get(tag);			
-			if (StringUtils.isNullOrEmpty(val)) {
-				// empty value -> check for guess
+		if (!osmObject.hasKey(tag) || StringUtils.isNullOrEmpty(osmObject.get(tag))) {
+			if (!hasDerivedValue(tag)) {
+				// object does not have this tag -> check for guess
 				if (hasGuessedValue(tag)) {
 					return "*" + getGuessedValue(tag);
 				} else {
-					// tag is empty and no guess available -> give up
+					// give up
 					return MISSING_TAG;
 				}
-			} else {
-				// ok, return existing tag value
-				return val;
+			} else { // ok, use derived value known via associated relation or way 
+				return getDerivedValue(tag);
 			}
+		} else { // get existing tag value
+			return osmObject.get(tag);			
 		}
 	}
@@ -376,4 +377,37 @@
 	
 	/**
+	 * Checks if given tag has a derived value (value is available via a referrer).
+	 *
+	 * @param tag the tag
+	 * @return true, if tag has a derived value.
+	 */
+	private boolean hasDerivedValue(String tag) {
+		return derivedValues.containsKey(tag) && 
+			!StringUtils.isNullOrEmpty(derivedValues.get(tag));
+	}
+	
+	/**
+	 * Gets the derived value for the given tag.
+	 * @param tag The tag to get the derived value for.
+	 * @return
+	 */
+	public String getDerivedValue(String tag) {
+		if (!hasDerivedValue(tag)) {
+			return null;			
+		}
+		return derivedValues.get(tag);
+	}
+		
+	/**
+	 * Sets the value known indirectly via a referrer with the given tag.
+	 *
+	 * @param tag the tag to set the derived value for
+	 * @param value the value of the derived tag.
+	 */
+	public void setDerivedValue(String tag, String value) {
+		derivedValues.put(tag, value);
+	}	
+	
+	/**
 	 * Sets the street name of the address node.
 	 * @param streetName
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/IProgressMonitorFinishedListener.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/IProgressMonitorFinishedListener.java	(revision 24023)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/IProgressMonitorFinishedListener.java	(revision 24023)
@@ -0,0 +1,18 @@
+/*
+ * This program is free software: you can redistribute it and/or modify it under 
+ * the terms of the GNU General Public License as published by the 
+ * Free Software Foundation, either version 3 of the License, or 
+ * (at your option) any later version. 
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * See the GNU General Public License for more details. 
+ * 
+ * You should have received a copy of the GNU General Public License along with this program. 
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.openstreetmap.josm.plugins.fixAddresses;
+
+public interface IProgressMonitorFinishedListener {
+	public void finished();
+}
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/OsmUtils.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/OsmUtils.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/OsmUtils.java	(revision 24023)
@@ -18,4 +18,7 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.tools.Pair;
@@ -84,3 +87,33 @@
 		}
 	}
+	
+	/**
+	 * Gets the associated street name via relation of the address node, if present.
+	 *
+	 * @param addrNode the OSM node containing the address.
+	 * @return the associated street or null, if no associated street has been found.
+	 */
+	public static String getAssociatedStreet(OsmPrimitive addrNode) {
+		if (addrNode == null) {
+			return null;
+		}
+		
+		for (OsmPrimitive osm : addrNode.getReferrers()) {
+			if (osm instanceof Relation) {
+				Relation r = (Relation) osm;
+				
+				if (!TagUtils.isAssociatedStreetRelation(r)) continue;
+				
+				for (RelationMember rm : r.getMembers()) {
+					if (TagUtils.isStreetMember(rm)) {
+						OsmPrimitive street = rm.getMember();
+						if (TagUtils.hasHighwayTag(street)) {
+							return TagUtils.getNameValue(street);
+						} // TODO: Issue a warning here
+					}
+				}
+			}
+		}
+		return null;
+	}
 }
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/TagUtils.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/TagUtils.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/TagUtils.java	(revision 24023)
@@ -15,4 +15,6 @@
 
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.Relation;
+import org.openstreetmap.josm.data.osm.RelationMember;
 
 /**
@@ -1875,4 +1877,38 @@
 	public static String getEmbankmentValue(OsmPrimitive osmPrimitive) {
 		return osmPrimitive != null ? osmPrimitive.get(EMBANKMENT_TAG) : null;
+	}
+	
+	// Relation support
+	
+	/**
+	 * Check if OSM relation is a 'associatedStreet' relation.
+	 * 
+	 * @param osmPrimitive
+	 *            The OSM entity to check.
+	 */
+	public static boolean isAssociatedStreetRelation(Relation rel) {
+		return rel != null && 
+			rel.hasKey(RELATION_TYPE) && 
+			ASSOCIATEDSTREET_RELATION_TYPE.equals(rel.get(RELATION_TYPE));
+	}
+	
+	/**
+	 * Checks if given relation member has role "street".
+	 *
+	 * @param relMember the relation member
+	 * @return true, if is street member
+	 */
+	public static boolean isStreetMember(RelationMember relMember) {
+		return relMember != null && STREET_RELATION_ROLE.equals(relMember.getRole());
+	}
+	
+	/**
+	 * Checks if given relation member has role "house".
+	 *
+	 * @param relMember the relation member
+	 * @return true, if is street member
+	 */
+	public static boolean isHouseMember(RelationMember relMember) {
+		return relMember != null && STREET_RELATION_ROLE.equals(relMember.getRole());
 	}
 
@@ -1968,3 +2004,11 @@
 	public static final String EMBANKMENT_TAG = "embankment";
 	public static final String ADDR_HOUSENAME_TAG = "addr:housename";
+	
+	/* Relation keys */
+	
+	// Associated street: See http://wiki.openstreetmap.org/wiki/Proposed_features/De:Hausnummern
+	public static final String RELATION_TYPE = "type";
+	public static final String ASSOCIATEDSTREET_RELATION_TYPE = "associatedStreet";
+	public static final String STREET_RELATION_ROLE = "street";
+	public static final String HOUSE_RELATION_ROLE = "house";
 }
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/GuessAddressDataAction.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/GuessAddressDataAction.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/GuessAddressDataAction.java	(revision 24023)
@@ -22,4 +22,5 @@
 import org.openstreetmap.josm.plugins.fixAddresses.AddressFinderThread;
 import org.openstreetmap.josm.plugins.fixAddresses.AddressNode;
+import org.openstreetmap.josm.plugins.fixAddresses.IProgressMonitorFinishedListener;
 
 /**
@@ -31,5 +32,5 @@
 
 @SuppressWarnings("serial")
-public class GuessAddressDataAction extends AbstractAddressEditAction {
+public class GuessAddressDataAction extends AbstractAddressEditAction implements IProgressMonitorFinishedListener {
 
 	public GuessAddressDataAction() {
@@ -80,5 +81,11 @@
 	 */
 	private void internalGuessAddresses(List<AddressNode> nodes) {
-		Main.worker.submit(new AddressFinderThread(nodes, tr("Guess street names")));
+		AddressFinderThread aft = new AddressFinderThread(nodes, tr("Guess street names"));
+		aft.addFinishListener(this);
+		Main.worker.submit(aft);
+	}
+
+	@Override
+	public void finished() {
 		if (container != null) {
 			container.invalidate();
Index: /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/IncompleteAddressesTableModel.java
===================================================================
--- /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/IncompleteAddressesTableModel.java	(revision 24022)
+++ /applications/editors/josm/plugins/FixAddresses/src/org/openstreetmap/josm/plugins/fixAddresses/gui/IncompleteAddressesTableModel.java	(revision 24023)
@@ -16,10 +16,14 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.openstreetmap.josm.plugins.fixAddresses.AddressEditContainer;
 import org.openstreetmap.josm.plugins.fixAddresses.AddressNode;
 import org.openstreetmap.josm.plugins.fixAddresses.INodeEntity;
+import org.openstreetmap.josm.plugins.fixAddresses.IProgressMonitorFinishedListener;
 import org.openstreetmap.josm.plugins.fixAddresses.StringUtils;
 
-public class IncompleteAddressesTableModel extends AddressEditTableModel {
+public class IncompleteAddressesTableModel extends AddressEditTableModel  {
 	/**
 	 * 
@@ -31,4 +35,5 @@
 	private static final Class<?>[] COLUMN_CLASSES = new Class<?>[]{
 		String.class, String.class, String.class, String.class, String.class};
+	
 	
 	/**
@@ -76,11 +81,5 @@
 			return aNode.getPostCode();
 		case 4:
-			if (!StringUtils.isNullOrEmpty(aNode.getGuessedStreetName()) && 
-					AddressNode.MISSING_TAG.equals(aNode.getStreetName())) {
-				
-				return "(" + aNode.getGuessedStreetName() + ")";
-			} else {
-				return aNode.getStreetName();
-			}
+			aNode.getStreetName();			
 		default:
 			throw new RuntimeException("Invalid column index: " + column);
