Index: applications/editors/josm/plugins/buildings_tools/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- applications/editors/josm/plugins/buildings_tools/.settings/org.eclipse.jdt.core.prefs	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/.settings/org.eclipse.jdt.core.prefs	(revision 21801)
@@ -1,3 +1,3 @@
-#Wed May 12 12:21:49 MSD 2010
+#Sat Jun 19 21:24:56 MSD 2010
 eclipse.preferences.version=1
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
@@ -243,4 +243,6 @@
 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=false
 org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
Index: applications/editors/josm/plugins/buildings_tools/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- applications/editors/josm/plugins/buildings_tools/.settings/org.eclipse.jdt.ui.prefs	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/.settings/org.eclipse.jdt.ui.prefs	(revision 21801)
@@ -1,5 +1,56 @@
-#Wed May 12 12:21:49 MSD 2010
+#Sat Jun 19 21:24:56 MSD 2010
 eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
 formatter_profile=_BTProf
 formatter_settings_version=11
-org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
Index: applications/editors/josm/plugins/buildings_tools/build.xml
===================================================================
--- applications/editors/josm/plugins/buildings_tools/build.xml	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/build.xml	(revision 21801)
@@ -33,5 +33,5 @@
 	<property name="commit.message" value="fix address dialog" />
 	<!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-	<property name="plugin.main.version" value="2830" />
+	<property name="plugin.main.version" value="3177" />
 
 
@@ -111,5 +111,4 @@
 				<attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
 				<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
-		                <attribute name="2561_Plugin-Url" value="29;http://upliner.openstreetmap.ru/josm/buildings_tools/2561/buildings_tools.jar"/>
 			</manifest>
 		</jar>
Index: applications/editors/josm/plugins/buildings_tools/src/buildings_tools/AdvancedSettingsDialog.java
===================================================================
--- applications/editors/josm/plugins/buildings_tools/src/buildings_tools/AdvancedSettingsDialog.java	(revision 21801)
+++ applications/editors/josm/plugins/buildings_tools/src/buildings_tools/AdvancedSettingsDialog.java	(revision 21801)
@@ -0,0 +1,47 @@
+package buildings_tools;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import static buildings_tools.BuildingSizeDialog.addLabelled;
+
+import java.awt.GridBagLayout;
+
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.tools.GBC;
+
+public class AdvancedSettingsDialog extends ExtendedDialog {
+	// TODO: Replace tag textbox to full-fledged tag editor
+	JTextField tBTag = new JTextField();
+	JCheckBox cBigMode = new JCheckBox("Big buildings mode");
+
+	public AdvancedSettingsDialog() {
+		super(Main.parent, tr("Advanced settings"),
+				new String[] { tr("OK"), tr("Cancel") },
+				true);
+		contentConstraints = GBC.eol().fill().insets(15, 15, 15, 5);
+		setButtonIcons(new String[] { "ok.png", "cancel.png" });
+
+		final JPanel panel = new JPanel(new GridBagLayout());
+		addLabelled(panel, tr("Building tag:"), tBTag);
+		panel.add(cBigMode, GBC.eol().fill(GBC.HORIZONTAL));
+
+		tBTag.setText(ToolSettings.getTag());
+		cBigMode.setSelected(ToolSettings.isBBMode());
+
+		setContent(panel);
+		setupDialog();
+		setVisible(true);
+	}
+
+	public String getTag() {
+		return tBTag.getText();
+	}
+
+	public boolean isBBMode() {
+		return cBigMode.isSelected();
+	}
+}
Index: applications/editors/josm/plugins/buildings_tools/src/buildings_tools/Building.java
===================================================================
--- applications/editors/josm/plugins/buildings_tools/src/buildings_tools/Building.java	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/src/buildings_tools/Building.java	(revision 21801)
@@ -29,42 +29,65 @@
 	private EastNorth en3;
 	private EastNorth en4;
-	
+
 	private EastNorth p1;
 	private Node node;
 	double meter = 0;
-	
+
 	private double len = 0;
-	private double lwidth;
+	private double width;
 	private double heading;
-	private boolean angconstrainted;
-	private double angconstraint = 0;
-	
+	private boolean angConstrained;
+	private double angConstraint = 0;
+
 	public void disableAngConstraint() {
-		angconstrainted = false;
-	}
+		angConstrained = false;
+	}
+
 	public void setAngConstraint(double angle) {
-		angconstrainted = true;
-		angconstraint = angle;
-		while (angconstraint>(Math.PI/4)) angconstraint-=Math.PI/4;
-	}
+		angConstrained = true;
+		angConstraint = angle;
+	}
+
 	public double getLength() {
 		return len;
 	}
-	
+
+	public double getWidth() {
+		return width;
+	}
+
+	public boolean isRectDrawing() {
+		return angConstrained && ToolSettings.getWidth() == 0 && ToolSettings.getLenStep() == 0;
+	}
+
 	public void reset() {
 		len = 0;
-		en1=null;
-		en2=null;
-		en3=null;
-		en4=null;
-	}
-	public EastNorth Point1() { return en1; }
-	public EastNorth Point2() { return en2; }
-	public EastNorth Point3() { return en3; }
-	public EastNorth Point4() { return en4; }
+		en1 = null;
+		en2 = null;
+		en3 = null;
+		en4 = null;
+	}
+
+	public EastNorth point1() {
+		return en1;
+	}
+
+	public EastNorth point2() {
+		return en2;
+	}
+
+	public EastNorth point3() {
+		return en3;
+	}
+
+	public EastNorth point4() {
+		return en4;
+	}
+
 	private void updMetrics() {
-		meter = 2*Math.PI/(Math.cos(Math.toRadians(eastNorth2latlon(p1).lat())) * eqlen);
+		meter = 2 * Math.PI / (Math.cos(Math.toRadians(eastNorth2latlon(p1).lat())) * eqlen);
 		reset();
 	}
+
 	public void setBase(EastNorth base) {
 		node = null;
@@ -72,4 +95,5 @@
 		updMetrics();
 	}
+
 	public void setBase(Node base) {
 		node = base;
@@ -77,35 +101,86 @@
 		updMetrics();
 	}
+
+	/**
+	 * @returns Projection of the point to the heading vector in metres
+	 */
+	private double projection1(EastNorth p) {
+		final EastNorth vec = p1.sub(p);
+		return (Math.sin(heading) * vec.east() + Math.cos(heading) * vec.north()) / meter;
+	}
+
+	/**
+	 * @returns Projection of the point to the perpendicular of the heading
+	 *          vector in metres
+	 */
+	private double projection2(EastNorth p) {
+		final EastNorth vec = p1.sub(p);
+		return (Math.cos(heading) * vec.east() - Math.sin(heading) * vec.north()) / meter;
+	}
+
 	private void updatePos() {
+		if (len == 0)
+			return;
 		en1 = p1;
-		en2 = new EastNorth(p1.east()+Math.sin(heading)*len*meter,p1.north()+Math.cos(heading)*len*meter);
-		en3 = new EastNorth(p1.east()+Math.sin(heading)*len*meter+Math.cos(heading)*lwidth*meter,p1.north()+Math.cos(heading)*len*meter-Math.sin(heading)*lwidth*meter);
-		en4 = new EastNorth(p1.east()+Math.cos(heading)*lwidth*meter,p1.north()-Math.sin(heading)*lwidth*meter);
-	}
-	public void setPlace(EastNorth p2,double width,double lenstep,boolean ignoreConstraint) {
-		heading = p1.heading(p2);
+		en2 = new EastNorth(p1.east() + Math.sin(heading) * len * meter, p1.north() + Math.cos(heading) * len * meter);
+		en3 = new EastNorth(p1.east() + Math.sin(heading) * len * meter + Math.cos(heading) * width * meter, p1.north()
+				+ Math.cos(heading) * len * meter - Math.sin(heading) * width * meter);
+		en4 = new EastNorth(p1.east() + Math.cos(heading) * width * meter, p1.north() - Math.sin(heading) * width
+				* meter);
+	}
+
+	public void setLengthWidth(double length, double width) {
+		this.len = length;
+		this.width = width;
+		updatePos();
+	}
+
+	public void setWidth(EastNorth p3) {
+		this.width = projection2(p3);
+		updatePos();
+	}
+
+	public void setPlace(EastNorth p2, double width, double lenstep, boolean ignoreConstraints) {
+		this.heading = p1.heading(p2);
 		double hdang = 0;
-		if (angconstrainted && !ignoreConstraint) {
-			hdang = Math.round((heading-angconstraint)/Math.PI*4);
-			if (hdang>=8)hdang-=8;
-			if (hdang<0)hdang+=8;
-			heading = hdang*Math.PI/4+angconstraint;
-		}
-		double distance = eastNorth2latlon(p1).greatCircleDistance(eastNorth2latlon(p2));
-		if (lenstep <= 0) len=distance; else len = Math.round(distance/lenstep)*lenstep;
-		if (len == 0) return;
-		lwidth = width;
+		if (angConstrained && !ignoreConstraints) {
+			hdang = Math.round((heading - angConstraint) / Math.PI * 4);
+			hdang = hdang % 8;
+			if (hdang < 0)
+				hdang += 8;
+			heading = (hdang * Math.PI / 4 + angConstraint) % (2 * Math.PI);
+		}
+
+		this.width = width;
+		this.len = projection1(p2);
+		if (lenstep > 0 && !ignoreConstraints)
+			this.len = Math.round(this.len / lenstep) * lenstep;
+
 		updatePos();
+
 		Main.map.statusLine.setHeading(Math.toDegrees(heading));
-		if (angconstrainted && !ignoreConstraint) {
-			Main.map.statusLine.setAngle(hdang*45);
-		}
-	}
-	public void setWidth(double width) {
-		lwidth = width;
-		updatePos();
-	}
+		if (angConstrained && !ignoreConstraints) {
+			Main.map.statusLine.setAngle(hdang * 45);
+		}
+	}
+
+	public void setPlaceRect(EastNorth p2) {
+		if (!isRectDrawing())
+			throw new IllegalStateException("Invalid drawing mode");
+		heading = angConstraint;
+		setLengthWidth(projection1(p2), projection2(p2));
+		Main.map.statusLine.setHeading(Math.toDegrees(heading));
+	}
+
+	public void angFix(EastNorth point) {
+		EastNorth en3 = this.en3;
+		heading = p1.heading(point);
+		setLengthWidth(projection1(en3), projection2(en3));
+		this.en3 = en3;
+	}
+
 	public void paint(Graphics2D g, MapView mv) {
-		if (len == 0) return;
+		if (len == 0)
+			return;
 		GeneralPath b = new GeneralPath();
 		Point pp1 = mv.getPoint(eastNorth2latlon(en1));
@@ -114,13 +189,17 @@
 		Point pp4 = mv.getPoint(eastNorth2latlon(en3));
 
-		b.moveTo(pp1.x, pp1.y); b.lineTo(pp3.x, pp3.y);
-		b.lineTo(pp4.x, pp4.y); b.lineTo(pp2.x, pp2.y);
+		b.moveTo(pp1.x, pp1.y);
+		b.lineTo(pp3.x, pp3.y);
+		b.lineTo(pp4.x, pp4.y);
+		b.lineTo(pp2.x, pp2.y);
 		b.lineTo(pp1.x, pp1.y);
 		g.draw(b);
 	}
+
 	public Way create() {
-		if (len == 0) return null;
+		if (len == 0)
+			return null;
 		Node n1;
-		if (node==null) 
+		if (node == null)
 			n1 = new Node(eastNorth2latlon(en1));
 		else
@@ -129,13 +208,13 @@
 		Node n3 = new Node(eastNorth2latlon(en3));
 		Node n4 = new Node(eastNorth2latlon(en4));
-		if (n1.getCoor().isOutSideWorld()||n2.getCoor().isOutSideWorld()||
-				n3.getCoor().isOutSideWorld()||n4.getCoor().isOutSideWorld()) {
+		if (n1.getCoor().isOutSideWorld() || n2.getCoor().isOutSideWorld() ||
+				n3.getCoor().isOutSideWorld() || n4.getCoor().isOutSideWorld()) {
 			JOptionPane.showMessageDialog(Main.parent,
-				tr("Cannot place building outside of the world."));
+					tr("Cannot place building outside of the world."));
 			return null;
 		}
 		Way w = new Way();
 		w.addNode(n1);
-		if (lwidth>=0) {
+		if (projection1(en3) > 0) {
 			w.addNode(n2);
 			w.addNode(n3);
@@ -147,7 +226,8 @@
 		}
 		w.addNode(n1);
-		w.put("building", "yes");
+		w.put("building", ToolSettings.getTag());
 		Collection<Command> cmds = new LinkedList<Command>();
-		if (node==null) cmds.add(new AddCommand(n1));
+		if (node == null)
+			cmds.add(new AddCommand(n1));
 		cmds.add(new AddCommand(n2));
 		cmds.add(new AddCommand(n3));
Index: applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeAction.java
===================================================================
--- applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeAction.java	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeAction.java	(revision 21801)
@@ -11,21 +11,20 @@
 @SuppressWarnings("serial")
 public class BuildingSizeAction extends JosmAction {
-	
+
 	public BuildingSizeAction() {
-		super(tr("Set buildings size"),"mapmode/building",tr("Set buildings size"),
+		super(tr("Set buildings size"), "mapmode/building", tr("Set buildings size"),
 				Shortcut.registerShortcut("edit:buildingsdialog",
-				        tr("Edit: {0}", tr("Set buildings size")),
-				        KeyEvent.VK_W, Shortcut.GROUP_EDIT, 
-				        Shortcut.SHIFT_DEFAULT),
+				tr("Edit: {0}", tr("Set buildings size")),
+				KeyEvent.VK_W, Shortcut.GROUP_EDIT,
+				Shortcut.SHIFT_DEFAULT),
 				true);
 	}
+
 	public void actionPerformed(ActionEvent arg0) {
 		BuildingSizeDialog dlg = new BuildingSizeDialog();
-		int answer = dlg.getValue();
-		if (answer == 1) {
-			DrawBuildingAction.SetSizes(dlg.width(), dlg.lenstep());
-			DrawBuildingAction.SetAddrDialog(dlg.useAddr());
+		if (dlg.getValue() == 1) {
+			ToolSettings.setSizes(dlg.width(), dlg.lenstep());
+			ToolSettings.setAddrDialog(dlg.useAddr());
 		}
 	}
-
 }
Index: applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeDialog.java
===================================================================
--- applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeDialog.java	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/src/buildings_tools/BuildingSizeDialog.java	(revision 21801)
@@ -5,7 +5,10 @@
 import java.awt.Component;
 import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.text.NumberFormat;
 import java.text.ParseException;
 
+import javax.swing.JButton;
 import javax.swing.JFormattedTextField;
 import javax.swing.JCheckBox;
@@ -21,7 +24,7 @@
 	private JFormattedTextField twidth = new JFormattedTextField(NumberFormat.getInstance());
 	private JFormattedTextField tlenstep = new JFormattedTextField(NumberFormat.getInstance());
-	private JPanel panel = new JPanel(new GridBagLayout());
 	private JCheckBox caddr = new JCheckBox(tr("Use Address dialog"));
-	private void addLabelled(String str, Component c) {
+
+	static void addLabelled(JPanel panel, String str, Component c) {
 		JLabel label = new JLabel(str);
 		panel.add(label, GBC.std());
@@ -29,34 +32,55 @@
 		panel.add(c, GBC.eol().fill(GBC.HORIZONTAL));
 	}
+
 	public BuildingSizeDialog() {
-		super(Main.parent, tr("Set buildings size"), 
+		super(Main.parent, tr("Set buildings size"),
 				new String[] { tr("OK"), tr("Cancel") },
 				true);
-		contentConstraints = GBC.eol().fill().insets(15,15,15,5);
-		setButtonIcons(new String[] {"ok.png", "cancel.png" });
-		
-		addLabelled(tr("Buildings width:"),twidth);
-		addLabelled(tr("Length step:"),tlenstep);
-		twidth.setValue(DrawBuildingAction.getWidth());
-		tlenstep.setValue(DrawBuildingAction.getLenStep());
-		panel.add(caddr,GBC.eol().fill(GBC.HORIZONTAL));
+		contentConstraints = GBC.eol().fill().insets(15, 15, 15, 5);
+		setButtonIcons(new String[] { "ok.png", "cancel.png" });
+
+		final JPanel panel = new JPanel(new GridBagLayout());
+		addLabelled(panel, tr("Buildings width:"), twidth);
+		addLabelled(panel, tr("Length step:"), tlenstep);
+		panel.add(caddr, GBC.eol().fill(GBC.HORIZONTAL));
+
+		twidth.setValue(ToolSettings.getWidth());
+		tlenstep.setValue(ToolSettings.getLenStep());
+		caddr.setSelected(ToolSettings.isUsingAddr());
+
+		JButton bAdv = new JButton(tr("Advanced..."));
+		bAdv.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				AdvancedSettingsDialog dlg = new AdvancedSettingsDialog();
+				if (dlg.getValue() == 1) {
+					ToolSettings.setTag(dlg.getTag());
+					ToolSettings.setBBMode(dlg.isBBMode());
+				}
+			}
+		});
+		panel.add(bAdv, GBC.eol().insets(0, 5, 0, 0).anchor(GBC.EAST));
+
 		setContent(panel);
 		setupDialog();
 		setVisible(true);
 	}
+
 	public double width() {
 		try {
 			return NumberFormat.getInstance().parse(twidth.getText()).doubleValue();
-		} catch (ParseException e) {			
+		} catch (ParseException e) {
 			return 0;
 		}
 	}
+
 	public double lenstep() {
 		try {
 			return NumberFormat.getInstance().parse(tlenstep.getText()).doubleValue();
-		} catch (ParseException e) {			
-		  return 0;
+		} catch (ParseException e) {
+			return 0;
 		}
 	}
+
 	public boolean useAddr() {
 		return caddr.isSelected();
Index: applications/editors/josm/plugins/buildings_tools/src/buildings_tools/DrawBuildingAction.java
===================================================================
--- applications/editors/josm/plugins/buildings_tools/src/buildings_tools/DrawBuildingAction.java	(revision 21798)
+++ applications/editors/josm/plugins/buildings_tools/src/buildings_tools/DrawBuildingAction.java	(revision 21801)
@@ -38,38 +38,19 @@
 @SuppressWarnings("serial")
 public class DrawBuildingAction extends MapMode 
-implements MapViewPaintable, AWTEventListener, SelectionChangedListener
-{
-	enum Mode {None, Drawing, DrawingWidth}
+implements MapViewPaintable, AWTEventListener, SelectionChangedListener {
+	enum Mode {None, Drawing, DrawingWidth, DrawingAngFix}
 	final private Cursor cursorCrosshair;
 	final private Cursor cursorJoinNode;
 	private Cursor currCursor;
 	
-	private static double width = 0;
-	private static double lenstep = 0;
-	private static boolean useAddr;
-	
 	private Mode mode = Mode.None;
-	private EastNorth p1,p2,p3;
+	private Mode nextMode = Mode.None;
+	
 	private Color selectedColor;
 	private Point mousePos;
-	
 	private Point drawStartPos;
 	
 	Building building = new Building();
 	
-	public static void SetAddrDialog(boolean _useAddr) {
-		useAddr = _useAddr;
-	}
-	public static void SetSizes(double newwidth,double newlenstep) {
-		width = newwidth;
-		lenstep = newlenstep;
-	}
-	public static double getWidth() {
-		return width;
-	}
-	
-	public static double getLenStep() {
-		return lenstep;
-	}
 	public DrawBuildingAction(MapFrame mapFrame) {
 		super(tr("Draw buildings"),"building",tr("Draw buildings"),
@@ -136,5 +117,5 @@
 		Main.map.mapView.addTemporaryLayer(this);
 		DataSet.selListeners.add(this);
-		UpdateConstraint(getCurrentDataSet().getSelected());
+		updateConstraint(getCurrentDataSet().getSelected());
 		try {
 			Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
@@ -159,5 +140,9 @@
 		if(Main.map == null || Main.map.mapView == null)
 			return;
+		Main.map.statusLine.setHeading(-1);
+  		Main.map.statusLine.setAngle(-1);
+  		building.reset();
 		Main.map.mapView.repaint();
+		updateStatusLine();
 	}
 
@@ -168,45 +153,60 @@
 			cancelDrawing();
 	}
-
-	private void ProcessMouseEvent(MouseEvent e) {
+	
+	private EastNorth getPoint(MouseEvent e) {
+		Node n;
+		if (e.isControlDown()) {
+			n = null;
+		} else { 
+			n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isUsablePredicate);
+		}
+		if (n == null) {
+			return latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y));
+		} else {
+			return latlon2eastNorth(n.getCoor());
+		}
+	}
+	
+	private Mode modeDrawing(MouseEvent e) {
+		EastNorth p = getPoint(e);
+		if (building.isRectDrawing() && (!e.isShiftDown() || ToolSettings.isBBMode())) {
+			building.setPlaceRect(p);
+			return e.isShiftDown() ? Mode.DrawingAngFix : Mode.None;
+		} else {
+			building.setPlace(p, ToolSettings.getWidth(),
+					ToolSettings.getLenStep(),e.isShiftDown());
+			Main.map.statusLine.setDist(building.getLength());
+			return this.nextMode = ToolSettings.getWidth() == 0? Mode.DrawingWidth : Mode.None;
+		}
+	}
+
+	private Mode modeDrawingWidth(MouseEvent e) {
+		building.setWidth(getPoint(e));
+		Main.map.statusLine.setDist(Math.abs(building.getWidth()));
+		return Mode.None;
+	}
+
+	private Mode modeDrawingAngFix(MouseEvent e) {
+		building.angFix(getPoint(e));
+		return Mode.None;
+	}
+
+	private void processMouseEvent(MouseEvent e) {
 		mousePos = e.getPoint();
-		if (mode == Mode.None) return;
-		Node n;
+		if (mode == Mode.None) {
+			nextMode = Mode.None;
+			return;
+		}
+
 		if (mode == Mode.Drawing) {
-			if (e.isControlDown()) {
-				n = null;
-			} else { 
-				n = Main.map.mapView.getNearestNode(mousePos);
-			}
-			if (n == null) {
-				p2 = latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y));
-			} else {
-				p2 = latlon2eastNorth(n.getCoor());
-			}
-			building.setPlace(p2, width, e.isShiftDown()?0:lenstep,e.isShiftDown());
-			Main.map.statusLine.setDist(building.getLength());
-			return;
-		}
-		if (mode == Mode.DrawingWidth) {
-			if (e.isControlDown()) { 
-				n = null;
-			} else {
-				n = Main.map.mapView.getNearestNode(mousePos);
-			}
-			if (n == null) {
-				p3 = latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y));
-			} else {
-				p3 = latlon2eastNorth(n.getCoor());
-			}
-			double mwidth =
-				((p3.east()-p2.east())*(p2.north()-p1.north())+
-				 (p3.north()-p2.north())*(p1.east()-p2.east()))
-				/p1.distanceSq(p2) * building.getLength();
-			
-			building.setWidth(mwidth);
-			Main.map.statusLine.setDist(Math.abs(mwidth));			
-			return;
-		}
-	}
+			nextMode = modeDrawing(e);
+		} else if (mode == Mode.DrawingWidth) {
+			nextMode = modeDrawingWidth(e);
+		} else if (mode == Mode.DrawingAngFix) {
+			nextMode = modeDrawingAngFix(e);
+		} else
+			throw new AssertionError("Invalid drawing mode");
+	}
+	
 	public void paint(Graphics2D g, MapView mv,Bounds bbox)
 	{
@@ -228,10 +228,8 @@
 		drawStartPos = mousePos;
 		
-		Node n = Main.map.mapView.getNearestNode(mousePos);
+		Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isUsablePredicate);
 		if (n == null) {
-			p1 = latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y));
-			building.setBase(p1);
+			building.setBase(latlon2eastNorth(Main.map.mapView.getLatLon(mousePos.x, mousePos.y)));
 		} else {
-			p1 = latlon2eastNorth(n.getCoor());
 			building.setBase(n);
 		}
@@ -241,22 +239,20 @@
 
 	private void drawingAdvance(MouseEvent e) {
-		ProcessMouseEvent(e);
-		if (building.getLength() > 0) {
-			if (width == 0 && mode == Mode.Drawing) {
-				p2 = building.Point2();
-				mode = Mode.DrawingWidth;
-				updateStatusLine();
-				return;
-			}
+		processMouseEvent(e);
+		if (this.mode != Mode.None && this.nextMode == Mode.None) {
+			drawingFinish();
+		} else {
+			mode = this.nextMode;
+			updateStatusLine();
+		}
+	}
+	
+	private void drawingFinish() {
+		if (building.getLength() != 0) {
 			Way w = building.create();
-			if (w != null && useAddr)
+			if (w != null && ToolSettings.isUsingAddr())
 				showAddrDialog(w);
 		}
-		Main.map.mapView.repaint();
-		mode = Mode.None;
-		Main.map.statusLine.setHeading(-1);
-  		Main.map.statusLine.setAngle(-1);
-  		building.reset();
-		updateStatusLine();
+		cancelDrawing();
 	}
 
@@ -270,5 +266,5 @@
 
 	@Override public void mouseDragged(MouseEvent e) {
-		ProcessMouseEvent(e);
+		processMouseEvent(e);
 		updCursor();
 		if (mode!=Mode.None) Main.map.mapView.repaint();
@@ -283,11 +279,13 @@
 		drawStartPos = null;
 
-		if ((mode == Mode.Drawing && dragged) || mode == Mode.DrawingWidth)
-			drawingAdvance(e);
+		if (mode == Mode.Drawing && !dragged) return;
+		if (mode == Mode.None) return;
+
+		drawingAdvance(e);
 	}
 	
 	private void updCursor() {
 		if (mousePos==null) return;
-		Node n = Main.map.mapView.getNearestNode(mousePos);
+		Node n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isUsablePredicate);
 		if (n != null) setCursor(cursorJoinNode); else setCursor(cursorCrosshair);
 
@@ -295,5 +293,5 @@
 	@Override public void mouseMoved(MouseEvent e) {
 		if(!Main.map.mapView.isActiveLayerDrawable()) return;
-		ProcessMouseEvent(e);
+		processMouseEvent(e);
 		updCursor();
 		if (mode!=Mode.None) Main.map.mapView.repaint();
@@ -301,7 +299,7 @@
 
 	@Override public String getModeHelpText() {
-		if (mode==Mode.None) return tr("Point on the corner of building to start drawing");
-		if (mode==Mode.Drawing) return tr("Point on opposite end of building");
-		if (mode==Mode.DrawingWidth) return tr("Set width of building");
+		if (mode==Mode.None) return tr("Point on the corner of the building to start drawing");
+		if (mode==Mode.Drawing) return tr("Point on opposite end of the building");
+		if (mode==Mode.DrawingWidth) return tr("Set width of the building");
 		return "";
 	}
@@ -311,5 +309,5 @@
 	}
 	
-	public void UpdateConstraint(Collection<? extends OsmPrimitive> newSelection) {
+	public void updateConstraint(Collection<? extends OsmPrimitive> newSelection) {
 		building.disableAngConstraint();
 		if (newSelection.size()!=2)return;
@@ -323,5 +321,5 @@
 	
 	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-		UpdateConstraint(newSelection);
+		updateConstraint(newSelection);
 	}
 }
Index: applications/editors/josm/plugins/buildings_tools/src/buildings_tools/ToolSettings.java
===================================================================
--- applications/editors/josm/plugins/buildings_tools/src/buildings_tools/ToolSettings.java	(revision 21801)
+++ applications/editors/josm/plugins/buildings_tools/src/buildings_tools/ToolSettings.java	(revision 21801)
@@ -0,0 +1,46 @@
+package buildings_tools;
+
+public class ToolSettings {
+	private static double width = 0;
+	private static double lenstep = 0;
+	private static boolean useAddr;
+	private static String tag = "yes";
+	private static boolean bbMode;
+
+	public static void setAddrDialog(boolean _useAddr) {
+		useAddr = _useAddr;
+	}
+
+	public static void setSizes(double newwidth, double newlenstep) {
+		width = newwidth;
+		lenstep = newlenstep;
+	}
+
+	public static double getWidth() {
+		return width;
+	}
+
+	public static double getLenStep() {
+		return lenstep;
+	}
+
+	public static boolean isUsingAddr() {
+		return useAddr;
+	}
+
+	public static void setTag(String newtag) {
+		tag = newtag;
+	}
+
+	public static String getTag() {
+		return tag;
+	}
+
+	public static void setBBMode(boolean _bbmode) {
+		bbMode = _bbmode;
+	}
+
+	public static boolean isBBMode() {
+		return bbMode;
+	}
+}
