Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressEditAction.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressEditAction.java	(revision 23828)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressEditAction.java	(revision 23829)
@@ -8,10 +8,7 @@
 import java.util.Collection;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.data.SelectionChangedListener;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor.CancelListener;
 import org.openstreetmap.josm.plugins.addressEdit.gui.AddressEditDialog;
@@ -28,4 +25,5 @@
 	private AddressEditModel addressModel;
 	private boolean isCanceled = false;
+	private AddressEditContainer addressEditContainer;
 
 	public AddressEditAction() {
@@ -37,5 +35,5 @@
 						| InputEvent.SHIFT_DOWN_MASK), false);
 		setEnabled(false);
-		DataSet.addSelectionListener(this);
+		
 	}
 
@@ -49,10 +47,13 @@
 	@Override
 	public void actionPerformed(ActionEvent arg0) {
-		collectAddressesAndStreets(Main.main.getCurrentDataSet()
-				.allPrimitives());
-
-		if (addressModel != null) {
-			AddressEditDialog dlg = new AddressEditDialog(addressModel);
-			dlg.setVisible(true);
+		addressEditContainer = new AddressEditContainer();
+		if (addressEditContainer != null) {
+			addressEditContainer.attachToDataSet();
+			try {
+				AddressEditDialog dlg = new AddressEditDialog(addressEditContainer);
+				dlg.setVisible(true);
+			} finally {
+				addressEditContainer.detachFromDataSet();
+			}
 		}
 	}
@@ -63,35 +64,5 @@
 			return;
 
-		final AddressVisitor addrVisitor = new AddressVisitor();
-
-		//final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Prepare OSM data..."));
-		// int ticks = osmData.size();
-
-
-
-		try {
-			for (OsmPrimitive osm : osmData) {
-				osm.visit(addrVisitor);
-
-				if (isCanceled) {
-					addrVisitor.clearData(); // free visitor data
-					return;
-				}
-			}
-			//monitor.worked(1);
-
-			// generateTagCode(addrVisitor);
-			//monitor.setCustomText(tr("Resolving addresses..."));
-			addrVisitor.resolveAddresses();
-			//monitor.worked(1);
-
-
-		} finally {
-			//monitor.close();
-		}
-
-		addressModel = new AddressEditModel(
-				addrVisitor.getStreetList(), 
-				addrVisitor.getUnresolvedItems());
+		
 	}
 
@@ -109,5 +80,5 @@
 	/* ----------------------------------------- */
 
-	private void generateTagCode(AddressVisitor addrVisitor) {
+	private void generateTagCode(AddressEditContainer addrVisitor) {
 		/* This code is abused to generate tag utility code */
 		for (String tag : addrVisitor.getTags()) {
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressEditContainer.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressEditContainer.java	(revision 23829)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressEditContainer.java	(revision 23829)
@@ -0,0 +1,305 @@
+/*
+ * 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/>.
+ */
+/**
+ * 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/>.
+ */
+
+/* File created on 24.10.2010 */
+package org.openstreetmap.josm.plugins.addressEdit;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.Changeset;
+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.Way;
+import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
+import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
+import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
+import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.data.osm.visitor.Visitor;
+
+/**
+ *
+ * @author Oliver Wieland <oliver.wieland@online.de>
+ * 
+ */
+
+public class AddressEditContainer implements Visitor, DataSetListener {
+	private HashMap<String, StreetNode> streetDict = new HashMap<String, StreetNode>(100); 
+	private List<AddressNode> unresolvedAddresses = new ArrayList<AddressNode>(100);
+	private List<AddressNode> incompleteAddresses = new ArrayList<AddressNode>(100);
+	
+	private HashSet<String> tags = new HashSet<String>();
+	
+	private List<IAddressEditContainerListener> listeners = new ArrayList<IAddressEditContainerListener>();
+	
+	/**
+	 * Adds a change listener.
+	 * @param listener
+	 */
+	public void addChangedListener(IAddressEditContainerListener listener) {
+		listeners.add(listener);
+	}
+	
+	/**
+	 * Removes a change listener.
+	 * @param listener
+	 */
+	public void removeChangedListener(IAddressEditContainerListener listener) {
+		listeners.remove(listener);
+	}
+	
+	/**
+	 * Notifies clients that the address container changed.
+	 */
+	protected void fireContainerChanged() {
+		for (IAddressEditContainerListener listener : listeners) {
+			listener.containerChanged(this);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Node)
+	 */
+	@Override
+	public void visit(Node n) {
+		AddressNode aNode = NodeFactory.createNode(n);
+		
+		if (aNode == null) return;
+		
+		if (!assignAddressToStreet(aNode)) {
+			// Assignment failed: Street is not known (yet) -> add to 'unresolved' list 
+			unresolvedAddresses.add(aNode);
+		}
+		
+		if (!aNode.isComplete()) {
+			incompleteAddresses.add(aNode);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Way)
+	 */
+	@Override
+	public void visit(Way w) {
+		if (w.isIncomplete()) return;
+		
+		StreetSegmentNode newSegment = NodeFactory.createNodeFromWay(w);
+		
+		if (newSegment != null) {
+			String name = newSegment.getName();
+			StreetNode sNode = null;
+			if (streetDict.containsKey(name)) {
+				sNode = streetDict.get(name);
+			} else {
+				sNode = new StreetNode(w);
+				streetDict.put(name, sNode);
+			}
+			
+			if (sNode != null) {
+				sNode.addStreetSegment(newSegment);
+			} else {
+				throw new RuntimeException("Street node is null!");
+			}
+		}
+		
+		for (String key : w.keySet()) {
+			if (!tags.contains(key)) {
+				tags.add(key);
+			}
+		}
+		/*
+        for (Node n : w.getNodes()) {
+            
+        }*/
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Relation)
+	 */
+	@Override
+	public void visit(Relation e) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Changeset)
+	 */
+	@Override
+	public void visit(Changeset cs) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * Gets the dictionary contains the collected streets.
+	 * @return
+	 */
+	public HashMap<String, StreetNode> getStreetDict() {
+		return streetDict;
+	}
+	
+	public List<StreetNode> getStreetList() {
+		
+		ArrayList<StreetNode> sortedList = new ArrayList<StreetNode>(streetDict.values());
+		Collections.sort(sortedList);
+		return sortedList;
+	}
+
+	public List<AddressNode> getUnresolvedItems() {
+		return unresolvedAddresses;
+	}
+
+	public HashSet<String> getTags() {
+		return tags;
+	}
+
+	/**
+	 * Tries to assign an address to a street.
+	 * @param aNode
+	 */
+	private boolean assignAddressToStreet(AddressNode aNode) {
+		String streetName = aNode.getStreet();
+		if (streetName != null && streetDict.containsKey(streetName)) {
+			StreetNode sNode = streetDict.get(streetName);
+			sNode.addAddress(aNode);
+			//System.out.println("Resolved address " + aNode + ": " + sNode);
+			return true;
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Walks through the list of unassigned addresses and tries to assign them to streets.
+	 */
+	public void resolveAddresses() {
+		List<AddressNode> resolvedAddresses = new ArrayList<AddressNode>();
+		for (AddressNode node : unresolvedAddresses) {
+			if (assignAddressToStreet(node)) {
+				resolvedAddresses.add(node);
+			}
+		}
+		
+		System.out.println("Resolved " + resolvedAddresses.size() + " addresses");
+		
+		/* Remove all resolves nodes from unresolved list */
+		for (AddressNode resolved : resolvedAddresses) {
+			unresolvedAddresses.remove(resolved);
+		}
+		
+		System.out.println("Still unresolved: " + unresolvedAddresses.size() + " addresses");
+	}
+	
+	/**
+	 * Rebuilds the street and address lists. 
+	 */
+	public void invalidate() {
+		invalidate(Main.main.getCurrentDataSet().allPrimitives());
+	}
+	
+	public void invalidate(final Collection<? extends OsmPrimitive> osmData) {
+		if (osmData == null || osmData.isEmpty())
+			return;
+		
+		clearData();
+		for (OsmPrimitive osmPrimitive : osmData) {
+			osmPrimitive.visit(this);
+		}
+		
+		fireContainerChanged();
+	}
+	
+	public void clearData() {
+		streetDict.clear();
+		unresolvedAddresses.clear();
+	}
+	
+	/**
+	 * Connects the listener to the data set and revisits the data. This method should
+	 * be called immediately before an edit session starts.
+	 */
+	public void attachToDataSet() {
+		Main.main.getCurrentDataSet().addDataSetListener(this);
+		invalidate();
+	}
+	
+	/**
+	 * Disconnects the listener from the data set. This method should
+	 * be called immediately after an edit session has ended.
+	 */
+	public void detachFromDataSet() {
+		Main.main.getCurrentDataSet().removeDataSetListener(this);
+	}
+
+	@Override
+	public void dataChanged(DataChangedEvent event) {
+	}
+
+	@Override
+	public void nodeMoved(NodeMovedEvent event) {
+				
+	}
+
+	@Override
+	public void otherDatasetChange(AbstractDatasetChangedEvent event) {
+	}
+
+	@Override
+	public void primtivesAdded(PrimitivesAddedEvent event) {
+		invalidate();
+	}
+
+	@Override
+	public void primtivesRemoved(PrimitivesRemovedEvent event) {
+		invalidate();
+	}
+
+	@Override
+	public void relationMembersChanged(RelationMembersChangedEvent event) {
+	}
+
+	@Override
+	public void tagsChanged(TagsChangedEvent event) {
+		invalidate();		
+	}
+
+	@Override
+	public void wayNodesChanged(WayNodesChangedEvent event) {
+	}
+}
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressNode.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressNode.java	(revision 23828)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressNode.java	(revision 23829)
@@ -112,12 +112,9 @@
 		cc = this.getCountry().compareTo(other.getCountry());
 		if ( cc  == 0) {
-			cc = this.getState().compareTo(other.getState());
-			
+			cc = this.getState().compareTo(other.getState());			
 			if (cc  == 0) {
-				cc = this.getCity().compareTo(other.getCity());
-				
+				cc = this.getCity().compareTo(other.getCity());				
 				if (cc  == 0) {
-					cc = this.getStreet().compareTo(other.getStreet());
-					
+					cc = this.getStreet().compareTo(other.getStreet());					
 					if (cc  == 0) {
 						cc = this.getHouseNumber().compareTo(other.getHouseNumber());
@@ -128,4 +125,57 @@
 		
 		return cc;
+	}
+	
+	/**
+	 * Applies the street name from the specified street node.
+	 * @param node
+	 */
+	public void assignStreet(StreetNode node) {
+		if (node == null || !node.hasName()) return;
+		
+		if (!node.getName().equals(getStreet())) {
+			setStreetName(node.getName());
+			node.addAddress(this);
+		}
+	}
+	
+	/**
+	 * Sets the street name of the address node.
+	 * @param streetName
+	 */
+	public void setStreetName(String streetName) {
+		if (streetName != null && streetName.length() == 0) return;
+		
+		this.osmObject.put(TagUtils.ADDR_STREET_TAG, streetName);
+	}
+	
+	/**
+	 * Sets the state of the address node.
+	 * @param state
+	 */
+	public void setState(String state) {
+		if (state != null && state.length() == 0) return;
+		
+		this.osmObject.put(TagUtils.ADDR_STATE_TAG, state);
+	}
+	
+	/**
+	 * Sets the country of the address node.
+	 * @param country
+	 */
+	public void setCountry(String country) {
+		if (country != null && country.length() == 0) return;
+		
+		this.osmObject.put(TagUtils.ADDR_COUNTRY_TAG, country);
+	}
+	
+	/**
+	 * Sets the post code of the address node.
+	 * @param postCode
+	 */
+	public void setPostCode(String postCode) {
+		if (postCode != null && postCode.length() == 0) return;
+		
+		this.osmObject.put(TagUtils.ADDR_POSTCODE_TAG, postCode);
 	}
 
Index: plications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressVisitor.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/AddressVisitor.java	(revision 23828)
+++ 	(revision )
@@ -1,189 +1,0 @@
-/*
- * 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/>.
- */
-/**
- * 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/>.
- */
-
-/* File created on 24.10.2010 */
-package org.openstreetmap.josm.plugins.addressEdit;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-
-import org.openstreetmap.josm.data.osm.Changeset;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.data.osm.Relation;
-import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.Visitor;
-
-/**
- *
- * @author Oliver Wieland <oliver.wieland@online.de>
- * 
- */
-
-public class AddressVisitor implements Visitor {
-	private HashMap<String, StreetNode> streetDict = new HashMap<String, StreetNode>(100); 
-	private List<AddressNode> unresolvedAddresses = new ArrayList<AddressNode>(100);
-	
-	private HashSet<String> tags = new HashSet<String>();
-	
-	/* (non-Javadoc)
-	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Node)
-	 */
-	@Override
-	public void visit(Node n) {
-		AddressNode aNode = NodeFactory.createNode(n);
-		
-		if (aNode == null) return;
-		
-		if (!assignAddressToStreet(aNode)) {
-			// Assignment failed: Street is not known (yet) -> add to 'unresolved' list 
-			unresolvedAddresses.add(aNode);
-		}
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Way)
-	 */
-	@Override
-	public void visit(Way w) {
-		if (w.isIncomplete()) return;
-		
-		StreetSegmentNode newSegment = NodeFactory.createNodeFromWay(w);
-		
-		if (newSegment != null) {
-			String name = newSegment.getName();
-			StreetNode sNode = null;
-			if (streetDict.containsKey(name)) {
-				sNode = streetDict.get(name);
-			} else {
-				sNode = new StreetNode(w);
-				streetDict.put(name, sNode);
-			}
-			
-			if (sNode != null) {
-				sNode.addStreetSegment(newSegment);
-			} else {
-				throw new RuntimeException("Street node is null!");
-			}
-		}
-		
-		for (String key : w.keySet()) {
-			if (!tags.contains(key)) {
-				tags.add(key);
-			}
-		}
-		/*
-        for (Node n : w.getNodes()) {
-            
-        }*/
-	}
-
-	/* (non-Javadoc)
-	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Relation)
-	 */
-	@Override
-	public void visit(Relation e) {
-		// TODO Auto-generated method stub
-
-	}
-
-	/* (non-Javadoc)
-	 * @see org.openstreetmap.josm.data.osm.visitor.Visitor#visit(org.openstreetmap.josm.data.osm.Changeset)
-	 */
-	@Override
-	public void visit(Changeset cs) {
-		// TODO Auto-generated method stub
-
-	}
-
-	/**
-	 * Gets the dictionary contains the collected streets.
-	 * @return
-	 */
-	public HashMap<String, StreetNode> getStreetDict() {
-		return streetDict;
-	}
-	
-	public List<StreetNode> getStreetList() {
-		
-		ArrayList<StreetNode> sortedList = new ArrayList<StreetNode>(streetDict.values());
-		Collections.sort(sortedList);
-		return sortedList;
-	}
-
-	public List<AddressNode> getUnresolvedItems() {
-		return unresolvedAddresses;
-	}
-
-	public HashSet<String> getTags() {
-		return tags;
-	}
-
-	/**
-	 * Tries to assign an address to a street.
-	 * @param aNode
-	 */
-	private boolean assignAddressToStreet(AddressNode aNode) {
-		String streetName = aNode.getStreet();
-		if (streetName != null && streetDict.containsKey(streetName)) {
-			StreetNode sNode = streetDict.get(streetName);
-			sNode.addAddress(aNode);
-			//System.out.println("Resolved address " + aNode + ": " + sNode);
-			return true;
-		}
-		
-		return false;
-	}
-	
-	/**
-	 * Walks through the list of unassigned addresses and tries to assign them to streets.
-	 */
-	public void resolveAddresses() {
-		List<AddressNode> resolvedAddresses = new ArrayList<AddressNode>();
-		for (AddressNode node : unresolvedAddresses) {
-			if (assignAddressToStreet(node)) {
-				resolvedAddresses.add(node);
-			}
-		}
-		
-		System.out.println("Resolved " + resolvedAddresses.size() + " addresses");
-		
-		/* Remove all resolves nodes from unresolved list */
-		for (AddressNode resolved : resolvedAddresses) {
-			unresolvedAddresses.remove(resolved);
-		}
-		
-		System.out.println("Still unresolved: " + unresolvedAddresses.size() + " addresses");
-	}
-	
-	public void clearData() {
-		streetDict.clear();
-		unresolvedAddresses.clear();
-	}
-}
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/IAddressEditContainerListener.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/IAddressEditContainerListener.java	(revision 23829)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/IAddressEditContainerListener.java	(revision 23829)
@@ -0,0 +1,22 @@
+/*
+ * 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.addressEdit;
+
+public interface IAddressEditContainerListener {
+	/**
+	 * Notifies clients the the container has been changed
+	 * @param container
+	 */
+	public void containerChanged(AddressEditContainer container);
+}
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/StreetNode.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/StreetNode.java	(revision 23828)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/StreetNode.java	(revision 23829)
@@ -16,4 +16,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 
@@ -81,4 +83,62 @@
 	}
 	
+	/**
+	 * Gets the number of addresses associated with this street.
+	 * @return
+	 */
+	public int getNumberOfAddresses() {
+		if (addresses == null) return 0;
+		
+		return addresses.size();
+	}
+	
+	/**
+	 * Gets the number of street segments of this street.
+	 * @return
+	 */
+	public int getNumberOfSegments() {
+		if (children == null) return 0;
+		
+		int sc = 0;
+		for (INodeEntity node : children) {
+			if (node instanceof StreetSegmentNode) {
+				sc++;
+			}
+		}
+		return sc;
+	}
+	
+	/**
+	 * Gets the road type(s) of this street. If the street has different types,
+	 * they are separated by comma. 
+	 * @return
+	 */
+	public String getType() {
+		List<String> types = new ArrayList<String>();
+		
+		for (INodeEntity seg : getChildren()) {
+			OsmPrimitive osmPrim = seg.getOsmObject();
+			if (TagUtils.hasHighwayTag(osmPrim)) {
+				String val = osmPrim.get(TagUtils.HIGHWAY_TAG);
+				if (!types.contains(val)) {
+					types.add(val);
+				}
+			}
+		}
+		
+		StringBuffer sb = new StringBuffer(20);
+		for (String string : types) {
+			if (sb.length() > 0) {
+				sb.append(", ");
+			}
+			sb.append(string);
+			
+		}
+		return sb.toString();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.openstreetmap.josm.plugins.addressEdit.NodeEntityBase#toString()
+	 */
 	@Override
 	public String toString() {
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AbstractAddressEditAction.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AbstractAddressEditAction.java	(revision 23829)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AbstractAddressEditAction.java	(revision 23829)
@@ -0,0 +1,75 @@
+/*
+ * 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.addressEdit.gui;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+
+public abstract class AbstractAddressEditAction extends AbstractAction {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 3080414353417044998L;
+
+	private AddressSelectionEvent event;
+
+	/**
+	 * @param name
+	 * @param icon
+	 */
+	public AbstractAddressEditAction(String name, Icon icon) {
+		super(name, icon);
+		setEnabled(false);
+	}
+
+	/**
+	 * @param name
+	 */
+	public AbstractAddressEditAction(String name) {
+		this(name, null);
+	}
+
+	/**
+	 * Updates 'enabled' state.
+	 * @param ev
+	 * @return
+	 */
+	public void updateEnabledState(AddressSelectionEvent ev) {
+		// If the tree selection changes, we will get a new event. So this is safe.
+		this.event = ev; // save for later use.  
+	}
+
+	/* (non-Javadoc)
+	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+	 */
+	@Override
+	public void actionPerformed(ActionEvent arg0) {
+		if (event != null) { // use the event acquired previously.
+			addressEditActionPerformed(event);			
+		}
+	}
+	
+
+	/**
+	 * Redirected action handler
+	 * @param ev
+	 */
+	public abstract void addressEditActionPerformed(AddressSelectionEvent ev);
+	
+	
+
+}
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AddressEditDialog.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AddressEditDialog.java	(revision 23828)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AddressEditDialog.java	(revision 23829)
@@ -31,12 +31,28 @@
 import javax.swing.JSeparator;
 import javax.swing.JSplitPane;
+import javax.swing.JTable;
 import javax.swing.JTree;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
+import javax.swing.table.DefaultTableModel;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreeSelectionModel;
 
-public class AddressEditDialog extends JFrame implements ActionListener, TreeSelectionListener {
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
+import org.openstreetmap.josm.data.osm.event.DataSetListener;
+import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
+import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
+import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
+import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
+import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.plugins.addressEdit.AddressEditContainer;
+
+public class AddressEditDialog extends JFrame implements ActionListener, TreeSelectionListener, ListSelectionListener {
 	private static final String CANCEL_COMMAND = "Cancel";
 	private static final String OK_COMMAND = "Ok";
@@ -45,8 +61,8 @@
 	 */
 	private static final long serialVersionUID = 6251676464816335631L;
-	private AddressEditModel model;
+	private AddressEditContainer model;
 	private JTree unresolvedTree;
 	private JTree incompleteTree;
-	private JTree streetsTree;
+	private JTable streetList;
 	private DefaultMutableTreeNode selStreet;
 	private DefaultMutableTreeNode selUnrAddr;
@@ -63,28 +79,32 @@
 	 * @throws HeadlessException
 	 */
-	public AddressEditDialog(AddressEditModel model) throws HeadlessException  {
+	public AddressEditDialog(AddressEditContainer addressEditContainer) throws HeadlessException  {
 		super(tr("Edit Addresses"));
 	
-		this.model = model; 
+		this.model = addressEditContainer; 
 		setLayout(new BorderLayout());
 		setSize(800,600);
 		// TODO: Center on screen
 		setLocation(100, 100);
-
+		
 		// TODO: Proper init, if model is null
-		if (model != null) {
+		if (addressEditContainer != null) {
 			JPanel streetPanel = new JPanel(new BorderLayout());
-			streetsTree = new JTree(new DefaultTreeModel(model.getStreetsTree()));
+			/*
+			streetsTree = new JTree(new DefaultTreeModel(addressEditContainer.getStreetsTree()));
 			streetsTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
 			streetsTree.addTreeSelectionListener(this);
 			streetsTree.setCellRenderer(new StreetTreeCellRenderer());
+			*/
+			streetList = new JTable(new StreetTableModel(model));
+			streetList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 			
-			JScrollPane scroll1 = new JScrollPane(streetsTree);
+			JScrollPane scroll1 = new JScrollPane(streetList);
 			streetPanel.add(scroll1, BorderLayout.CENTER);
 			streetPanel.add(new JLabel("Unresolved Addresses"), BorderLayout.NORTH);
-			streetPanel.setMinimumSize(new Dimension(300, 400));
+			streetPanel.setMinimumSize(new Dimension(350, 400));
 			
 			JPanel unresolvedPanel = new JPanel(new BorderLayout());		
-			unresolvedTree = new JTree(new DefaultTreeModel(model.getUnresolvedAddressesTree()));
+			unresolvedTree = new JTree(new DefaultTreeModel(new DefaultMutableTreeNode()));
 			unresolvedTree.addTreeSelectionListener(this);
 			
@@ -92,5 +112,5 @@
 			unresolvedPanel.add(scroll2, BorderLayout.CENTER);
 			unresolvedPanel.add(new JLabel("Unresolved Addresses"), BorderLayout.NORTH);
-			unresolvedPanel.setMinimumSize(new Dimension(300, 200));
+			unresolvedPanel.setMinimumSize(new Dimension(350, 200));
 			
 			JPanel unresolvedButtons = new JPanel(new FlowLayout());
@@ -100,10 +120,10 @@
 			
 			JPanel incompletePanel = new JPanel(new BorderLayout());
-			incompleteTree = new JTree(new DefaultTreeModel(model.getIncompleteAddressesTree()));
+			incompleteTree = new JTree(new DefaultTreeModel(new DefaultMutableTreeNode()));
 			incompleteTree.addTreeSelectionListener(this);
 			JScrollPane scroll3 = new JScrollPane(incompleteTree);
 			incompletePanel.add(scroll3, BorderLayout.CENTER);
 			incompletePanel.add(new JLabel("Incomplete Addresses"), BorderLayout.NORTH);
-			incompletePanel.setMinimumSize(new Dimension(300, 200));
+			incompletePanel.setMinimumSize(new Dimension(350, 200));
 			
 			JSplitPane addrSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, unresolvedPanel, incompletePanel);
@@ -112,4 +132,5 @@
 			this.getContentPane().add(pane, BorderLayout.CENTER);
 		} else {
+			streetList = new JTable(new DefaultTableModel());
 			this.getContentPane().add(new JLabel(tr("(No data)")), BorderLayout.CENTER);
 		}
@@ -131,19 +152,4 @@
 	}
 
-	public AddressEditModel getModel() {
-		return model;
-	}
-
-	public void setModel(AddressEditModel model) {
-		if (this.model != model) {
-			this.model = model;
-			if (model != null) {
-				streetsTree.setModel(new DefaultTreeModel(model.getStreetsTree()));
-				unresolvedTree.setModel(new DefaultTreeModel(model.getUnresolvedAddressesTree()));
-				incompleteTree.setModel(new DefaultTreeModel(model.getIncompleteAddressesTree()));
-			}
-		}
-	}
-
 	@Override
 	public void actionPerformed(ActionEvent e) {
@@ -161,21 +167,22 @@
 	public void valueChanged(TreeSelectionEvent event) {
 		// Updates the selection
-		if (event.getSource() == streetsTree) {
-			selStreet = (DefaultMutableTreeNode) streetsTree.getLastSelectedPathComponent();
+		if (event.getSource() == streetList) {
+			int selStr = streetList.getSelectedRow();
+			 
 		}
 		
-		if (event.getSource() == unresolvedTree) {
-			selUnrAddr = (DefaultMutableTreeNode) unresolvedTree.getLastSelectedPathComponent();
-		}
-		
-		if (event.getSource() == incompleteTree) {
-			selIncAddr = (DefaultMutableTreeNode) incompleteTree.getLastSelectedPathComponent();
-		}
-		
+		/*
 		AddressSelectionEvent ev = new AddressSelectionEvent(event.getSource(),
 				selStreet, selUnrAddr, selIncAddr);		
 		for (AbstractAddressEditAction action : actions) {
 			action.updateEnabledState(ev);
-		}
+		}*/
 	}
+
+	@Override
+	public void valueChanged(ListSelectionEvent e) {
+		// TODO Auto-generated method stub
+		
+	}
+
 }
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AddressSelectionEvent.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AddressSelectionEvent.java	(revision 23829)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AddressSelectionEvent.java	(revision 23829)
@@ -0,0 +1,47 @@
+/*
+ * 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.addressEdit.gui;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+public class AddressSelectionEvent extends ActionEvent {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -93034483427803409L;
+	private DefaultMutableTreeNode selStreet;
+	private DefaultMutableTreeNode unresolvedAddr;
+	private DefaultMutableTreeNode incomplete;
+	
+	public AddressSelectionEvent(Object source, DefaultMutableTreeNode selStreet, DefaultMutableTreeNode unresolvedAddr, DefaultMutableTreeNode incomplete ) {
+		super(source, -1, "");
+		this.selStreet = selStreet;
+		this.unresolvedAddr = unresolvedAddr;
+		this.incomplete = incomplete;
+	}
+	
+	public DefaultMutableTreeNode getSelectedStreet() {
+		return selStreet;
+	}
+
+	public DefaultMutableTreeNode getSelectedUnresolvedAddress() {
+		return unresolvedAddr;
+	}
+
+	public DefaultMutableTreeNode getSelectedIncompleteAddress() {
+		return incomplete;
+	}
+}
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AssignAddressToStreetAction.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AssignAddressToStreetAction.java	(revision 23829)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/AssignAddressToStreetAction.java	(revision 23829)
@@ -0,0 +1,67 @@
+/*
+ * 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.addressEdit.gui;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import org.openstreetmap.josm.plugins.addressEdit.AddressNode;
+import org.openstreetmap.josm.plugins.addressEdit.StreetNode;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+public class AssignAddressToStreetAction extends AbstractAddressEditAction {
+
+	public AssignAddressToStreetAction() {
+		super(tr("Assign address to street"));
+		// TODO Auto-generated constructor stub
+	}
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -6180491357232121384L;
+
+	@Override
+	public void addressEditActionPerformed(AddressSelectionEvent ev) {
+		DefaultMutableTreeNode streetNode = ev.getSelectedStreet();
+		StreetNode sNode = null;
+		AddressNode aNode = null;
+		
+		if (streetNode != null) {
+			sNode = (StreetNode) streetNode.getUserObject();
+		}
+		
+		DefaultMutableTreeNode addrNode = ev.getSelectedUnresolvedAddress();
+		if (addrNode != null) {
+			aNode = (AddressNode) addrNode.getUserObject();
+		}
+		
+		if (sNode != null && aNode != null) {
+			System.out.println("Assign " + aNode + " top " + sNode);
+			
+			aNode.assignStreet(sNode);
+			addrNode.removeFromParent();			
+		}		
+	}
+
+	@Override
+	public void updateEnabledState(AddressSelectionEvent ev) {
+		super.updateEnabledState(ev);
+		setEnabled(ev.getSelectedStreet() != null && ev.getSelectedUnresolvedAddress() != null);
+	}
+
+
+}
Index: /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/StreetTableModel.java
===================================================================
--- /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/StreetTableModel.java	(revision 23829)
+++ /applications/editors/josm/plugins/AddressEdit/src/org/openstreetmap/josm/plugins/addressEdit/gui/StreetTableModel.java	(revision 23829)
@@ -0,0 +1,93 @@
+/*
+ * 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.addressEdit.gui;
+
+import javax.swing.table.DefaultTableModel;
+import static org.openstreetmap.josm.tools.I18n.tr;
+import org.openstreetmap.josm.plugins.addressEdit.AddressEditContainer;
+import org.openstreetmap.josm.plugins.addressEdit.StreetNode;
+
+public class StreetTableModel extends DefaultTableModel {
+
+	private static final int NUMBER_OF_COLUMNS = 4;
+	private static final String[] COLUMN_NAMES = new String[]{tr("Type"), tr("Name"), tr("Segments"), tr("Addresses")}; 
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 424009321818130586L;
+
+	private AddressEditContainer addressContainer;
+
+	/**
+	 * @param addressContainer
+	 */
+	public StreetTableModel(AddressEditContainer addressContainer) {
+		super();
+		this.addressContainer = addressContainer;
+	}
+
+	@Override
+	public int getColumnCount() {
+		// TODO Auto-generated method stub
+		return NUMBER_OF_COLUMNS;
+	}
+
+	@Override
+	public String getColumnName(int column) {
+		return COLUMN_NAMES[column];
+	}
+
+	@Override
+	public int getRowCount() {
+		if (addressContainer == null || addressContainer.getStreetList() == null) {
+			return 0;
+		}
+		return addressContainer.getStreetList().size();
+	}
+
+	@Override
+	public Object getValueAt(int row, int column) {
+		if (addressContainer == null || addressContainer.getStreetList() == null) {
+			return null;
+		}
+		if (row < 0 || row > addressContainer.getStreetList().size()) {
+			return null;
+		}
+		StreetNode sNode = addressContainer.getStreetList().get(row);
+		
+		switch (column) {
+		case 0:
+			return sNode.getType();
+		case 1:
+			return sNode.getName();
+		case 2:
+			return sNode.getNumberOfSegments();
+		case 3:
+			return sNode.getNumberOfAddresses();
+		default:
+			throw new RuntimeException("Invalid column index: " + column);
+		}
+		
+	}
+
+	@Override
+	public boolean isCellEditable(int row, int column) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+	
+	
+	
+}
