draw2d
diff --git a/visualization/plugins/.project b/visualization/plugins/.project
new file mode 100644
index 0000000..0ab6892
--- /dev/null
+++ b/visualization/plugins/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>plugins</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/visualization/plugins/org.eclipse.draw2d/.checkstyle b/visualization/plugins/org.eclipse.draw2d/.checkstyle
new file mode 100644
index 0000000..00370b8
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/.checkstyle
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<fileset-config file-format-version="1.1.0" simple-config="false">

+<fileset name="All Java Files" check-config-name="Checkstyle Generic" enabled="true"><file-match-pattern match-pattern=".java$" include-pattern="true"/>

+</fileset>

+<fileset name="All API Files" check-config-name="API Checkstyle" enabled="true"><file-match-pattern match-pattern=".java$" include-pattern="true"/>

+<file-match-pattern match-pattern=".internal.*.java$" include-pattern="false"/>

+</fileset>

+</fileset-config>
\ No newline at end of file
diff --git a/visualization/plugins/org.eclipse.draw2d/.classpath b/visualization/plugins/org.eclipse.draw2d/.classpath
new file mode 100644
index 0000000..df094ee
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+    <classpathentry kind="src" path="src"/>
+    <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+    <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/visualization/plugins/org.eclipse.draw2d/.cvsignore b/visualization/plugins/org.eclipse.draw2d/.cvsignore
new file mode 100644
index 0000000..4fcea73
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/.cvsignore
@@ -0,0 +1,5 @@
+bin
+runtime
+temp.folder
+.settings
+org
diff --git a/visualization/plugins/org.eclipse.draw2d/.project b/visualization/plugins/org.eclipse.draw2d/.project
new file mode 100644
index 0000000..0b91d60
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.draw2d</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>
+		<nature>org.eclipse.pde.PluginNature</nature>
+	</natures>
+</projectDescription>
diff --git a/visualization/plugins/org.eclipse.draw2d/META-INF/MANIFEST.MF b/visualization/plugins/org.eclipse.draw2d/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1d609b3
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Draw2d
+Bundle-SymbolicName: org.eclipse.draw2d
+Bundle-Version: 3.2.1.qualifier
+Bundle-Vendor: Eclipse.org
+Bundle-Localization: plugin
+Import-Package: com.ibm.icu.text
+Export-Package: org.eclipse.draw2d,
+ org.eclipse.draw2d.graph,
+ org.eclipse.draw2d.geometry,
+ org.eclipse.draw2d.images,
+ org.eclipse.draw2d.internal;x-internal:=true,
+ org.eclipse.draw2d.parts,
+ org.eclipse.draw2d.text,
+ org.eclipse.draw2d.widgets
+Require-Bundle: org.eclipse.swt;visibility:=reexport;bundle-version="[3.2.0,4.0.0)"
+Eclipse-LazyStart: true
diff --git a/visualization/plugins/org.eclipse.draw2d/about.html b/visualization/plugins/org.eclipse.draw2d/about.html
new file mode 100644
index 0000000..6f6b96c
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/about.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>February 24, 2005</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/visualization/plugins/org.eclipse.draw2d/build.properties b/visualization/plugins/org.eclipse.draw2d/build.properties
new file mode 100644
index 0000000..d87fcaa
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/build.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2002, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes=about.html,META-INF/,.
+bin.excludes=**/doc-files/**,overview.html
+source.. = src/
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbsoluteBendpoint.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbsoluteBendpoint.java
new file mode 100644
index 0000000..43d23ab
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbsoluteBendpoint.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * AbsoluteBendpoint is a Bendpoint that defines its location simply as its X and Y
+ * coordinates. It is used by bendable {@link Connection Connections}. 
+ */
+public class AbsoluteBendpoint 
+	extends Point 
+	implements Bendpoint 
+{
+
+/**
+ * Creates a new AbsoluteBendpoint at the Point p.
+ * @param p The absolute location of the bendpoint
+ * @since 2.0
+ */
+public AbsoluteBendpoint(Point p) {
+	super(p);
+}
+
+/**
+ * Creates a new AbsoluteBendpoint at the Point (x,y).
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @since 2.0
+ */
+public AbsoluteBendpoint(int x, int y) {
+	super(x, y);
+}
+
+/**
+ * @see org.eclipse.draw2d.Bendpoint#getLocation()
+ */
+public Point getLocation() {
+	return this;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractBorder.java
new file mode 100644
index 0000000..b97ad0f
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractBorder.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * Provides generic support for borders.
+ * @author hudsonr
+ */
+public abstract class AbstractBorder
+	implements Border
+{
+
+private static final Dimension EMPTY = new Dimension();
+
+/** A temporary Rectangle*/
+protected static Rectangle tempRect = new Rectangle();
+
+/**
+ * Returns a temporary rectangle representing the figure's bounds cropped by the specified
+ * insets.  This method exists for convenience and performance; the method does not new
+ * any Objects and returns a rectangle which the caller can manipulate.
+ * @since 2.0
+ * @param figure  Figure for which the paintable rectangle is needed
+ * @param insets The insets
+ * @return The paintable region on the Figure f
+ */
+protected static final Rectangle getPaintRectangle(IFigure figure, Insets insets) {
+	tempRect.setBounds(figure.getBounds());
+	return tempRect.crop(insets);
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#getPreferredSize(IFigure)
+ */
+public Dimension getPreferredSize(IFigure f) {
+	return EMPTY;
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#isOpaque()
+ */
+public boolean isOpaque() {
+	return false;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractConnectionAnchor.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractConnectionAnchor.java
new file mode 100644
index 0000000..70c6bcc
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractConnectionAnchor.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * Provides support for anchors which depend on a figure for thier location. 
+ * @author hudsonr
+ */
+public abstract class AbstractConnectionAnchor
+	extends ConnectionAnchorBase
+	implements AncestorListener
+{
+
+private IFigure owner;
+
+/**
+ * Constructs an AbstractConnectionAnchor with no owner.
+ * 
+ * @since 2.0
+ */
+public AbstractConnectionAnchor() { }
+
+/**
+ * Constructs an AbstractConnectionAnchor with the owner supplied as input.
+ *
+ * @since 2.0
+ * @param owner  Owner of this anchor
+ */
+public AbstractConnectionAnchor(IFigure owner) {
+	setOwner(owner);
+}
+
+/**
+ * Adds the given listener to the listeners to be notified of anchor location changes.
+ *
+ * @since 2.0
+ * @param listener   Listener to be added
+ * @see  #removeAnchorListener(AnchorListener)
+ */
+public void addAnchorListener(AnchorListener listener) {
+	if (listener == null)
+		return;
+	if (listeners.size() == 0)
+		getOwner().addAncestorListener(this);
+	super.addAnchorListener(listener);
+}
+
+/**
+ * Notifies all the listeners of this anchor's location change.
+ *
+ * @since 2.0
+ * @param figure  Anchor-owning Figure which has moved
+ * @see org.eclipse.draw2d.AncestorListener#ancestorMoved(IFigure)
+ */
+public void ancestorMoved(IFigure figure) {
+	fireAnchorMoved();
+}
+
+/**
+ * @see org.eclipse.draw2d.AncestorListener#ancestorAdded(IFigure)
+ */
+public void ancestorAdded(IFigure ancestor) { }
+
+/**
+ * @see org.eclipse.draw2d.AncestorListener#ancestorRemoved(IFigure)
+ */
+public void ancestorRemoved(IFigure ancestor) { }
+
+/** 
+ * Returns the owner Figure on which this anchor's location is dependent.
+ *
+ * @since 2.0
+ * @return  Owner of this anchor
+ * @see #setOwner(IFigure)
+ */
+public IFigure getOwner() {
+	return owner;
+}
+
+/**
+ * Returns the point which is used as the reference by this AbstractConnectionAnchor. It
+ * is generally dependent on the Figure which is the owner of this
+ * AbstractConnectionAnchor.
+ *
+ * @since 2.0
+ * @return  The reference point of this anchor
+ * @see org.eclipse.draw2d.ConnectionAnchor#getReferencePoint()
+ */
+public Point getReferencePoint() {
+	if (getOwner() == null)
+		return null;
+	else {
+		Point ref = getOwner().getBounds().getCenter();
+		getOwner().translateToAbsolute(ref);
+		return ref;
+	}
+}
+
+/**
+ * Removes the given listener from this anchor. If all the listeners are removed, then
+ * this anchor removes itself from its owner.
+ *
+ * @since 2.0
+ * @param listener  Listener to be removed from this anchors listeners list
+ * @see #addAnchorListener(AnchorListener)
+ */
+public void removeAnchorListener(AnchorListener listener) {
+	super.removeAnchorListener(listener);
+	if (listeners.size() == 0)
+		getOwner().removeAncestorListener(this);
+}
+
+/**
+ * Sets the owner of this anchor, on whom this anchors location is dependent.
+ *
+ * @since 2.0
+ * @param owner  Owner of this anchor
+ */
+public void setOwner(IFigure owner) {
+	this.owner = owner;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractHintLayout.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractHintLayout.java
new file mode 100644
index 0000000..d822927
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractHintLayout.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+
+/**
+ * The foundation for layout managers which are sensitive to width and/or height hints.
+ * This class will cache preferred and minimum sizes for a given set of hints. If the
+ * hints change in a meaningful way, the cached size is thrown out and redetermined.
+ * <P>
+ * Subclasses may be sensitive to one or both hints. By default, this class assumes both
+ * hints are important. Subclasses may override this behavior in {@link
+ * #isSensitiveHorizontally(IFigure)} and {@link #isSensitiveVertically(IFigure)}. At
+ * least one of these method should return <code>true</code>.
+ * 
+ * @author hudsonr
+ * @since 2.0
+ */
+public abstract class AbstractHintLayout
+	extends AbstractLayout
+{
+
+private Dimension minimumSize = null;
+private Dimension cachedPreferredHint = new Dimension(-1, -1);
+private Dimension cachedMinimumHint = new Dimension(-1, -1);
+
+/**
+ * Calculates the minimum size using the given width and height hints. This method is
+ * called from {@link #getMinimumSize(IFigure, int, int)} whenever the cached minimum size
+ * has been flushed.
+ * <P>
+ * By default, this method just calls {@link #getPreferredSize(IFigure, int, int)},
+ * meaning minimum and preferres sizes will be the same unless this method is overridden.
+ * 
+ * @param container the Figure on which this layout is installed
+ * @param wHint the width hint
+ * @param hHint the height hint
+ * 
+ * @return the layout's minimum size
+ */
+protected Dimension calculateMinimumSize(IFigure container, int wHint, int hHint) {
+	return getPreferredSize(container, wHint, hHint);
+}
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#getMinimumSize(IFigure, int, int)
+ */
+public Dimension getMinimumSize(IFigure container, int w, int h) {
+	boolean flush = cachedMinimumHint.width != w
+		&& isSensitiveHorizontally(container);
+	flush |= cachedMinimumHint.height != h
+		&& isSensitiveVertically(container);
+	if (flush) {
+		minimumSize = null;
+		cachedMinimumHint.width = w;
+		cachedMinimumHint.height = h;
+	}
+	if (minimumSize == null)
+		minimumSize = calculateMinimumSize(container, w, h);
+	return minimumSize;
+}
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#getPreferredSize(IFigure, int, int)
+ */
+public final Dimension getPreferredSize(IFigure container, int w, int h) {
+	boolean flush = cachedPreferredHint.width != w
+		&& isSensitiveHorizontally(container);
+	flush |= cachedPreferredHint.height != h
+		&& isSensitiveVertically(container);
+	if (flush) {
+		preferredSize = null;
+		cachedPreferredHint.width = w;
+		cachedPreferredHint.height = h;
+	}
+	return super.getPreferredSize(container, w, h);
+}
+
+/**
+ * Extends the superclass implementation to flush the cached minimum size.
+ * @see org.eclipse.draw2d.LayoutManager#invalidate()
+ */
+public void invalidate() {
+	minimumSize = null;
+	super.invalidate();
+}
+
+/**
+ * Returns whether this layout manager is sensitive to changes in the horizontal hint. By
+ * default, this method returns <code>true</code>.
+ * @param container the layout's container
+ * @return <code>true</code> if this layout is sensite to horizontal hint changes
+ */
+protected boolean isSensitiveHorizontally(IFigure container) {
+	return true;
+}
+
+/**
+ * Returns whether this layout manager is sensitive to changes in the vertical hint. By
+ * default, this method returns <code>true</code>.
+ * @param container the layout's container
+ * @return <code>true</code> if this layout is sensite to vertical hint changes
+ */
+protected boolean isSensitiveVertically(IFigure container) {
+	return true;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLabeledBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLabeledBorder.java
new file mode 100644
index 0000000..75477b8
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLabeledBorder.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+
+/**
+ * Provides support for a border with a label describing the contents of which it is
+ * surrounding.
+ */
+public abstract class AbstractLabeledBorder
+	extends AbstractBorder
+	implements LabeledBorder
+{
+	
+private Dimension textExtents;
+private String label;
+private Insets insets;
+private Color textColor = ColorConstants.black;
+private Font font;
+
+/**
+ * Constructs a default AbstractLabeledBorder with the name of this class set as its
+ * label.
+ * 
+ * @since 2.0
+ */
+public AbstractLabeledBorder() {
+	String className = getClass().getName();
+	setLabel(className.substring(className.lastIndexOf('.') + 1, className.length()));
+}
+
+/**
+ * Constructs a border with the label set to the String passed in as input.
+ *
+ * @param s  Label to be set on the border
+ * @since 2.0
+ */
+public AbstractLabeledBorder(String s) {
+	setLabel(s);
+}
+
+/**
+ * Calculates insets based on the current font and other attributes. This value will be
+ * cached until {@link #invalidate()} is called.
+ * @param figure The figure to which the border is being applied
+ * @return The Insets
+ */
+protected abstract Insets calculateInsets(IFigure figure);
+
+/**
+ * Returns the font that this border will use. If no Font has been specified, the font
+ * associated with the input Figure will be used.
+ * @param f Figure used to get a default font
+ * @return The font for this border
+ */
+protected Font getFont(IFigure f) {
+	if (font == null)
+		return f.getFont();
+	return font;
+}
+
+/**
+ * Returns the insets, or space associated for this border. Returns any previously set
+ * value if present, else calculates it from the Figure provided in as input.
+ * @param fig Figure used to calculate insets
+ * @return The insets
+ */
+public Insets getInsets(IFigure fig) {
+	if (insets == null)
+		insets = calculateInsets(fig);
+	return insets;
+}
+
+/**
+ * @see org.eclipse.draw2d.LabeledBorder#getLabel()
+ */
+public String getLabel() {
+	return label;
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#getPreferredSize(IFigure)
+ */
+public Dimension getPreferredSize(IFigure fig) {
+	return new Dimension(getTextExtents(fig));
+}
+
+/**
+ * Returns the text Color of this AbstractLabeledBorder's label.
+ * 
+ * @return The text color
+ * @since 2.0
+ */
+public Color getTextColor() {
+	return textColor;
+}
+
+/** 
+ * Calculates and returns the size required by this border's label. 
+ *
+ * @param f  IFigure on which the calculations are to be made
+ * @return   Dimensions required by the text of this border's label
+ * @since 2.0
+ */
+protected Dimension getTextExtents(IFigure f) {
+	if (textExtents == null)
+		textExtents = FigureUtilities.getTextExtents(label, getFont(f));
+	return textExtents;
+}
+
+/**
+ * Resets the internal values and state so that they can be recalculated. Called whenever
+ * a state  change has occurred that effects the insets or  text extents of this border.
+ */
+protected void invalidate() {
+	insets = null;
+	textExtents = null;
+}
+
+/**
+ * Sets the Font of this border to the input value, and invalidates the border forcing an
+ * update of internal parameters of insets and text extents.
+ * @param font The font
+ */
+public void setFont(Font font) {
+	this.font = font;
+	invalidate();
+}
+
+/**
+ * @see org.eclipse.draw2d.LabeledBorder#setLabel(String)
+ */
+public void setLabel(String s) {
+	label = ((s == null) ? "" : s);  //$NON-NLS-1$
+	invalidate();
+}
+
+/**
+ * Sets the color for this border's text.
+ *
+ * @param color  Color to be set for this border's text
+ * @since 2.0
+ */
+public void setTextColor(Color color) {
+	textColor = color;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLayout.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLayout.java
new file mode 100644
index 0000000..fe92fe4
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLayout.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+
+/**
+ * Provides generic support for LayoutManagers.
+ */
+public abstract class AbstractLayout
+	implements LayoutManager
+{
+
+/**
+ * The cached preferred size.
+ */
+protected Dimension preferredSize;
+
+/**
+ * Whether or not this layout pays attention to visiblity of figures when 
+ * calculating its bounds. By default, false.
+ */
+protected boolean isObservingVisibility = false;
+
+/**
+ * This method is now {@link #calculatePreferredSize(IFigure, int, int)}.
+ * @param container the figure
+ */
+protected final void calculatePreferredSize(IFigure container) { }
+
+/**
+ * Calculates the preferred size of the given figure, using width and height hints.
+ * @param container The figure
+ * @param wHint The width hint
+ * @param hHint The height hint
+ * @return The preferred size
+ */
+protected abstract Dimension calculatePreferredSize(IFigure container,
+	int wHint, int hHint);
+
+/**
+ * Returns the preferred size of the figure's border.
+ * @param container The figure that the border is on
+ * @return The border's preferred size
+ */
+protected Dimension getBorderPreferredSize(IFigure container) {
+	if (container.getBorder() == null)
+		return new Dimension();
+	return container.getBorder().getPreferredSize(container);
+}
+
+/**
+ * Returns the constraint for the given figure.
+ * @param child The figure
+ * @return The constraint
+ */
+public Object getConstraint(IFigure child) {
+	return null;
+}
+
+/**
+ * This method is now {@link #getMinimumSize(IFigure, int, int)}.
+ * @param container the figure
+ */
+public final void getMinimumSize(IFigure container) { }
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#getMinimumSize(IFigure, int, int)
+ */
+public Dimension getMinimumSize(IFigure container, int wHint, int hHint) {
+	return getPreferredSize(container, wHint, hHint);
+}
+
+/**
+ * Returns the preferred size of the given figure, using width and height hints.  If the
+ * preferred size is cached, that size  is returned.  Otherwise, {@link
+ * #calculatePreferredSize(IFigure, int, int)} is called.
+ * @param container The figure
+ * @param wHint The width hint
+ * @param hHint The height hint
+ * @return The preferred size
+ */
+public Dimension getPreferredSize(IFigure container, int wHint, int hHint) {
+	if (preferredSize == null)
+		preferredSize = calculatePreferredSize(container, wHint, hHint);
+	return preferredSize;
+}
+
+/**
+ * This method is now {@link #getPreferredSize(IFigure, int, int)}.
+ * @param container the figure
+ */
+public final void getPreferredSize(IFigure container) { }
+
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#invalidate()
+ */
+public void invalidate() {
+	preferredSize = null;
+}
+
+/**
+ * Removes any cached information about the given figure.
+ * @param child the child that is invalidated
+ */
+protected void invalidate(IFigure child) {
+	invalidate();
+}
+
+/**
+ * Returns whether or not this layout pays attention to visiblity when calculating its
+ * bounds.
+ * @return true if invisible figures should not contribute to this layout's bounds.
+ */
+public boolean isObservingVisibility() {
+	return isObservingVisibility;
+}
+
+/**
+ * Removes the given figure from this LayoutManager's list of figures.
+ * @param child The figure to remove
+ */
+public void remove(IFigure child) {
+	invalidate();
+}
+
+/**
+ * Sets the constraint for the given figure.
+ * @param child the child
+ * @param constraint the child's new constraint
+ */
+public void setConstraint(IFigure child, Object constraint) {
+	invalidate(child);
+}
+
+/**
+ * Sets isObservingVisibility to the given value.
+ * @param newValue <code>true</code> if visibility should be observed
+ */
+public void setObserveVisibility(boolean newValue) {
+	if (isObservingVisibility == newValue)
+		return;
+	isObservingVisibility = newValue;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLocator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLocator.java
new file mode 100644
index 0000000..b3988c5
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractLocator.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * Places a figure relative to a point determined by the subclass. The figure may be
+ * placed in some location relative to the point with a configurable amount of spacing.
+ */
+public abstract class AbstractLocator
+	implements Locator
+{
+
+private int relativePosition = PositionConstants.CENTER;
+private int gap;
+
+/**
+ * Creates a new AbstractLocator.
+ */
+public AbstractLocator() { }
+
+/**
+ * Returns the number of pixels to leave between the figure being located and the
+ * reference point. Only used if {@link #getRelativePosition()} returns something other
+ * than {@link PositionConstants#CENTER}.
+ * 
+ * @return The gap
+ * @since 2.0
+ */
+public int getGap() {
+	return gap;
+}
+
+/**
+ * Returns the reference point in absolute coordinates used to calculate the location.
+ * @return The reference point in absolute coordinates
+ * @since 2.0
+ */
+protected abstract Point getReferencePoint();
+
+/**
+ * Recalculate the location of the figure according to its desired position relative to
+ * the center point.
+ * 
+ * @param size The size of the figure
+ * @param center The center point
+ * @return The new bounds
+ * @since 2.0
+ */
+protected Rectangle getNewBounds(Dimension size, Point center) {
+	Rectangle bounds = new Rectangle(center, size);
+
+	bounds.x -= bounds.width / 2;
+	bounds.y -= bounds.height / 2;
+
+	int xFactor = 0, yFactor = 0;
+	int position = getRelativePosition();
+
+	if ((position & PositionConstants.NORTH) != 0) 
+		yFactor = -1;
+	else if ((position & PositionConstants.SOUTH) != 0) 
+		yFactor = 1;
+
+	if ((position & PositionConstants.WEST) != 0) 
+		xFactor = -1;
+	else if ((position & PositionConstants.EAST) != 0) 
+		xFactor = 1;
+
+	bounds.x += xFactor * (bounds.width / 2 + getGap());
+	bounds.y += yFactor * (bounds.height / 2 + getGap());
+
+	return bounds;
+}
+
+/**
+ * Returns the position of the figure with respect to the center point. Possible values
+ * can be found in {@link PositionConstants} and include CENTER, NORTH, SOUTH, EAST, WEST,
+ * NORTH_EAST, NORTH_WEST, SOUTH_EAST, or SOUTH_WEST.
+ * 
+ * @return An int constant representing the relative position
+ * @since 2.0
+ */
+public int getRelativePosition() {
+	return relativePosition;
+}
+
+/**
+ * Recalculates the position of the figure and returns the updated bounds.
+ * @param target The figure to relocate
+ */
+public void relocate(IFigure target) {
+	Dimension prefSize = target.getPreferredSize();
+	Point center = getReferencePoint();
+	target.translateToRelative(center);
+	target.setBounds(getNewBounds(prefSize, center));
+}
+
+/**
+ * Sets the gap between the reference point and the figure being placed. Only used if
+ * getRelativePosition() returns something other than  {@link PositionConstants#CENTER}.
+ * 
+ * @param i The gap
+ * @since 2.0
+ */
+public void setGap(int i) {
+	gap = i;
+}
+
+/**
+ * Sets the position of the figure with respect to the center point. Possible values can
+ * be found in {@link PositionConstants} and include CENTER, NORTH, SOUTH, EAST, WEST,
+ * NORTH_EAST, NORTH_WEST, SOUTH_EAST, or SOUTH_WEST.
+ * 
+ * @param pos The relative position
+ * @since 2.0
+ */
+public void setRelativePosition(int pos) {
+	relativePosition = pos;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractRouter.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractRouter.java
new file mode 100644
index 0000000..288345d
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AbstractRouter.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * Base class for implementing a connection router. This class provides stubs for
+ * constraint usage, and some utility methods.
+ */
+public abstract class AbstractRouter
+	implements ConnectionRouter
+{
+
+private static final Point START = new Point();
+private static final Point END = new Point();
+
+/**
+ * Returns the constraint for the given Connection.
+ * 
+ * @param connection The connection
+ * @return The constraint
+ * @since 2.0
+ */
+public Object getConstraint(Connection connection) {
+	return null;
+}
+
+/**
+ * A convenience method for obtaining a connection's endpoint.  The connection's endpoint
+ * is a point in absolute coordinates obtained by using its source and target {@link
+ * ConnectionAnchor}. The returned Point is a static singleton that is reused to reduce
+ * garbage collection. The caller may modify this point in any way. However, the point
+ * will be reused and its values overwritten during the next call to this method.
+ * 
+ * @param connection The connection
+ * @return The endpoint
+ * @since 2.0
+ */
+protected Point getEndPoint(Connection connection) {
+	Point ref = connection.getSourceAnchor().getReferencePoint();
+	return END.setLocation(connection.getTargetAnchor().getLocation(ref));
+}
+
+/**
+ * A convenience method for obtaining a connection's start point.  The connection's
+ * startpoint is a point in absolute coordinates obtained by using its source and target
+ * {@link ConnectionAnchor}. The returned Point is a static singleton that is reused to
+ * reduce garbage collection. The caller may modify this point in any way. However, the
+ * point will be reused and its values overwritten during the next call to this method.
+ * 
+ * @param conn The connection
+ * @return The start point
+ * @since 2.0
+ */
+protected Point getStartPoint(Connection conn) {
+	Point ref = conn.getTargetAnchor().getReferencePoint();
+	return START.setLocation(conn.getSourceAnchor().getLocation(ref));
+}
+
+/**
+ * Causes the router to discard any cached information about the given Connection.
+ * 
+ * @param connection The connection to invalidate
+ * @since 2.0
+ */
+public void invalidate(Connection connection) { }
+
+/**
+ * Removes the given Connection from this routers list of Connections it is responsible
+ * for.
+ * 
+ * @param connection The connection to remove
+ * @since 2.0
+ */
+public void remove(Connection connection) { }
+
+/**
+ * Sets the constraint for the given Connection.
+ * 
+ * @param connection The connection
+ * @param constraint The constraint
+ * @since 2.0
+ */
+public void setConstraint(Connection connection, Object constraint) { }
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AccessibleBase.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AccessibleBase.java
new file mode 100644
index 0000000..23abbdc
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AccessibleBase.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * The base class for accessible objects which provides accesibilty clients with a unique
+ * ID.
+ */
+public class AccessibleBase {
+
+/**
+ * Returns the id of this accessible object using {@link Object#hashCode()}.  
+ * @return the id
+ */
+public final int getAccessibleID() {
+	/* This assumes that the native implementation of hashCode in Object is to
+	 * return the pointer to the Object, which should be U-unique.
+	 */
+	int value = super.hashCode();
+	/*
+	 * Values -3, -2, and -1 are reserved by SWT's ACC class to have special meaning.
+	 * Therefore, a child cannot have this value.
+	 */
+	if (value < 0)
+		value -= 4;
+	return value;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ActionEvent.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ActionEvent.java
new file mode 100644
index 0000000..6d7244c
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ActionEvent.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * An event that occurs as a result of an action being performed.
+ */
+public class ActionEvent
+	extends java.util.EventObject
+{
+
+private String actionName;
+
+/**
+ * Constructs a new ActionEvent with <i>source</i> as the source of the event.
+ * 
+ * @param source The source of the event
+ */
+public ActionEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Constructs a new ActionEvent with <i>source</i> as the source of the event and
+ * <i>name</i> as the name of the action that was performed.
+ * 
+ * @param source The source of the event
+ * @param name The name of the action
+ */
+public ActionEvent(Object source, String name) {
+	super(source);
+	actionName = name;
+}
+
+/**
+ * Returns the name of the action that was performed.
+ * 
+ * @return String The name of the action
+ */
+public String getActionName() {
+	return actionName;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ActionListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ActionListener.java
new file mode 100644
index 0000000..fe300d6
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ActionListener.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * A Listener interface for receiving {@link ActionEvent ActionEvents}.
+ */
+public interface ActionListener {
+	
+/**
+ * Called when the action occurs.
+ * @param event The event
+ */
+void actionPerformed(ActionEvent event);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AncestorHelper.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AncestorHelper.java
new file mode 100644
index 0000000..984d780
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AncestorHelper.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+/**
+ * A helper object which tracks the parent chain hierarchy.
+ * @since 2.1
+ */
+class AncestorHelper
+	implements PropertyChangeListener, FigureListener 
+{
+
+/**
+ * The base figure whose ancestor chain is being observed.
+ */
+protected final IFigure base;
+/**
+ * The array of ancestor listeners.
+ */
+protected AncestorListener[] listeners;
+
+/**
+ * Constructs a new helper on the given base figure and starts listening to figure and
+ * property changes on the base figure's parent chain.  When no longer needed, the helper
+ * should be disposed.
+ * @since 2.1
+ * @param baseFigure
+ */
+public AncestorHelper(IFigure baseFigure) {
+	this.base = baseFigure;
+	addAncestors(baseFigure);
+}
+
+/**
+ * Appends a new listener to the list of listeners.
+ * @param listener the listener
+ */
+public void addAncestorListener(AncestorListener listener) {
+    if (listeners == null) {
+        listeners = new AncestorListener[1];
+        listeners[0] = listener;
+    } else {
+    	int oldSize = listeners.length;
+    	AncestorListener newListeners[] = new AncestorListener[oldSize + 1];
+    	System.arraycopy(listeners, 0, newListeners, 0, oldSize);
+    	newListeners[oldSize] = listener;
+    	listeners = newListeners;
+    }
+}
+
+/**
+ * Hooks up internal listeners used for maintaining the proper figure listeners.
+ * @param rootFigure the root figure
+ */
+protected void addAncestors(IFigure rootFigure) {
+	for (IFigure ancestor = rootFigure;
+			ancestor != null;
+			ancestor = ancestor.getParent()) {
+		ancestor.addFigureListener(this);
+		ancestor.addPropertyChangeListener("parent", this); //$NON-NLS-1$
+	}
+}
+
+/**
+ * Removes all internal listeners.
+ */
+public void dispose() {
+	removeAncestors(base);
+	listeners = null;
+}
+
+/**
+ * @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure)
+ */
+public void figureMoved(IFigure ancestor) {
+	fireAncestorMoved(ancestor);
+}
+
+/**
+ * Fires notification to the listener list 
+ * @param ancestor the figure which moved
+ */
+protected void fireAncestorMoved(IFigure ancestor) {
+	if (listeners == null)
+		return;
+	for (int i = 0; i < listeners.length; i++)
+		listeners[i].ancestorMoved(ancestor);
+}
+
+/**
+ * Fires notification to the listener list 
+ * @param ancestor the figure which moved
+ */
+protected void fireAncestorAdded(IFigure ancestor) {
+	if (listeners == null)
+		return;
+	for (int i = 0; i < listeners.length; i++)
+		listeners[i].ancestorAdded(ancestor);
+}
+
+/**
+ * Fires notification to the listener list 
+ * @param ancestor the figure which moved
+ */
+protected void fireAncestorRemoved(IFigure ancestor) {
+	if (listeners == null)
+		return;
+	for (int i = 0; i < listeners.length; i++)
+		listeners[i].ancestorRemoved(ancestor);
+}
+
+/**
+ * Returns the total number of listeners.
+ * @return the number of listeners
+ */
+public boolean isEmpty() {
+	return listeners == null;
+}
+
+/**
+ * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+ */
+public void propertyChange(PropertyChangeEvent event) {
+	if (event.getPropertyName().equals("parent")) { //$NON-NLS-1$
+		IFigure oldParent = (IFigure)event.getOldValue();
+		IFigure newParent = (IFigure)event.getNewValue();
+		if (oldParent != null) {
+			removeAncestors(oldParent);
+			fireAncestorRemoved(oldParent);
+		}
+		if (newParent != null) {
+			addAncestors(newParent);
+			fireAncestorAdded(newParent);
+		}
+	}
+}
+
+/**
+ * Removes the first occurence of the given listener
+ * @param listener the listener to remove
+ */
+public void removeAncestorListener(AncestorListener listener) {
+	if (listeners == null)
+		return;
+	for (int index = 0; index < listeners.length; index++)
+		if (listeners[index] == listener) {
+			int newSize = listeners.length - 1;
+			AncestorListener newListeners[] = null;
+			if (newSize != 0) {
+				newListeners = new AncestorListener[newSize];
+				System.arraycopy(listeners, 0, newListeners, 0, index);
+				System.arraycopy(listeners, index + 1, newListeners, index, newSize - index);
+			}
+			listeners = newListeners;
+			return;
+		}
+}
+
+/**
+ * Unhooks listeners starting at the given figure
+ * @param rootFigure
+ */
+protected void removeAncestors(IFigure rootFigure) {
+	for (IFigure ancestor = rootFigure; 
+				ancestor != null; 
+				ancestor = ancestor.getParent()) {
+		ancestor.removeFigureListener(this);
+		ancestor.removePropertyChangeListener("parent", this); //$NON-NLS-1$
+	}
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AncestorListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AncestorListener.java
new file mode 100644
index 0000000..203ea7c
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AncestorListener.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * Classes which implement this interface provide methods to respond to changes in the
+ * ancestor properties of a Figure.
+ * <P>
+ * Instances of this class can be added as listeners to a figure using the
+ * <code>addAncestorListener</code> method and removed using the
+ * <code>removeAncestoreListener</code> method.  When the parent chain of the figure being
+ * observed changes or moves, the listener will be notified appropriately.
+ */
+public interface AncestorListener {
+
+/**
+ * Called when an ancestor has been added into the listening figure's hierarchy.
+ * @param ancestor The ancestor that was added
+ */
+void ancestorAdded(IFigure ancestor);
+
+/**
+ * Called when an ancestor has moved to a new location.
+ * @param ancestor The ancestor that has moved
+ */
+void ancestorMoved(IFigure ancestor);
+
+/**
+ * Called when an ancestor has been removed from the listening figure's hierarchy.
+ * @param ancestor The ancestor that has been removed
+ */
+void ancestorRemoved(IFigure ancestor);
+
+/**
+ * An empty implementation of AncestorListener for convenience.
+ */
+class Stub implements AncestorListener {
+	public void ancestorMoved(IFigure ancestor) { }
+	public void ancestorAdded(IFigure ancestor) { }
+	public void ancestorRemoved(IFigure ancestor) { }
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AnchorListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AnchorListener.java
new file mode 100644
index 0000000..34e5e67
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AnchorListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * Classes which implement this interface provide a method to notify that an anchor has
+ * moved.
+ * <P>
+ * Instances of this class can be added as listeners of an Anchor using the
+ * <code>addAnchorListener</code> method and removed using the
+ * <code>removeAnchorListener</code> method.
+ */
+public interface AnchorListener {
+
+/**
+ * Called when an anchor has moved to a new location.
+ * @param anchor The anchor that has moved.
+ */
+void anchorMoved(ConnectionAnchor anchor);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Animation.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Animation.java
new file mode 100644
index 0000000..0c32617
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Animation.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.draw2d;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A utility for coordinating figure animations. During animation, multiple
+ * <i>animators</i> are employed to capture the <em>initial</em> and <em>final</em> states
+ * for one or more figures. The animators then playback the animation by interpolating the
+ * intermediate states for each figure using the initial and final "keyframes".
+ * <P>
+ * An animator is usually stateless and represents an specific technique. Any state
+ * information is stored by the Animation utility. Therefore, one instance can be used
+ * with multiple figures. Animators hook into the validation mechanism for figures and
+ * connections. These hooks are used to capture the states, and to intercept the typical
+ * layout process to insert the interpolated state.
+ * <P>
+ * To indicate that animation is desired, clients must call {@link #markBegin()} prior to
+ * invalidating any figures that are to be included in the animation. After this method is
+ * called, changes are made, and {@link #run()} is invoked. The run method will force a
+ * validation pass to capture the final states, and then commence the animation. The
+ * animation is synchronous and the method does not return until the animation has
+ * completed.
+ * @see LayoutAnimator
+ * @since 3.2
+ */
+public class Animation {
+
+static class AnimPair {
+
+	final Animator animator;
+	final IFigure figure;
+
+	AnimPair(Animator animator, IFigure figure) {
+		this.animator = animator;
+		this.figure = figure;	
+	}
+
+	public boolean equals(Object obj) {
+		AnimPair pair = (AnimPair)obj;
+		return pair.animator == animator && pair.figure == figure;
+	}
+
+	public int hashCode() {
+		return animator.hashCode() ^ figure.hashCode();
+	}
+}
+private static final int DEFAULT_DELAY = 250;
+private static Set figureAnimators;
+private static Map finalStates;
+
+private static Map initialStates;
+private static final int PLAYBACK = 3;
+private static float progress;
+private static final int RECORD_FINAL = 2;
+
+private static final int RECORD_INITIAL = 1;
+private static long startTime;
+private static int state;
+private static Set toCapture;
+
+private static UpdateManager updateManager;
+
+private static void capture() {
+	Iterator keys = figureAnimators.iterator();
+	while (keys.hasNext()) {
+		AnimPair pair = (AnimPair) keys.next();
+		if (toCapture.contains(pair))
+			pair.animator.capture(pair.figure);
+		else
+			keys.remove();
+	}
+}
+
+static void cleanup() {
+	if (figureAnimators != null) {
+		Iterator keys = figureAnimators.iterator();
+		while (keys.hasNext()) {
+			AnimPair pair = (AnimPair) keys.next();
+			pair.animator.tearDown(pair.figure);
+		}
+	}
+
+	state = 0;
+	step();
+	//Allow layout to occur normally
+	//updateManager.performUpdate();
+
+	initialStates = null;
+	finalStates = null;
+	figureAnimators = null;
+	updateManager = null;
+    toCapture = null;
+	state = 0;
+}
+
+private static void doRun(int duration) {
+	state = RECORD_FINAL;
+	findUpdateManager();
+	updateManager.performValidation();
+	capture();
+	state = PLAYBACK;
+	progress = 0.1f;
+	startTime = System.currentTimeMillis();
+	
+	notifyPlaybackStarting();
+	
+	while (progress != 0) {
+		step();
+		updateManager.performUpdate();
+		if (progress == 1.0)
+			progress = 0;
+		else {
+			int delta = (int)(System.currentTimeMillis() - startTime);
+			if (delta >= duration)
+				progress = 1f;
+			else
+				progress = 0.1f + 0.9f * delta / duration;
+		}
+	}
+}
+
+private static void findUpdateManager() {
+	AnimPair pair = (AnimPair) figureAnimators.iterator().next();
+	updateManager = pair.figure.getUpdateManager();
+}
+
+/**
+ * Returns the final animation state for the given figure.
+ * @param animator the animator for the figure
+ * @param figure the figure being animated
+ * @return the final state
+ * @since 3.2
+ */
+public static Object getFinalState(Animator animator, IFigure figure) {
+	return finalStates.get(new AnimPair(animator, figure));
+}
+
+/**
+ * Returns the initial animation state for the given animator and figure. If no state was
+ * recorded, <code>null</code> is returned.
+ * @param animator the animator for the figure
+ * @param figure the figure being animated
+ * @return the initial state
+ * @since 3.2
+ */
+public static Object getInitialState(Animator animator, IFigure figure) {
+	return initialStates.get(new AnimPair(animator, figure));
+}
+
+/**
+ * Returns the animation progress, where 0.0 < progress &#8804; 1.0.
+ * @return the progress of the animation
+ * @since 3.2
+ */
+public static float getProgress() {
+	return progress;
+}
+
+static void hookAnimator(IFigure figure, Animator animator) {
+	AnimPair pair = new AnimPair(animator, figure);
+	if (figureAnimators.add(pair))
+		animator.init(figure);
+}
+
+static void hookNeedsCapture(IFigure figure, Animator animator) {
+	AnimPair pair = new AnimPair(animator, figure);
+	if (figureAnimators.contains(pair))
+		toCapture.add(pair);
+}
+
+static boolean hookPlayback(IFigure figure, Animator animator) {
+	if (toCapture.contains(new AnimPair(animator, figure)))
+		return animator.playback(figure);
+	return false;
+}
+
+/**
+ * Returns <code>true</code> if animation is in progress.
+ * @return <code>true</code> when animating
+ * @since 3.2
+ */
+public static boolean isAnimating() {
+	return state == PLAYBACK;
+}
+
+static boolean isFinalRecording() {
+	return state == RECORD_FINAL;
+}
+
+static boolean isInitialRecording() {
+	return state == RECORD_INITIAL;
+}
+
+/**
+ * Marks the beginning of the animation process. If the beginning has already been marked,
+ * this has no effect.
+ * @return returns <code>true</code> if beginning was not previously marked
+ * @since 3.2
+ */
+public static boolean markBegin() {
+	if (state == 0) {
+		state = RECORD_INITIAL;
+		initialStates = new HashMap();
+		finalStates = new HashMap();
+		figureAnimators = new HashSet();
+		toCapture = new HashSet();
+		return true;
+	}
+	return false;
+}
+
+private static void notifyPlaybackStarting() {
+	Iterator keys = figureAnimators.iterator();
+	while (keys.hasNext()) {
+		AnimPair pair = (AnimPair) keys.next();
+		pair.animator.playbackStarting(pair.figure);
+	}
+}
+
+static void putFinalState(Animator animator, IFigure key, Object state) {
+	finalStates.put(new AnimPair(animator, key), state);
+}
+
+static void putInitialState(Animator animator, IFigure key, Object state) {
+	initialStates.put(new AnimPair(animator, key), state);
+}
+
+/**
+ * Runs animation using the recommended duration: 250 milliseconds.
+ * @see #run(int)
+ * @since 3.2
+ */
+public static void run() {
+	run(DEFAULT_DELAY);
+}
+
+/**
+ * Captures the final states for the animation and then plays the animation.
+ * @param duration the length of animation in milliseconds
+ * @since 3.2
+ */
+public static void run(int duration) {
+	if (state == 0)
+		return;
+	try {
+		if (!figureAnimators.isEmpty())
+			doRun(duration);
+	} finally {
+		cleanup();
+	}
+}
+
+private static void step() {
+	Iterator iter = initialStates.keySet().iterator();
+	while (iter.hasNext())
+		((AnimPair)iter.next()).figure.revalidate();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Animator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Animator.java
new file mode 100644
index 0000000..1183bf2
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Animator.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.draw2d;
+
+/**
+ * Animates some aspect of a figure. Each animator will capture some of the effects of
+ * validation of the figures.
+ * <P>
+ * Animators must be hooked to figure in special ways. Refer to each implementation for
+ * the specific requirements. Animators are generally stateless, which allows them to be
+ * shared and prevents them from leaking memory.
+ * 
+ * @since 3.2
+ */
+public abstract class Animator {
+
+Animator() { }
+
+/**
+ * Captures the final state of the given figure. This method is called once after the
+ * update manager has completed validation of all invalid figures.
+ * @param figure the container
+ * @since 3.2
+ */
+public void capture(IFigure figure) {
+	recordFinalState(figure);
+}
+
+/**
+ * Returns an object encapsulating the current state of the figure. This method is called
+ * to capture both the initial and final states.
+ * @param figure the figure
+ * @return the current state
+ * @since 3.2
+ */
+protected abstract Object getCurrentState(IFigure figure);
+
+/**
+ * Plays back the animation for the given figure and returns <code>true</code> if
+ * successful. This method does nothing by default and return <code>false</code>.
+ * @param figure the figure being animated
+ * @return <code>true</code> if playback was successful
+ * @since 3.2
+ */
+protected boolean playback(IFigure figure) {
+	return false;
+}
+
+/**
+ * Sent as playback is starting for a given figure.
+ * @param figure the figure
+ * @since 3.2
+ */
+public void playbackStarting(IFigure figure) { }
+
+/**
+ * Records the final state information for a figure.
+ * @param figure the figure
+ * @since 3.2
+ */
+protected void recordFinalState(IFigure figure) {
+	Animation.putFinalState(this, figure, getCurrentState(figure));
+}
+
+/**
+ * Records initial state information for the given figure.
+ * @param figure the container.
+ * @since 3.2
+ */
+protected void recordInitialState(IFigure figure) {
+	Animation.putInitialState(this, figure, getCurrentState(figure));
+}
+
+/**
+ * Sets up the animator for the given figure to be animated. This method is called exactly
+ * once time prior to any layouts happening. The animator can capture the figure's current
+ * state, and set any animation-time settings for the figure. Changes made to the figure
+ * should be reverted in {@link #tearDown(IFigure)}.
+ * @param figure the animated figure
+ * @since 3.2
+ */
+public void init(IFigure figure) {
+	recordInitialState(figure);
+}
+
+/**
+ * Reverts any temporary changes made to the figure during animation. This method is
+ * called exactly once after all animation has been completed. Subclasses should extend
+ * this method to revert any changes.
+ * @param figure the animated figure
+ * @since 3.2
+ * @see #init(IFigure)
+ */
+public void tearDown(IFigure figure) { }
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ArrowButton.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ArrowButton.java
new file mode 100644
index 0000000..84b5f7f
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ArrowButton.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Insets;
+
+/**
+ * A Button which displays a triangle pointing in a specified direction. This class is
+ * used by the {@link ScrollBar} figure.
+ */
+public class ArrowButton
+	extends Button
+	implements Orientable
+{
+
+{
+	createTriangle();
+	setRequestFocusEnabled(false);
+	setFocusTraversable(false);
+}
+
+/**
+ * Constructs a default ArrowButton with the arrow pointing north.
+ * 
+ * @since 2.0
+ */
+public ArrowButton() { }
+
+/**
+ * Constructs an ArrowButton with the arrow having the direction given in the input.
+ * The direction can be one of many directional constants defined in 
+ * {@link PositionConstants}.
+ *
+ * @param direction  Direction of the arrow
+ * @since 2.0
+ */
+public ArrowButton(int direction) {
+	setDirection(direction);
+}
+
+/**
+ * Contructs a triangle with a black background pointing north, and sets it as the
+ * contents of the button.
+ * 
+ * @since 2.0
+ */
+protected void createTriangle() {
+	Triangle tri = new Triangle();
+	tri.setOutline(true);
+	tri.setBackgroundColor(ColorConstants.listForeground);
+	tri.setForegroundColor(ColorConstants.listForeground);
+	tri.setBorder(new MarginBorder(new Insets(2)));
+	setContents(tri);
+}
+
+/**
+ * @see org.eclipse.draw2d.Orientable#setDirection(int)
+ */
+public void setDirection(int value) {
+	setChildrenDirection(value);
+}
+
+/**
+ * @see org.eclipse.draw2d.Orientable#setOrientation(int)
+ */
+public void setOrientation(int value) {
+	setChildrenOrientation(value);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ArrowLocator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ArrowLocator.java
new file mode 100644
index 0000000..befa9e8
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ArrowLocator.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.PointList;
+
+/**
+ * Locator used to place a {@link RotatableDecoration} on a {@link Connection}. The
+ * decoration can be placed at the source or target end of the connection figure. The
+ * default connection implementation uses a {@link DelegatingLayout} which requires
+ * locators.
+ */
+public class ArrowLocator extends ConnectionLocator {
+
+/**
+ * Constructs an ArrowLocator associated with passed connection and tip location (either
+ * {@link ConnectionLocator#SOURCE} or {@link ConnectionLocator#TARGET}).
+ * 
+ * @param connection The connection associated with the locator
+ * @param location Location of the arrow decoration
+ * @since 2.0
+ */
+public ArrowLocator(Connection connection, int location) {
+	super(connection, location);
+}
+
+/**
+ * Relocates the passed in figure (which must be a {@link RotatableDecoration}) at either
+ * the start or end of the connection.
+ * @param target The RotatableDecoration to relocate
+ */
+public void relocate(IFigure target) {
+	PointList points = getConnection().getPoints();
+	RotatableDecoration arrow = (RotatableDecoration)target;
+	arrow.setLocation(getLocation(points));
+
+	if (getAlignment() == SOURCE)
+		arrow.setReferencePoint(points.getPoint(1));
+	else if (getAlignment() == TARGET)
+		arrow.setReferencePoint(points.getPoint(points.size() - 2));
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AutomaticRouter.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AutomaticRouter.java
new file mode 100644
index 0000000..464f0f0
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/AutomaticRouter.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.ArrayList;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.internal.MultiValueMap;
+
+/**
+ * An abstract router implementation which detects when multiple connections are
+ * overlapping. Two connections overlap if the combination of source and target
+ * anchors are equal. Subclasses must implement {@link #handleCollision(PointList, int)}
+ * to determine how to avoid the overlap.
+ * <p>
+ * This router can delegate to another connection router. The wrappered router will route
+ * the connections first, after which overlapping will be determined.
+ */
+public abstract class AutomaticRouter
+	extends AbstractRouter 
+{
+
+private ConnectionRouter nextRouter;
+private MultiValueMap connections = new MultiValueMap();
+
+private class HashKey {
+    
+	private ConnectionAnchor anchor1, anchor2;
+	
+	HashKey(Connection conn) {
+		anchor1 = conn.getSourceAnchor();
+		anchor2 = conn.getTargetAnchor();
+	}
+	
+	public boolean equals(Object object) {
+		boolean isEqual = false;
+		HashKey hashKey;
+		
+		if (object instanceof HashKey) {
+			hashKey = (HashKey)object;
+			ConnectionAnchor hkA1 = hashKey.getFirstAnchor();
+			ConnectionAnchor hkA2 = hashKey.getSecondAnchor();
+			
+			isEqual = (hkA1.equals(anchor1) && hkA2.equals(anchor2))
+				|| (hkA1.equals(anchor2) && hkA2.equals(anchor1));
+		}
+		return isEqual;
+	}
+			
+	public ConnectionAnchor getFirstAnchor() {
+		return anchor1;
+	}
+	
+	public ConnectionAnchor getSecondAnchor() {
+		return anchor2;	
+	}
+	
+	public int hashCode() {
+		return anchor1.hashCode() ^ anchor2.hashCode();
+	}
+}
+
+/**
+ * @see org.eclipse.draw2d.ConnectionRouter#getConstraint(Connection)
+ */
+public Object getConstraint(Connection connection) {
+	if (next() != null)
+		return next().getConstraint(connection);
+	return null;
+}
+
+/**
+ * Handles collisions between 2 or more Connections. Collisions are currently defined as 2
+ * connections with no bendpoints and whose start and end points coincide.  In other
+ * words, the 2 connections are the exact same line.
+ *  
+ * @param list The PointList of a connection that collides with another connection
+ * @param index The index of the current connection in the list of colliding connections
+ */
+protected abstract void handleCollision(PointList list, int index);
+
+/**
+ * @see org.eclipse.draw2d.ConnectionRouter#invalidate(Connection)
+ */
+public void invalidate(Connection conn) {
+	if (next() != null)
+		next().invalidate(conn);
+	if (conn.getSourceAnchor() == null || conn.getTargetAnchor() == null)
+		return;
+	HashKey connectionKey = new HashKey(conn);
+	ArrayList connectionList = connections.get(connectionKey);
+	int affected = connections.remove(connectionKey, conn); 
+	if (affected != -1) {
+		for (int i = affected; i < connectionList.size(); i++)
+			((Connection)connectionList.get(i)).revalidate();
+	} else
+		connections.removeValue(conn);
+	
+}
+
+/**
+ * Returns the next router in the chain.
+ * @return The next router
+ * @since 2.0
+ */
+protected ConnectionRouter next() {
+	return nextRouter;
+}
+
+
+
+/**
+ * @see org.eclipse.draw2d.ConnectionRouter#remove(Connection)
+ */
+public void remove(Connection conn) {
+	if (conn.getSourceAnchor() == null || conn.getTargetAnchor() == null)
+		return;
+	HashKey connectionKey = new HashKey(conn);
+	ArrayList connectionList = connections.get(connectionKey);
+	if (connectionList != null) {
+		int index = connections.remove(connectionKey, conn);		
+		for (int i = index + 1; i < connectionList.size(); i++)
+			((Connection)connectionList.get(i)).revalidate();
+	}
+	if (next() != null) 
+		next().remove(conn);
+}
+
+/**
+ * Routes the given connection.  Calls the 'next' router first (if one exists) and if no
+ * bendpoints were added by the next router, collisions are dealt with by calling 
+ * {@link #handleCollision(PointList, int)}.
+ * @param conn The connection to route
+ */
+public void route(Connection conn) {
+	if (next() != null) 
+		next().route(conn);
+	else {
+		conn.getPoints().removeAllPoints();
+		setEndPoints(conn);
+	}
+
+	if (conn.getPoints().size() == 2) {
+		PointList points = conn.getPoints();
+		HashKey connectionKey = new HashKey(conn);
+		ArrayList connectionList = connections.get(connectionKey);
+		
+		if (connectionList != null) {
+			
+			int index;
+			
+			if (connectionList.contains(conn)) {
+				index = connectionList.indexOf(conn) + 1;	
+			} else {
+				index = connectionList.size() + 1;
+				connections.put(connectionKey, conn);
+			}
+			
+			handleCollision(points, index);
+			conn.setPoints(points);
+		} else {
+			connections.put(connectionKey, conn);
+		}
+	}
+}
+
+/**
+ * An AutomaticRouter needs no constraints for the connections it routes.  This method
+ * invalidates the connections and calls {@link #setConstraint(Connection, Object)} on the
+ * {@link #next()} router.
+ * @see org.eclipse.draw2d.ConnectionRouter#setConstraint(Connection, Object)
+ */
+public void setConstraint(Connection connection, Object constraint) {
+	invalidate(connection);
+	if (next() != null)
+		next().setConstraint(connection, constraint);
+}
+
+/**
+ * Sets the start and end points for the given connection.
+ * @param conn The connection
+ */
+protected void setEndPoints(Connection conn) {
+	PointList points = conn.getPoints();
+	points.removeAllPoints();
+	Point start = getStartPoint(conn);
+	Point end = getEndPoint(conn);
+	conn.translateToRelative(start);
+	conn.translateToRelative(end);
+	points.addPoint(start);
+	points.addPoint(end);
+	conn.setPoints(points);
+}
+
+/**
+ * Sets the next router.
+ * @param router The ConnectionRouter
+ * @since 2.0
+ */
+public void setNextRouter(ConnectionRouter router) {
+	nextRouter = router;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Bendpoint.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Bendpoint.java
new file mode 100644
index 0000000..30be843
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Bendpoint.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * A helper used to calculate the point at which a {@link org.eclipse.draw2d.Connection}
+ * should bend. A bendpoint returns a point <em>relative</em> to the connection figure on
+ * which it is being used. This was chosen so that fixed bendpoints would be easy to
+ * implement. A fixed bendpoint will have a fixed x and y value.  Although the absolute x
+ * and y location change during zoom and scrolling, the relative values stay the same.
+ */
+public interface Bendpoint {
+
+/**
+ * Returns the location of the bendpoint <em>relative</em> to the connection. The returned
+ * value may be by reference. The caller should NOT modify the returned value.
+ * 
+ * @return the location of the bendpoint relative to the Connection
+ */
+Point getLocation();
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BendpointConnectionRouter.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BendpointConnectionRouter.java
new file mode 100644
index 0000000..59c7f72
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BendpointConnectionRouter.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.PrecisionPoint;
+
+/**
+ * Routes {@link Connection}s through a <code>List</code> of {@link Bendpoint Bendpoints}.
+ */
+public class BendpointConnectionRouter
+	extends AbstractRouter
+{
+
+private Map constraints = new HashMap(11);
+
+private static final PrecisionPoint A_POINT = new PrecisionPoint();
+
+/**
+ * Gets the constraint for the given {@link Connection}.  
+ *
+ * @param connection The connection whose constraint we are retrieving
+ * @return The constraint
+ */
+public Object getConstraint(Connection connection) {
+	return constraints.get(connection);
+}
+
+/**
+ * Removes the given connection from the map of constraints.
+ *
+ * @param connection The connection to remove
+ */
+public void remove(Connection connection) {
+	constraints.remove(connection);
+}
+
+/**
+ * Routes the {@link Connection}.  Expects the constraint to be a List
+ * of {@link org.eclipse.draw2d.Bendpoint Bendpoints}.
+ *
+ * @param conn The connection to route
+ */
+public void route(Connection conn) {
+	PointList points = conn.getPoints();
+	points.removeAllPoints();
+
+	List bendpoints = (List)getConstraint(conn);
+	if (bendpoints == null)
+		bendpoints = Collections.EMPTY_LIST;
+
+	Point ref1, ref2;
+
+	if (bendpoints.isEmpty()) {
+		ref1 = conn.getTargetAnchor().getReferencePoint();
+		ref2 = conn.getSourceAnchor().getReferencePoint();
+	} else {
+		ref1 = new Point(((Bendpoint)bendpoints.get(0)).getLocation());
+		conn.translateToAbsolute(ref1);
+		ref2 = new Point(((Bendpoint)bendpoints.get(bendpoints.size() - 1)).getLocation());
+		conn.translateToAbsolute(ref2);
+	}
+
+	A_POINT.setLocation(conn.getSourceAnchor().getLocation(ref1));
+	conn.translateToRelative(A_POINT);
+	points.addPoint(A_POINT);
+
+	for (int i = 0; i < bendpoints.size(); i++) {
+		Bendpoint bp = (Bendpoint)bendpoints.get(i);
+		points.addPoint(bp.getLocation());
+	}
+
+	A_POINT.setLocation(conn.getTargetAnchor().getLocation(ref2));
+	conn.translateToRelative(A_POINT);
+	points.addPoint(A_POINT);
+	conn.setPoints(points);
+}
+
+/**
+ * Sets the constraint for the given {@link Connection}.
+ *
+ * @param connection The connection whose constraint we are setting
+ * @param constraint The constraint
+ */
+public void setConstraint(Connection connection, Object constraint) {
+	constraints.put(connection, constraint);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BendpointLocator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BendpointLocator.java
new file mode 100644
index 0000000..f390cfa
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BendpointLocator.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * Places a figure relative to a specified bend in a {@link Connection}. A bendpoint is
+ * one of the points returned in the connection's {@link Connection#getPoints()} method.
+ * It is not related to the bendpoint class used as routing constraints.
+ */
+public class BendpointLocator 
+	extends ConnectionLocator 
+{
+
+private int index;
+
+/**
+ * Creates a BendpointLocator associated with passed Connection c and index i.
+ * 
+ * @param c Connection associated with BendpointLocator
+ * @param i Index of bendpoint, represents the position of the bendpoint on Connection c
+ * @since 2.0
+ */
+public BendpointLocator(Connection c, int i) {
+	super(c);
+	index = i;
+}
+
+/**
+ * Returns the index of this BendpointLocator. This index is the position of the reference
+ * point in this BendpointLocator's {@link Connection}.
+ * 
+ * @return The index
+ * @since 2.0
+ */
+protected int getIndex() {
+	return index;
+}
+
+/**
+ * Returns reference point associated with the BendpointLocator.  This Point is taken from
+ * the BendpointLocator's connection and is point number 'index'.
+ * 
+ * @return The reference point
+ * @since 2.0
+ */
+protected Point getReferencePoint() {
+	Point p = getConnection().getPoints().getPoint(Point.SINGLETON, getIndex());
+	getConnection().translateToAbsolute(p);
+	return p;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Border.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Border.java
new file mode 100644
index 0000000..563c9e7
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Border.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A decoration on a Figure. A border may paint itself within the bounds of a figure, and
+ * it may provide Insets which can affect how the figures children are posiiton and
+ * painted.
+ * <P>
+ * A border instance may be used with multiple figure instances.
+ */
+public interface Border {
+
+/**
+ * Returns the Insets for this Border for the given Figure.
+ * @param figure The figure this border belongs to
+ * @return The insets
+ */
+Insets getInsets(IFigure figure);
+
+/**
+ * Returns the preferred width and height that this border would like to display itself
+ * properly.
+ * @param figure The figure
+ * @return The preferred size
+ */
+Dimension getPreferredSize(IFigure figure);
+
+/**
+ * Returns <code>true</code> if the Border completely fills the region defined in 
+ * {@link #paint(IFigure, Graphics, Insets)}.
+ * @return <code>true</code> if this border is opaque
+ */
+boolean isOpaque();
+
+/**
+ * Paints the border. The border should paint inside figure's {@link IFigure#getBounds()},
+ * inset by the parameter <i>insets</i>.  The border generally should not paint inside its
+ * own insets.  More specifically, Border <i>b</i> should paint inside the rectangle:
+ * figure.getBounds().getCropped(insets) and outside of the rectangle:
+ * figure.getBounds().getCropped(insets).getCropped(getInsets()) where <i>inside</i> is
+ * defined as {@link Rectangle#contains(int, int)}.
+ * 
+ * @param figure The figure this border belongs to
+ * @param graphics The graphics object used for painting
+ * @param insets The insets
+ */
+void paint(IFigure figure, Graphics graphics, Insets insets);
+
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BorderLayout.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BorderLayout.java
new file mode 100644
index 0000000..da0996e
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BorderLayout.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * @author Pratik Shah
+ */
+public class BorderLayout 
+	extends AbstractHintLayout 
+{
+
+/**
+ * Constant to be used as a constraint for child figures
+ */
+public static final Integer CENTER = new Integer(PositionConstants.CENTER);
+/**
+ * Constant to be used as a constraint for child figures
+ */
+public static final Integer TOP = new Integer(PositionConstants.TOP);
+/**
+ * Constant to be used as a constraint for child figures
+ */
+public static final Integer BOTTOM = new Integer(PositionConstants.BOTTOM);
+/**
+ * Constant to be used as a constraint for child figures
+ */
+public static final Integer LEFT = new Integer(PositionConstants.LEFT);
+/**
+ * Constant to be used as a constraint for child figures
+ */
+public static final Integer RIGHT = new Integer(PositionConstants.RIGHT);
+
+private IFigure center, left, top, bottom, right;
+private int vGap = 0, hGap = 0;
+
+/**
+ * @see org.eclipse.draw2d.AbstractHintLayout#calculateMinimumSize(IFigure, int, int)
+ */
+protected Dimension calculateMinimumSize(IFigure container, int wHint, int hHint) {
+	int minWHint = 0, minHHint = 0;
+	if (wHint < 0) {
+		minWHint = -1;
+	}
+	if (hHint < 0) {
+		minHHint = -1;
+	}
+	Insets border = container.getInsets();
+	wHint = Math.max(minWHint, wHint - border.getWidth());
+	hHint = Math.max(minHHint, hHint - border.getHeight());
+	Dimension minSize = new Dimension();
+	int middleRowWidth = 0, middleRowHeight = 0;
+	int rows = 0, columns = 0;
+
+	if (top != null  && top.isVisible()) {
+		Dimension childSize = top.getMinimumSize(wHint, hHint);
+		hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
+		minSize.setSize(childSize);
+		rows += 1;
+	}
+	if (bottom != null && bottom.isVisible()) {
+		Dimension childSize = bottom.getMinimumSize(wHint, hHint);
+		hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
+		minSize.width = Math.max(minSize.width, childSize.width);
+		minSize.height += childSize.height;
+		rows += 1;
+	}
+	if (left != null && left.isVisible()) {
+		Dimension childSize = left.getMinimumSize(wHint, hHint);
+		middleRowWidth = childSize.width;
+		middleRowHeight = childSize.height;
+		wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
+		columns += 1;
+	}
+	if (right != null  && right.isVisible()) {
+		Dimension childSize = right.getMinimumSize(wHint, hHint);
+		middleRowWidth += childSize.width;
+		middleRowHeight = Math.max(childSize.height, middleRowHeight);
+		wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
+		columns += 1;
+	}
+	if (center != null && center.isVisible()) {
+		Dimension childSize = center.getMinimumSize(wHint, hHint);
+		middleRowWidth += childSize.width;
+		middleRowHeight = Math.max(childSize.height, middleRowHeight);
+		columns += 1;
+	}
+
+	rows += columns > 0 ? 1 : 0;
+	// Add spacing, insets, and the size of the middle row
+	minSize.height += middleRowHeight + border.getHeight() + ((rows - 1) * vGap);
+	minSize.width = Math.max(minSize.width, middleRowWidth) + border.getWidth() 
+					+ ((columns - 1) * hGap);
+	
+	return minSize;
+}
+
+/**
+ * @see AbstractLayout#calculatePreferredSize(IFigure, int, int)
+ */
+protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
+	int minWHint = 0, minHHint = 0;
+	if (wHint < 0)
+		minWHint = -1;
+	
+	if (hHint < 0)
+		minHHint = -1;
+	
+	Insets border = container.getInsets();
+	wHint = Math.max(minWHint, wHint - border.getWidth());
+	hHint = Math.max(minHHint, hHint - border.getHeight());
+	Dimension prefSize = new Dimension();
+	int middleRowWidth = 0, middleRowHeight = 0;
+	int rows = 0, columns = 0;
+
+	if (top != null && top.isVisible()) {
+		Dimension childSize = top.getPreferredSize(wHint, hHint);
+		hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
+		prefSize.setSize(childSize);
+		rows += 1;
+	}
+	if (bottom != null && bottom.isVisible()) {
+		Dimension childSize = bottom.getPreferredSize(wHint, hHint);
+		hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
+		prefSize.width = Math.max(prefSize.width, childSize.width);
+		prefSize.height += childSize.height;
+		rows += 1;
+	}
+	if (left != null && left.isVisible()) {
+		Dimension childSize = left.getPreferredSize(wHint, hHint);
+		middleRowWidth = childSize.width;
+		middleRowHeight = childSize.height;
+		wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
+		columns += 1;
+	}
+	if (right != null && right.isVisible()) {
+		Dimension childSize = right.getPreferredSize(wHint, hHint);
+		middleRowWidth += childSize.width;
+		middleRowHeight = Math.max(childSize.height, middleRowHeight);
+		wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
+		columns += 1;
+	}
+	if (center != null && center.isVisible()) {
+		Dimension childSize = center.getPreferredSize(wHint, hHint);
+		middleRowWidth += childSize.width;
+		middleRowHeight = Math.max(childSize.height, middleRowHeight);
+		columns += 1;
+	}
+
+	rows += columns > 0 ? 1 : 0;
+	// Add spacing, insets, and the size of the middle row
+	prefSize.height += middleRowHeight + border.getHeight() + ((rows - 1) * vGap);
+	prefSize.width = Math.max(prefSize.width, middleRowWidth) + border.getWidth() 
+					+ ((columns - 1) * hGap);
+	
+	return prefSize;
+}
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#layout(IFigure)
+ */
+public void layout(IFigure container) {
+	Rectangle area = container.getClientArea();
+	Rectangle rect = new Rectangle();
+
+	Dimension childSize;
+	
+	if (top != null && top.isVisible()) {
+		childSize = top.getPreferredSize(area.width, -1);
+		rect.setLocation(area.x, area.y);
+		rect.setSize(childSize);
+		rect.width = area.width;
+		top.setBounds(rect);
+		area.y += rect.height + vGap;
+		area.height -= rect.height + vGap;
+	}
+	if (bottom != null && bottom.isVisible()) {
+		childSize = bottom.getPreferredSize(Math.max(area.width, 0), -1);
+		rect.setSize(childSize);
+		rect.width = area.width;
+		rect.setLocation(area.x, area.y + area.height - rect.height);
+		bottom.setBounds(rect);
+		area.height -= rect.height + vGap;
+	}
+	if (left != null && left.isVisible()) {
+		childSize = left.getPreferredSize(-1, Math.max(0, area.height));
+		rect.setLocation(area.x, area.y);
+		rect.width = childSize.width;
+		rect.height = Math.max(0, area.height);
+		left.setBounds(rect);
+		area.x += rect.width + hGap;
+		area.width -= rect.width + hGap;
+	}
+	if (right != null && right.isVisible()) {
+		childSize = right.getPreferredSize(-1, Math.max(0, area.height));
+		rect.width = childSize.width;
+		rect.height = Math.max(0, area.height);
+		rect.setLocation(area.x + area.width - rect.width, area.y);
+		right.setBounds(rect);
+		area.width -= rect.width + hGap;
+	}
+	if (center != null && center.isVisible()) {
+		if (area.width < 0)
+			area.width = 0;
+		if (area.height < 0)
+			area.height = 0;
+		center.setBounds(area);
+	}
+}
+
+/**
+ * @see org.eclipse.draw2d.AbstractLayout#remove(IFigure)
+ */
+public void remove(IFigure child) {
+	if (center == child) {
+		center = null;
+	} else if (top == child) {
+		top = null;
+	} else if (bottom == child) {
+		bottom = null;
+	} else if (right == child) {
+		right = null;
+	} else if (left == child) {
+		left = null;
+	}
+}
+
+/**
+ * Sets the location of hte given child in this layout.  Valid constraints:
+ * <UL>
+ * 		<LI>{@link #CENTER}</LI>
+ * 		<LI>{@link #TOP}</LI>
+ * 		<LI>{@link #BOTTOM}</LI>
+ * 		<LI>{@link #LEFT}</LI>
+ * 		<LI>{@link #RIGHT}</LI>
+ * 		<LI><code>null</code> (to remove a child's constraint)</LI>
+ * </UL>
+ * 
+ * <p>
+ * Ensure that the given Figure is indeed a child of the Figure on which this layout has
+ * been set.  Proper behaviour cannot be guaranteed if that is not the case.  Also ensure
+ * that every child has a valid constraint.  
+ * </p>
+ * <p> 
+ * Passing a <code>null</code> constraint will invoke {@link #remove(IFigure)}.
+ * </p>
+ * <p> 
+ * If the given child was assigned another constraint earlier, it will be re-assigned to
+ * the new constraint.  If there is another child with the given constraint, it will be
+ * over-ridden so that the given child now has that constraint.
+ * </p>
+ * 
+ * @see org.eclipse.draw2d.AbstractLayout#setConstraint(IFigure, Object)
+ */
+public void setConstraint(IFigure child, Object constraint) {
+	remove(child);
+	super.setConstraint(child, constraint);
+	if (constraint == null) {
+		return;
+	}
+	
+	switch (((Integer) constraint).intValue()) {
+		case PositionConstants.CENTER :
+			center = child;
+			break;
+		case PositionConstants.TOP :
+			top = child;
+			break;
+		case PositionConstants.BOTTOM :
+			bottom = child;
+			break;
+		case PositionConstants.RIGHT :
+			right = child;
+			break;
+		case PositionConstants.LEFT :
+			left = child;
+			break;
+		default :
+			break;
+	}
+}
+
+/**
+ * Sets the horizontal spacing to be used between the children.  Default is 0.
+ * 
+ * @param gap The horizonal spacing
+ */
+public void setHorizontalSpacing(int gap) {
+	hGap = gap;
+}
+
+/**
+ * Sets the vertical spacing ot be used between the children.  Default is 0.
+ * 
+ * @param gap The vertical spacing
+ */
+public void setVerticalSpacing(int gap) {
+	vGap = gap;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BufferedGraphicsSource.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BufferedGraphicsSource.java
new file mode 100644
index 0000000..c16e829
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/BufferedGraphicsSource.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+class BufferedGraphicsSource implements GraphicsSource {
+
+private Image imageBuffer;
+private GC imageGC;
+private GC controlGC;
+private Control control;
+private Rectangle inUse;
+
+/**
+ * Constructs a new buffered graphics source using the given control.
+ * @since 2.1
+ * @param c the control
+ */
+public BufferedGraphicsSource(Control c) {
+	control = c;
+}
+
+/**
+ * @see org.eclipse.draw2d.GraphicsSource#flushGraphics(org.eclipse.draw2d.geometry.Rectangle)
+ */
+public void flushGraphics(Rectangle region) {
+	if (inUse.isEmpty())
+		return;
+	
+	boolean restoreCaret = false;
+	Canvas canvas = null;
+	if (control instanceof Canvas) {
+		canvas = (Canvas)control;
+		Caret caret = canvas.getCaret();
+		if (caret != null)
+			restoreCaret = caret.isVisible();
+		if (restoreCaret)
+			caret.setVisible(false);
+	}
+	/*
+	 * The imageBuffer may be null if double-buffering was not successful.
+	 */
+	if (imageBuffer != null) {
+		imageGC.dispose();
+		controlGC.drawImage(getImage(),
+				0, 0, inUse.width, inUse.height,
+				inUse.x, inUse.y, inUse.width, inUse.height);
+		imageBuffer.dispose();
+		imageBuffer = null;
+		imageGC = null;
+	}
+	controlGC.dispose();
+	controlGC = null;
+	
+	if (restoreCaret)
+		canvas.getCaret().setVisible(true);
+}
+
+/**
+ * @see org.eclipse.draw2d.GraphicsSource#getGraphics(org.eclipse.draw2d.geometry.Rectangle)
+ */
+public Graphics getGraphics(Rectangle region) {
+	if (control == null || control.isDisposed())
+		return null;
+
+	org.eclipse.swt.graphics.Point ptSWT = control.getSize();
+	inUse = new Rectangle(0, 0, ptSWT.x, ptSWT.y);
+	inUse.intersect(region);
+	if (inUse.isEmpty())
+		return null;
+	
+	/*
+	 * Bugzilla 53632 - Attempts to create large images on some platforms will fail.
+	 * When this happens, do not use double-buffering for painting.
+	 */
+	try {
+		imageBuffer = new Image(null, inUse.width, inUse.height);
+	} catch (SWTError noMoreHandles) {
+		imageBuffer = null;
+	} catch (IllegalArgumentException tooBig) {
+		imageBuffer = null;
+	}
+	
+	controlGC = new GC(control,
+			control.getStyle() & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT));
+	Graphics graphics;
+	if (imageBuffer != null) {
+		imageGC = new GC(imageBuffer,
+				control.getStyle() & (SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT));
+		imageGC.setBackground(controlGC.getBackground());
+		imageGC.setForeground(controlGC.getForeground());
+		imageGC.setFont(controlGC.getFont());
+		imageGC.setLineStyle(controlGC.getLineStyle());
+		imageGC.setLineWidth(controlGC.getLineWidth());
+		imageGC.setXORMode(controlGC.getXORMode());
+		graphics = new SWTGraphics(imageGC);
+		graphics.translate(inUse.getLocation().negate());
+	} else {
+		graphics = new SWTGraphics(controlGC);
+	}
+
+	graphics.setClip(inUse);
+	return graphics;
+}
+
+/**
+ * Returns the current image buffer or <code>null</code>.
+ * @since 2.1
+ * @return the current image buffer
+ */
+protected Image getImage() {
+	return imageBuffer;
+}
+
+/**
+ * Returns the current GC used on the buffer or <code>null</code>.
+ * @since 2.1
+ * @return the GC for the image buffer
+ */
+protected GC getImageGC() {
+	return imageGC;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Button.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Button.java
new file mode 100644
index 0000000..f4de857
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Button.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A Button usually has a border and appears to move up and down in response to being
+ * pressed. It can contain  an image and/or text in it.
+ */
+public class Button
+	extends Clickable
+{
+
+/**
+ * Constructs a default Button with no icon or text.
+ * 
+ * @since 2.0
+ */
+public Button() { 
+	super();
+	setStyle(STYLE_BUTTON);
+}
+
+/** 
+ * Contructs a Button containing the icon <i>image</i>.
+ *
+ * @param image  Image to be used by the Button as its icon.
+ * @since 2.0
+ */
+public Button(Image image) {
+	super(new Label(image), STYLE_BUTTON);
+}
+
+/**
+ * Constructs a Button containing the given text.
+ *
+ * @param text  Text for the button.
+ * @since 2.0
+ */
+public Button(String text) {
+	super(new Label(text), STYLE_BUTTON);
+}
+
+/** 
+ * Constructs a Button with the given image and text.
+ *
+ * @param text  Text for the button.
+ * @param image  Image for the button.
+ * @since 2.0
+ */
+public Button(String text, Image image) {
+	super(new Label(text, image), STYLE_BUTTON);
+}
+
+/**
+ * Initializes this button by setting its default border and setting its background color
+ * to {@link ColorConstants#button}.
+ * 
+ * @since 2.0
+ */
+protected void init() {
+	super.init();
+	setBackgroundColor(ColorConstants.button);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonBorder.java
new file mode 100644
index 0000000..076d384
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonBorder.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Color;
+
+import org.eclipse.draw2d.geometry.Insets;
+
+/**
+ * Creates a border for a clickable type of figure, which works in conjunction with the
+ * Figure and its model. This border adjusts itself to the various states the model of the
+ * figure could be. This border uses an extended  {@link SchemeBorder.Scheme Scheme}
+ * called {@link ButtonScheme} which provides more information required by border to
+ * handle the the states of the model.
+ *
+ * @see Scheme
+ * @see ButtonScheme
+ */
+public class ButtonBorder
+	extends SchemeBorder
+{
+
+/** 
+ * Default button border.  
+ * @see SCHEMES#BUTTON
+ */
+public static final Border BUTTON = new ButtonBorder(SCHEMES.BUTTON);
+/** 
+ * Inverted hightlight colors from BUTTON.  
+ * @see SCHEMES#BUTTON_CONTRAST 
+ */
+public static final Border BUTTON_CONTRAST = new ButtonBorder(SCHEMES.BUTTON_CONTRAST);
+/** 
+ * Used for scrollbar buttons.  
+ * @see SCHEMES#BUTTON_SCROLLBAR 
+ */
+public static final Border BUTTON_SCROLLBAR = new ButtonBorder(SCHEMES.BUTTON_SCROLLBAR);
+/** 
+ * Used for toolbar buttons.  
+ * @see SCHEMES#TOOLBAR 
+ */
+public static final Border TOOLBAR = new ButtonBorder(SCHEMES.TOOLBAR);
+
+/**
+ * Provides for a scheme to represent the borders of clickable figures like buttons.
+ * Though similar to the {@link SchemeBorder.Scheme Scheme} it supports an extra set of
+ * borders for the pressed states. 
+ */
+public static class ButtonScheme
+	extends Scheme
+{
+	private Color
+		highlightPressed[] = null,
+		shadowPressed[] = null;
+
+	/**
+	 * Constructs a new button scheme where the input colors are the colors for the
+	 * top-left and bottom-right sides of the  border. These colors serve as the colors
+	 * when the border is in a pressed state too. The width of each side is determined by
+	 * the number of colors passed in as input.
+	 *
+	 * @param highlight  Colors for the top-left sides of the border
+	 * @param shadow     Colors for the bottom-right sides of the border
+	 * @since 2.0
+	 */
+	public ButtonScheme(Color[] highlight, Color[] shadow) {
+		highlightPressed = this.highlight = highlight;
+		shadowPressed = this.shadow = shadow;
+		init();
+	}
+
+	/**
+	 * Constructs a new button scheme where the input colors are the colors for the
+	 * top-left and bottom-right sides of the  border, for the normal and pressed states. 
+	 * The width of  each side is determined by the number of colors passed in  as input. 
+	 *
+	 * @param hl   Colors for the top-left sides of the border
+	 * @param sh   Colors for the bottom-right sides of the border
+	 * @param hlp  Colors for the top-left sides of the border when figure is pressed
+	 * @param shp  Colors for the bottom-right sides of the border when figure is pressed
+	 * @since 2.0
+	 */
+	public ButtonScheme(Color[] hl, Color[] sh, Color[] hlp, Color[] shp) {
+		highlight = hl;
+		shadow = sh;
+		highlightPressed = hlp;
+		shadowPressed = shp;
+		init();
+	}
+
+	/**
+	 * Calculates and returns the Insets for this border. The calculations are based on
+	 * the number of normal and pressed, highlight and shadow colors.
+	 *
+	 * @return  The insets for this border
+	 * @since 2.0
+	 */
+	protected Insets calculateInsets() {
+		int br = 1 + Math.max(getShadow().length, getHighlightPressed().length);
+		int tl = Math.max(getHighlight().length, getShadowPressed().length);
+		return new Insets(tl, tl, br, br);
+	}
+	
+	/**
+	 * Calculates and returns the opaque state of this border.
+	 * <p>
+	 * Returns false in the following conditions:
+	 * <ul>
+	 * 		<li> The number of highlight colors is different than the the number of
+	 * 		shadow colors.
+	 * 		<li> The number of pressed highlight colors is different than the number of
+	 * 		pressed shadow colors.
+	 * 		<li> Any of the highlight and shadow colors are set to <code>null</code>
+	 * 		<li> Any of the pressed highlight and shadow colors are set to
+	 * 		<code>null</code> 
+	 * </ul>
+	 * This is done so that the entire region under the figure is properly covered.
+	 *
+	 * @return  The opaque state of this border
+	 * @since 2.0
+	 */
+	protected boolean calculateOpaque() {
+		if (!super.calculateOpaque())
+			return false;
+		if (getHighlight().length != getShadowPressed().length)
+			return false;
+		if (getShadow().length != getHighlightPressed().length)
+			return false;
+		Color [] colors = getHighlightPressed();
+		for (int i = 0; i < colors.length; i++)
+			if (colors[i] == null)
+				return false;
+		colors = getShadowPressed();
+		for (int i = 0; i < colors.length; i++)
+			if (colors[i] == null)
+				return false;
+		return true;
+	}
+	
+	/**
+	 * Returns the pressed highlight colors of this border.
+	 *
+	 * @return  Colors as an array of Colors
+	 * @since 2.0
+	 */
+	protected Color[] getHighlightPressed() {
+		return highlightPressed;
+	}
+
+	/**
+	 * Returns the pressed shadow colors of this border.
+	 *
+	 * @return  Colors as an array of Colors
+	 * @since 2.0
+	 */
+	protected Color[] getShadowPressed() {
+		return shadowPressed;
+	}
+}
+
+/**
+ * Interface defining commonly used schemes for the ButtonBorder.
+ */
+public static interface SCHEMES {
+	
+	/**
+	 * Contrast button scheme
+	 */
+	ButtonScheme BUTTON_CONTRAST = new ButtonScheme(
+		new Color[] {button, buttonLightest},
+		DARKEST_DARKER
+	);
+	/**
+	 * Regular button scheme
+	 */
+	ButtonScheme BUTTON = new ButtonScheme(
+		new Color[] {buttonLightest},
+		DARKEST_DARKER
+	);
+	/**
+	 * Toolbar button scheme
+	 */
+	ButtonScheme TOOLBAR = new ButtonScheme(
+		new Color[] {buttonLightest},
+		new Color[] {buttonDarker}
+	);
+	/**
+	 * Scrollbar button scheme
+	 */
+	ButtonScheme BUTTON_SCROLLBAR = new ButtonScheme(
+		new Color[] {button, buttonLightest},
+		DARKEST_DARKER,
+		new Color[] {buttonDarker},
+		new Color[] {buttonDarker}
+	);
+}
+
+/**
+ * Constructs a ButtonBorder with a predefined button scheme set as its default.
+ * 
+ * @since 2.0
+ */
+public ButtonBorder() {
+	setScheme(SCHEMES.BUTTON);
+}
+
+/**
+ * Constructs a ButtonBorder with the input ButtonScheme set as its Scheme.
+ *
+ * @param scheme  ButtonScheme for this ButtonBorder.
+ * @since 2.0
+ */
+public ButtonBorder(ButtonScheme scheme) {
+	setScheme(scheme);
+}
+
+/**
+ * Paints this border with the help of the set scheme, the model of the clickable figure,
+ * and other inputs. The scheme is used in conjunction with the state of the model to get 
+ * the appropriate colors for the border.
+ * 
+ * @param figure The Clickable that this border belongs to
+ * @param graphics The graphics used for painting
+ * @param insets The insets
+ */
+public void paint(IFigure figure, Graphics graphics, Insets insets) {
+	Clickable clickable = (Clickable)figure;
+	ButtonModel model = clickable.getModel();
+	ButtonScheme colorScheme = (ButtonScheme)getScheme();
+
+	if (clickable.isRolloverEnabled() && !model.isMouseOver()
+		&& !model.isSelected())
+		return;
+
+	Color tl[], br[];
+	if (model.isSelected() || model.isArmed()) {
+		tl = colorScheme.getShadowPressed();
+		br = colorScheme.getHighlightPressed();
+	} else {
+		tl = colorScheme.getHighlight();
+		br = colorScheme.getShadow();
+	}
+
+	paint(graphics, figure, insets, tl, br);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonGroup.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonGroup.java
new file mode 100644
index 0000000..8cb7199
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonGroup.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A ButtonGroup holds a group of {@link Clickable Clickable's} models and provides unique
+ * selection in them. There is  capability to add a default selection. Models who want to
+ * belong to the group should just add themselves to this group. By doing so they listen
+ * to this group for changes.
+ * <p>
+ * Setting of the default selection results in its being selected any time
+ * {@link #setSelected(ButtonModel, boolean)} is called. If no default selection is set,
+ * the last entry selected is not allowed to deselect.
+ */
+public class ButtonGroup {
+		
+private ButtonModel selectedModel;
+private ButtonModel defaultModel;
+private List members = new ArrayList();
+private List listeners = new ArrayList();
+
+/**
+ * Constructs a ButtonGroup with no default selection.
+ * 
+ * @since 2.0
+ */
+public ButtonGroup() {
+}
+
+/** 
+ * Adds the passed ButtonModel to the ButtonGroup.
+ *
+ * @param model  ButtonModel to be added to this group
+ * @since 2.0
+ */
+public void add(ButtonModel model) {
+	if (!members.contains(model)) {
+		model.setGroup(this);
+		members.add(model);
+	}
+}
+
+/**
+ * Adds the passed listener. ButtonGroups use PropertyChangeListeners to react to
+ * selection changes in the ButtonGroup.
+ * 
+ * @param listener  Listener to be added to this group
+ * @since 2.0
+ */
+public void addPropertyChangeListener(PropertyChangeListener listener) {
+	listeners.add(listener);
+}
+
+/**
+ * Fires a PropertyChangeEvent to all PropertyChangeListeners added to this ButtonGroup.
+ *
+ * @param oldValue  Old selection value
+ * @param newValue  New selection value
+ * @since 2.0
+ */
+protected void firePropertyChange(Object oldValue, Object newValue) {
+	PropertyChangeEvent event = new PropertyChangeEvent(
+		this, ButtonModel.SELECTED_PROPERTY, oldValue, newValue);
+	for (int i = 0; i < listeners.size(); i++)
+		((PropertyChangeListener)listeners.get(i)).propertyChange(event);
+}
+
+/**
+ * Returns the ButtonModel which is selected by default for this ButtonGroup.
+ * 
+ * @return The default ButtonModel
+ * @since 2.0
+ */
+public ButtonModel getDefault() {
+	return defaultModel;
+}
+
+/**
+ * Returns a List which contains all of the {@link ButtonModel ButtonModels} added to this
+ * ButtonGroup.
+ * 
+ * @return The List of ButtonModels in this ButtonGroup
+ * @since 2.0
+ */
+public List getElements() {
+	return members;
+}
+
+/**
+ * Returns the ButtonModel for the currently selected button.
+ * 
+ * @return The ButtonModel for the currently selected button
+ * @since 2.0
+ */
+public ButtonModel getSelected() {
+	return selectedModel;
+}
+
+/**
+ * Determines if the given ButtonModel is selected or not.
+ *
+ * @param model  Model being tested for selected status
+ * @return  Selection state of the given model
+ * @since 2.0
+ */
+public boolean isSelected(ButtonModel model) {
+	return (model == getSelected());
+}
+
+/**
+ * Removes the given ButtonModel from this ButtonGroup. 
+ * 
+ * @param model  ButtonModel being removed
+ * @since 2.0
+ */
+public void remove(ButtonModel model) {
+	if (getSelected() == model)
+		setSelected(getDefault(), true);
+	if (defaultModel == model)
+		defaultModel = null;
+	members.remove(model);
+}
+
+/**
+ * Removes the passed PropertyChangeListener from this ButtonGroup.
+ *
+ * @param listener  PropertyChangeListener to be removed
+ * @since 2.0
+ */
+public void removePropertyChangeListener(PropertyChangeListener listener) {
+	listeners.remove(listener);
+}
+
+/**
+ * Sets the passed ButtonModel to be the currently selected ButtonModel of this
+ * ButtonGroup. Fires a property change.
+ * 
+ * @param model ButtonModel to be selected
+ * @since 2.0
+ */
+protected void selectNewModel(ButtonModel model) {
+	ButtonModel oldModel = selectedModel;
+	selectedModel = model;
+	if (oldModel != null)
+		oldModel.setSelected(false);
+	firePropertyChange(oldModel, model);
+}
+
+/**
+ * Sets the default selection of this ButtonGroup. Does nothing if it is not present in
+ * the group. Sets selection to the passed ButtonModel.
+ *
+ * @param model  ButtonModel which is to be the default selection.
+ * @since 2.0
+ */
+public void setDefault(ButtonModel model) {
+	defaultModel = model;
+	if (getSelected() == null && defaultModel != null)
+		defaultModel.setSelected(true);
+}
+
+/**
+ * Sets the button with the given ButtonModel to be selected.
+ * 
+ * @param model The ButtonModel to be selected
+ * @since 2.0
+ */
+public void setSelected(ButtonModel model) {
+	if (model == null)
+		selectNewModel(null);
+	else
+		model.setSelected(true);
+}
+
+/**
+ * Sets model to the passed state.  
+ * <p>
+ * If <i>value</i> is 
+ * <ul>
+ * 		<li><code>true</code>: 
+ * 		<ul>
+ * 			<li>The passed ButtonModel will own selection.
+ * 		</ul>
+ * 		<li><code>false</code>:
+ * 		<ul> 
+ * 			<li>If the passed model owns selection, it will lose selection, and
+ * 			selection will be given to the default ButonModel. If no default
+ * 			ButtonModel was set, selection will remain as it was, as one ButtonModel
+ * 			must own selection at all times. 
+ * 			<li>If the passed model does not own selection, then selection will remain
+ * 			as it was.
+ * 		</ul>
+ * </ul>
+ *
+ * @param model The model to be affected
+ * @param value The selected state
+ * @since 2.0
+ */
+public void setSelected(ButtonModel model, boolean value) {
+	if (value) {
+		if (model == getSelected())
+			return;
+		selectNewModel(model);
+	} else {
+		if (model != getSelected())
+			return;
+		if (getDefault() == null)
+			return;
+		getDefault().setSelected(true);
+	}
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonModel.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonModel.java
new file mode 100644
index 0000000..6ef66e1
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonModel.java
@@ -0,0 +1,557 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Iterator;
+import java.util.Timer;
+import java.util.TimerTask;
+
+//import org.eclipse.draw2d.internal.Timer;
+
+/**
+ * A model for buttons containing several properties, including enabled, pressed,
+ * selected, rollover enabled and mouseover.
+ */
+public class ButtonModel {
+
+/** Enabled property */
+public static final String ENABLED_PROPERTY = "enabled"; //$NON-NLS-1$
+/** Pressed property */
+public static final String PRESSED_PROPERTY = "pressed"; //$NON-NLS-1$
+/** Selected property */
+public static final String SELECTED_PROPERTY = "selected"; //$NON-NLS-1$
+/** Rollover Enabled property */
+public static final String ROLLOVER_ENABLED_PROPERTY = "rollover enabled"; //$NON-NLS-1$
+/** Mouseover property */
+public static final String MOUSEOVER_PROPERTY = "mouseover"; //$NON-NLS-1$
+
+/** Armed property */
+public static final String ARMED_PROPERTY = "armed";  //$NON-NLS-1$
+
+
+/** Flag for armed button state */
+protected static final int ARMED_FLAG 				= 1;
+/** Flag for pressed button state */
+protected static final int PRESSED_FLAG 			= 2;
+/** Flag for mouseOver state */
+protected static final int MOUSEOVER_FLAG 			= 4;
+/** Flag for selected button state */
+protected static final int SELECTED_FLAG 			= 8;
+/** Flag for enablement button state */
+protected static final int ENABLED_FLAG 			= 16;
+/** Flag for rollover enablement button state */
+protected static final int ROLLOVER_ENABLED_FLAG 	= 32;
+/** Flag that can be used by subclasses to define more states */
+protected static final int MAX_FLAG 				= ROLLOVER_ENABLED_FLAG;
+
+private int state = ENABLED_FLAG;
+private Object data;
+
+/**
+ * Action performed events are not fired until the mouse button is released. 
+ */
+public static final int DEFAULT_FIRING_BEHAVIOR = 0;
+
+/**
+ * Action performed events fire repeatedly until the mouse button is released.
+ */
+public static final int REPEAT_FIRING_BEHAVIOR  = 1;
+
+/**
+ * The name of the action associated with this button.
+ */
+protected String actionName;
+
+/**
+ * The ButtonGroup this button belongs to (if any).
+ */
+protected ButtonGroup group = null;
+
+private EventListenerList listeners = new EventListenerList();
+
+/**
+ * Listens to button state transitions and fires action performed events based on the
+ * desired behavior ({@link #DEFAULT_FIRING_BEHAVIOR} or {@link #REPEAT_FIRING_BEHAVIOR}).
+ */
+protected ButtonStateTransitionListener firingBehavior; {
+	installFiringBehavior();
+}
+
+/**
+ * Registers the given listener as an ActionListener.
+ * 
+ * @param listener The ActionListener to add
+ * @since 2.0
+ */
+public void addActionListener(ActionListener listener) {
+	if (listener == null)
+		throw new IllegalArgumentException();
+	listeners.addListener(ActionListener.class, listener);
+}
+
+/**
+ * Registers the given listener as a ChangeListener.
+ * 
+ * @param listener The ChangeListener to add
+ * @since 2.0
+ */
+public void addChangeListener(ChangeListener listener) {
+	if (listener == null)
+		throw new IllegalArgumentException();
+	listeners.addListener(ChangeListener.class, listener);
+}
+
+/**
+ * Registers the given listener as a ButtonStateTransitionListener.
+ * 
+ * @param listener The ButtonStateTransitionListener to add
+ * @since 2.0
+ */
+public void addStateTransitionListener(ButtonStateTransitionListener listener) {
+	if (listener == null)
+		throw new IllegalArgumentException();
+	listeners.addListener(ButtonStateTransitionListener.class, listener);
+}
+
+/**
+ * Notifies any ActionListeners on this ButtonModel that an action has been performed.
+ * 
+ * @since 2.0
+ */
+protected void fireActionPerformed() {
+	Iterator iter = listeners.getListeners(ActionListener.class);
+	ActionEvent action = new ActionEvent(this);
+	while (iter.hasNext())
+		((ActionListener)iter.next()).
+			actionPerformed(action);
+}
+
+/**
+ * Notifies any listening ButtonStateTransitionListener that the pressed state of this
+ * button has been cancelled.
+ * 
+ * @since 2.0
+ */
+protected void fireCanceled() {
+	Iterator iter = listeners.getListeners(ButtonStateTransitionListener.class);
+	while (iter.hasNext())
+		((ButtonStateTransitionListener)iter.next()).
+			canceled();
+}
+
+/**
+ * Notifies any listening ButtonStateTransitionListener that this button has been pressed.
+ * 
+ * @since 2.0
+ */
+protected void firePressed() {
+	Iterator iter = listeners.getListeners(ButtonStateTransitionListener.class);
+	while (iter.hasNext())
+		((ButtonStateTransitionListener)iter.next()).
+			pressed();
+}
+
+/** 
+ * Notifies any listening ButtonStateTransitionListener that this button has been
+ * released.
+ * 
+ * @since 2.0
+ */
+protected void fireReleased() {
+	Iterator iter = listeners.getListeners(ButtonStateTransitionListener.class);
+	while (iter.hasNext())
+		((ButtonStateTransitionListener)iter.next()).
+			released();
+}
+
+/**
+ * Notifies any listening ButtonStateTransitionListeners that this button has resumed
+ * activity.
+ * 
+ * @since 2.0
+ */
+protected void fireResume() {
+	Iterator iter = listeners.getListeners(ButtonStateTransitionListener.class);
+	while (iter.hasNext())
+		((ButtonStateTransitionListener)iter.next()).
+			resume();
+}
+
+/**
+ * Notifies any listening ChangeListeners that this button's state has changed.
+ * 
+ * @param property The name of the property that changed
+ * @since 2.0
+ */
+protected void fireStateChanged(String property) {
+	Iterator iter = listeners.getListeners(ChangeListener.class);
+	ChangeEvent change = new ChangeEvent(this, property);
+	while (iter.hasNext())
+		((ChangeListener)iter.next()).
+			handleStateChanged(change);
+}
+
+/**
+ * Notifies any listening ButtonStateTransitionListeners that this button has suspended
+ * activity.
+ * 
+ * @since 2.0
+ */
+protected void fireSuspend() {
+	Iterator iter = listeners.getListeners(ButtonStateTransitionListener.class);
+	while (iter.hasNext())
+		((ButtonStateTransitionListener)iter.next()).
+			suspend();
+}
+
+boolean getFlag(int which) {
+	return (state & which) != 0;
+}
+
+/**
+ * Returns the group to which this model belongs.
+ * 
+ * @return The ButtonGroup to which this model belongs
+ * @since 2.0
+ */
+public ButtonGroup getGroup() {
+	return group;
+}
+
+/**
+ * Returns an object representing user data.
+ * 
+ * @return User data
+ * @since 2.0
+ */
+public Object getUserData() {
+	return data;
+}
+
+/**
+ * Sets the firing behavior for this button.
+ * 
+ * @since 2.0
+ */
+protected void installFiringBehavior() {
+	setFiringBehavior(DEFAULT_FIRING_BEHAVIOR);
+}
+
+/**
+ * Returns <code>true</code> if this button is armed. If a button is armed, it will fire
+ * an ActionPerformed when released.
+ * 
+ * @return <code>true</code> if this button is armed
+ * @since 2.0
+ */
+public boolean isArmed() {
+	return (state & ARMED_FLAG) != 0;
+}
+
+/**
+ * Returns <code>true</code> if this button is enabled.
+ * 
+ * @return <code>true</code> if this button is enabled
+ * @since 2.0
+ */
+public boolean isEnabled() {
+	return (state & ENABLED_FLAG) != 0;
+}
+
+/**
+ * Returns <code>true</code> if the mouse is over this button.
+ * 
+ * @return <code>true</code> if the mouse is over this button
+ * @since 2.0
+ */
+public boolean isMouseOver() {
+	return (state & MOUSEOVER_FLAG) != 0;
+}
+
+/**
+ * Returns <code>true</code> if this button is pressed.
+ * 
+ * @return <code>true</code> if this button is pressed
+ * @since 2.0
+ */
+public boolean isPressed() {
+	return (state & PRESSED_FLAG) != 0;
+}
+
+/**
+ * Returns the selection state of this model. If this model belongs to any group, the
+ * group is queried for selection state, else the flags are used.
+ *
+ * @return  <code>true</code> if this button is selected
+ * @since 2.0
+ */
+public boolean isSelected() {
+	if (group == null) {
+		return (state & SELECTED_FLAG) != 0;
+	} else {
+		return group.isSelected(this);
+	}
+}
+
+/**
+ * Removes the given ActionListener.
+ * 
+ * @param listener The ActionListener to remove
+ * @since 2.0
+ */
+public void removeActionListener(ActionListener listener) {
+	listeners.removeListener(ActionListener.class, listener);
+}
+
+/**
+ * Removes the given ChangeListener.
+ * 
+ * @param listener The ChangeListener to remove
+ * @since 2.0
+ */
+public void removeChangeListener(ChangeListener listener) {
+	listeners.removeListener(ChangeListener.class, listener);
+}
+
+/**
+ * Removes the given ButtonStateTransitionListener.
+ * 
+ * @param listener The ButtonStateTransitionListener to remove 
+ * @since 2.0
+ */
+public void removeStateTransitionListener(ButtonStateTransitionListener listener) {
+	listeners.removeListener(ButtonStateTransitionListener.class, listener);
+}
+
+/**
+ * Sets this button to be armed. If a button is armed, it will fire an ActionPerformed
+ * when released.
+ *
+ *@param value The armed state
+ * @since 2.0
+ */
+public void setArmed(boolean value) {
+	if (isArmed() == value)
+		return;
+	if (!isEnabled())
+		return;
+	setFlag(ARMED_FLAG, value);
+	fireStateChanged(ARMED_PROPERTY);
+}
+
+/**
+ * Sets this button to be enabled.
+ * 
+ * @param value The enabled state
+ * @since 2.0
+ */
+public void setEnabled(boolean value) {
+	if (isEnabled() == value)
+		return;
+	if (!value) {
+		setMouseOver(false);
+		setArmed(false);
+		setPressed(false);
+	}
+	setFlag(ENABLED_FLAG, value);
+	fireStateChanged(ENABLED_PROPERTY);
+}
+
+/**
+ * Sets the firing behavior for this button. {@link #DEFAULT_FIRING_BEHAVIOR} is the
+ * default behavior, where action performed events are not fired until the mouse button is
+ * released. {@link #REPEAT_FIRING_BEHAVIOR} causes action performed events to fire
+ * repeatedly until the mouse button is released.
+ * 
+ * @param type The firing behavior type
+ * @since 2.0
+ *          
+ */
+public void setFiringBehavior(int type) {
+	if (firingBehavior != null)
+		removeStateTransitionListener(firingBehavior);
+	switch (type) {
+		case REPEAT_FIRING_BEHAVIOR:
+			firingBehavior = new RepeatFiringBehavior();
+			break;
+		default:
+			firingBehavior = new DefaultFiringBehavior();
+	}
+	addStateTransitionListener(firingBehavior);
+}
+
+void setFlag(int flag, boolean value) {
+	if (value)
+		state |= flag;
+	else
+		state &= ~flag;
+}
+
+/**
+ * Sets the ButtonGroup to which this model belongs to. Adds this model as a listener to
+ * the group.
+ *
+ * @param bg The group to which this model belongs.
+ * @since 2.0
+ */
+public void setGroup(ButtonGroup bg) {
+	if (group == bg)
+		return;
+	if (group != null)
+		group.remove(this);
+	group = bg;
+	if (group != null)
+		group.add(this);
+}
+
+/**
+ * Sets the mouseover property of this button.
+ * 
+ * @param value The value the mouseover property will be set to
+ * @since 2.0
+ */
+public void setMouseOver(boolean value) {
+	if (isMouseOver() == value)
+		return;
+	if (isPressed())
+		if (value)
+			fireResume();
+		else
+			fireSuspend();
+	setFlag(MOUSEOVER_FLAG, value);
+	fireStateChanged(MOUSEOVER_PROPERTY);
+}
+
+/**
+ * Sets the pressed property of this button.
+ * 
+ * @param value The value the pressed property will be set to
+ * @since 2.0
+ */
+public void setPressed(boolean value) {
+	if (isPressed() == value)
+		return;
+	setFlag(PRESSED_FLAG, value);
+	if (value)
+		firePressed();
+	else {
+		if (isArmed())
+			fireReleased();
+		else
+			fireCanceled();
+	}
+	fireStateChanged(PRESSED_PROPERTY);
+}
+
+/**
+ * Sets this button to be selected.
+ * 
+ * @param value The value the selected property will be set to
+ * @since 2.0
+ */
+public void setSelected(boolean value) {
+	if (group == null) {
+		if (isSelected() == value)
+			return;
+	} else {
+		group.setSelected(this, value);
+		if (getFlag(SELECTED_FLAG) == isSelected())
+			return;
+	}
+	setFlag(SELECTED_FLAG, value);
+	fireStateChanged(SELECTED_PROPERTY);
+}
+
+/**
+ * Sets user data.
+ * 
+ * @param data The user data
+ * @since 2.0
+ */
+public void setUserData(Object data) {
+	this.data = data;
+}
+
+class DefaultFiringBehavior
+	extends ButtonStateTransitionListener
+{
+	public void released() {
+		fireActionPerformed();
+	}
+}
+
+class RepeatFiringBehavior
+	extends ButtonStateTransitionListener
+{
+	protected static final int
+		INITIAL_DELAY = 250,
+		STEP_DELAY = 40;
+	
+	protected int
+		stepDelay = INITIAL_DELAY,
+		initialDelay = STEP_DELAY;
+	
+	protected Timer timer;
+	
+	public void pressed() {
+		fireActionPerformed();
+		if (!isEnabled())
+			return;
+		
+		timer = new Timer();
+		TimerTask runAction = new Task(timer);
+
+		timer.scheduleAtFixedRate(runAction, INITIAL_DELAY, STEP_DELAY);
+	}
+
+	public void canceled() {
+		suspend();
+	}	
+	public void released() {
+		suspend();
+	}
+	
+	public void resume() {
+		timer = new Timer();
+		
+		TimerTask runAction = new Task(timer);
+		
+		timer.scheduleAtFixedRate(runAction, STEP_DELAY, STEP_DELAY);
+	}
+	
+	public void suspend() {
+		if (timer == null) return;
+		timer.cancel();
+		timer = null;
+	}
+}
+
+class Task 
+	extends TimerTask {
+	
+	private Timer timer;
+	
+	public Task(Timer timer) {
+		this.timer = timer;
+	}
+	
+	public void run() {
+		org.eclipse.swt.widgets.Display.getDefault().syncExec(new Runnable() {
+			public void run() {
+				if (!isEnabled())
+					timer.cancel();
+				fireActionPerformed();
+			}
+		});
+	}
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonStateTransitionListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonStateTransitionListener.java
new file mode 100644
index 0000000..48058db
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonStateTransitionListener.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+class ButtonStateTransitionListener {
+
+protected final void cancel() throws Exception { }
+public void canceled() { }
+final void cancelled() throws Exception { }
+
+protected final void press() throws Exception { }
+public void pressed() { }
+
+protected final void release() throws Exception { }
+public void released() { }
+
+public void resume() { }
+
+public void suspend() { }
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChangeEvent.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChangeEvent.java
new file mode 100644
index 0000000..da5093e
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChangeEvent.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * An event for property changes.  Includes the source of the event as well as the name of
+ * the property that has changed.
+ */
+public class ChangeEvent
+	extends java.util.EventObject
+{
+
+private String property;
+
+/**
+ * Constructs a new ChangeEvent with the given object as the source of the event.
+ * @param source The source of the event
+ */
+public ChangeEvent(Object source) {
+	super(source);
+}
+
+/**
+ * Constructs a new ChangeEvent with the given source object and property name.
+ * @param source The source of the event
+ * @param property The property name
+ */
+public ChangeEvent(Object source, String property) {
+	super(source);
+	setPropertyName(property);
+}
+
+/**
+ * Returns the name of the property that has changed.
+ * @return String the name of the property that has changed
+ */
+public String getPropertyName() {
+	return property;
+}
+
+/**
+ * Sets the name of the property that has changed.
+ * @param string The property name
+ */
+protected void setPropertyName(String string) {
+	property = string;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChangeListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChangeListener.java
new file mode 100644
index 0000000..0c2626f
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChangeListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+
+/**
+ * A generic state listener
+ */
+public interface ChangeListener {
+
+/**
+ * Called when the listened to object's state has changed.
+ * @param event the ChangeEvent
+ */
+void handleStateChanged(ChangeEvent event);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CheckBox.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CheckBox.java
new file mode 100644
index 0000000..5556df0
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CheckBox.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * A Checkbox is a toggle figure which toggles between the checked and unchecked figures
+ * to simulate a check box. A check box contains a text label to represent it.
+ */
+public final class CheckBox 
+	extends Toggle 
+{
+
+private Label label = null;
+
+static final Image
+	UNCHECKED = createImage("images/checkboxenabledoff.gif"), //$NON-NLS-1$
+	CHECKED = createImage("images/checkboxenabledon.gif"); //$NON-NLS-1$
+
+private static Image createImage(String name) {
+	InputStream stream = CheckBox.class.getResourceAsStream(name);
+	Image image = new Image(null, stream);
+	try {
+		stream.close();
+	} catch (IOException ioe) {
+	}
+	return image;
+}
+
+/**
+ * Constructs a CheckBox with no text.
+ * 
+ * @since 2.0
+ */
+public CheckBox() {
+	this(""); //$NON-NLS-1$
+}
+
+/**
+ * Constructs a CheckBox with the passed text in its label.
+ * @param text The label text
+ * @since 2.0
+ */
+public CheckBox(String text) {
+	setContents(label = new Label(text, UNCHECKED));
+}
+
+/**
+ * Adjusts CheckBox's icon depending on selection status.
+ * 
+ * @since 2.0
+ */
+protected void handleSelectionChanged() {
+	if (isSelected())
+		label.setIcon(CHECKED);
+	else
+		label.setIcon(UNCHECKED);
+}
+
+/**
+ * Initializes this Clickable by setting a default model and adding a clickable event
+ * handler for that model. Also adds a ChangeListener to update icon when  selection
+ * status changes.
+ * 
+ * @since 2.0
+ */
+protected void init() {
+	super.init();
+	addChangeListener(new ChangeListener () {
+		public void handleStateChanged(ChangeEvent changeEvent) { 
+			if (changeEvent.getPropertyName().equals(ButtonModel.SELECTED_PROPERTY))
+				handleSelectionChanged();
+		}
+	});
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChopboxAnchor.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChopboxAnchor.java
new file mode 100644
index 0000000..8eadd27
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ChopboxAnchor.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * The ChopboxAnchor's location is found by calculating the intersection of a line drawn
+ * from the center point of its owner's box to a reference point on that box. Thus 
+ * {@link Connection Connections} using the ChopBoxAnchor will be oriented such that they
+ * point to their owner's center.
+ */
+public class ChopboxAnchor
+	extends AbstractConnectionAnchor
+{
+
+/**
+ * Constructs a new ChopboxAnchor.
+ */
+protected ChopboxAnchor() { }
+
+/**
+ * Constructs a ChopboxAnchor with the given <i>owner</i> figure.
+ * 
+ * @param owner The owner figure
+ * @since 2.0
+ */
+public ChopboxAnchor(IFigure owner) {
+	super(owner);
+}
+
+/**
+ * Gets a Rectangle from {@link #getBox()} and returns the Point where a line from the
+ * center of the Rectangle to the Point <i>reference</i> intersects the Rectangle.
+ * 
+ * @param reference The reference point
+ * @return The anchor location
+ */
+public Point getLocation(Point reference) {
+	Rectangle r = Rectangle.SINGLETON;
+	r.setBounds(getBox());
+	r.translate(-1, -1);
+	r.resize(1, 1);
+
+	getOwner().translateToAbsolute(r);
+	float centerX = r.x + 0.5f * r.width;
+	float centerY = r.y + 0.5f * r.height;
+	
+	if (r.isEmpty() || (reference.x == (int)centerX && reference.y == (int)centerY))
+		return new Point((int)centerX, (int)centerY);  //This avoids divide-by-zero
+
+	float dx = reference.x - centerX;
+	float dy = reference.y - centerY;
+	
+	//r.width, r.height, dx, and dy are guaranteed to be non-zero. 
+	float scale = 0.5f / Math.max(Math.abs(dx) / r.width, Math.abs(dy) / r.height);
+
+	dx *= scale;
+	dy *= scale;
+	centerX += dx;
+	centerY += dy;
+
+	return new Point(Math.round(centerX), Math.round(centerY));
+}
+
+/**
+ * Returns the bounds of this ChopboxAnchor's owner.  Subclasses can override this method
+ * to adjust the box the anchor can be placed on.  For instance, the owner figure may have
+ * a drop shadow that should not be included in the box. 
+ *  
+ * @return The bounds of this ChopboxAnchor's owner
+ * @since 2.0
+ */
+protected Rectangle getBox() {
+	return getOwner().getBounds();
+}
+
+/**
+ * Returns the anchor's reference point. In the case of the ChopboxAnchor, this is the
+ * center of the anchor's owner.
+ * 
+ * @return The reference point
+ */
+public Point getReferencePoint() {
+	Point ref = getBox().getCenter();
+	getOwner().translateToAbsolute(ref);
+	return ref;
+}
+
+
+/**
+ * Returns <code>true</code> if the other anchor has the same owner and box.
+ * @param obj the other anchor
+ * @return <code>true</code> if equal
+ */
+public boolean equals(Object obj) {
+	if (obj instanceof ChopboxAnchor) {
+		ChopboxAnchor other = (ChopboxAnchor)obj;
+		return other.getOwner() == getOwner() && other.getBox().equals(getBox());
+	}
+	return false;
+}
+
+/**
+ * The owning figure's hashcode is used since equality is approximately based on the
+ * owner.
+ * @return the hash code.
+ */
+public int hashCode() {
+	if (getOwner() != null)
+		return getOwner().hashCode();
+	else
+		return super.hashCode();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Clickable.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Clickable.java
new file mode 100644
index 0000000..3acdd22
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Clickable.java
@@ -0,0 +1,487 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Iterator;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A Clickable responds to mouse clicks in some way (determined by a ClickBehavior) and
+ * fires action events. No visual appearance of feedback is offered. Depends on a model
+ * holder and an event handler which understands the model and updates the model
+ * accordingly. {@link ButtonModel} is used by default. Any figure can be set as contents
+ * to a Clickable. Clickable->EventHandler->Model->ModelObserver->Listeners of actions.
+ */
+public class Clickable
+	extends Figure
+{
+
+private static final int
+	ROLLOVER_ENABLED_FLAG = Figure.MAX_FLAG << 1,
+	STYLE_BUTTON_FLAG = Figure.MAX_FLAG << 2,
+	STYLE_TOGGLE_FLAG = Figure.MAX_FLAG << 3;
+
+/**
+ * The highest reserved flag used by this class
+ */
+protected static int
+	MAX_FLAG = STYLE_TOGGLE_FLAG;
+
+/**
+ * Style constant that defines a push button. The button will be pressed when the mouse is
+ * pressed on top of it. The button will be released when the mouse is released or is move
+ * off of the button.
+ * 
+ */
+public static final int STYLE_BUTTON = STYLE_BUTTON_FLAG;
+
+/**
+ * Style constant that defines a toggle button. The button will toggle between 2 states
+ * when the mouse is clicked on the button. 
+ */
+public static final int STYLE_TOGGLE = STYLE_TOGGLE_FLAG;
+
+/**
+ * An action is performed every time the mouse is released.
+ */
+public static final int DEFAULT_FIRING = 0;
+
+/**
+ * Firing starts as soon as the mouse is pressed on this Clickable, and keeps firing at
+ * prefixed intervals until the mouse is released.
+ */
+public static final int REPEAT_FIRING  = 1;
+
+/**
+ * Observes the model for action and state changes.
+ *
+ * @see ActionListener
+ * @see ChangeListener 
+ */
+static interface ModelObserver
+	extends ActionListener, ChangeListener
+{ }
+
+private ClickableEventHandler eventHandler;
+
+private ButtonModel model;
+
+private ModelObserver modelObserver;
+
+{
+	init();
+	setRequestFocusEnabled(true);
+	setFocusTraversable(true);
+}
+
+/**
+ * Constructs a Clickable with no contents.
+ */
+public Clickable() { }
+
+/**
+ * Constructs a Clickable whose contents are provided as input. The content figure
+ * occupies the entire region of the Clickable.
+ * 
+ * @param contents The content figure
+ */
+public Clickable(IFigure contents) {
+	this(contents, 0);
+}
+
+/**
+ * Constructs a Clickable whose contents are provided as input. The content figure
+ * occupies the entire region of the Clickable.  Sets the style to the given <i>style</i>
+ * (either {@link #STYLE_BUTTON} or {@link #STYLE_TOGGLE}).
+ * 
+ * @param contents The content figure
+ * @param style The button style
+ */
+public Clickable(IFigure contents, int style) {
+	setContents(contents);
+	setStyle(style);
+}
+
+/**
+ * Adds the given listener to the list of action listeners of this Figure. Listener is
+ * called whenever an action is performed.
+ *
+ * @param listener The ActionListener to be added
+ * @since 2.0
+ */
+public void addActionListener(ActionListener listener) {
+	addListener(ActionListener.class, listener);
+}
+
+/**
+ * Adds the given listener to the list of state change listeners of this figure. A
+ * ChangeListener is informed if there is any state change in the model requiring action
+ * by the listener. 
+ *
+ * @param listener The ChangeListener to be added
+ * @since 2.0
+ */
+public void addChangeListener(ChangeListener listener) {
+	addListener(ChangeListener.class, listener);
+}
+
+/**
+ * Returns a newly created ButtonModel as the default model to be used by this Clickable
+ * based on the button style.
+ *
+ * @return The model to be used by default
+ * @since 2.0
+ */
+protected ButtonModel createDefaultModel() {
+	if (isStyle(STYLE_TOGGLE))
+		return new ToggleModel();
+	else
+		return new ButtonModel();
+}
+
+/**
+ * Returns a newly created event handler for this Clickable and its model.
+ *
+ * @return The event handler
+ * @since 2.0
+ */
+protected ClickableEventHandler createEventHandler() {
+	return new ClickableEventHandler();
+}
+
+/**
+ * Returns a newly created model observer which listens to the model, and fires any action
+ * or state changes. A ModelObserver holds both an action listener and a state change
+ * listener.
+ *
+ * @return  The newly created model observer
+ * @since 2.0
+ */
+protected ModelObserver createModelObserver() {
+	return new ModelObserver() {
+		public void actionPerformed(ActionEvent action) {
+			fireActionPerformed();
+		}
+		public void handleStateChanged(ChangeEvent change) {
+			fireStateChanged(change);
+		}
+	};
+}
+
+/**
+ * Fires an action performed event.
+ * 
+ * @since 2.0
+ */
+public void doClick() {
+	fireActionPerformed();
+}
+
+/**
+ * Called when there has been an action performed by this Clickable, which is determined
+ * by the model. Notifies all ActionListener type listeners of an action performed.
+ * 
+ * @since 2.0
+ */
+protected void fireActionPerformed() {
+	ActionEvent action = new ActionEvent(this);
+	Iterator listeners = getListeners(ActionListener.class);
+	while (listeners.hasNext())
+		((ActionListener)listeners.next()) //Leave newline for debug stepping
+			.actionPerformed(action); 
+}
+
+/**
+ * Called when there has been a change of state in the model of this clickable. Notifies
+ * all ChangeListener type listeners  of the state change.
+ * 
+ * @param modelChange The ChangeEvent
+ * @since 2.0
+ */
+protected void fireStateChanged(ChangeEvent modelChange) {
+	ChangeEvent change = new ChangeEvent(this, modelChange.getPropertyName());
+	Iterator listeners = getListeners(ChangeListener.class);
+	while (listeners.hasNext())
+		((ChangeListener)listeners.next())  //Leave newline for debug stepping
+			.handleStateChanged(change);
+}
+
+/**
+ * Returns the behavior model used by this Clickable.
+ *
+ * @return  The model used by this Clickable
+ * @since 2.0
+ */
+public ButtonModel getModel() {
+	return model;
+}
+
+/**
+ * Adds the given ClickableEventHandler to this clickable. A ClickableEventHandler
+ * should be a MouseListener, MouseMotionListener, ChangeListener, KeyListener,  and
+ * FocusListener.
+ *
+ * @param handler  The new event handler
+ * @since 2.0
+ */
+protected void hookEventHandler(ClickableEventHandler handler) {
+	if (handler == null) 
+		return;
+	addMouseListener(handler);
+	addMouseMotionListener(handler);
+	addChangeListener(handler);
+	addKeyListener(handler);
+	addFocusListener(handler);
+}
+
+/**
+ * Initializes this Clickable by setting a default model and adding a clickable event
+ * handler for that model.
+ * 
+ * @since 2.0
+ */
+protected void init() {
+	setModel(createDefaultModel());
+	setEventHandler(createEventHandler());
+}
+
+/**
+ * Returns <code>true</code> if rollover feedback is enabled.
+ * 
+ * @return <code>true</code> rollover feedback is enabled
+ * @since 2.0
+ */
+public boolean isRolloverEnabled() {
+	return (flags & ROLLOVER_ENABLED_FLAG) != 0;
+}
+
+/**
+ * Returns <code>true</code> if this Clickable is in a selected state. The model is the
+ * one which holds all this state based information.
+ *
+ * @return <code>true</code> if this Clickable is in a selected state
+ * @since 2.0
+ */
+public boolean isSelected() {
+	return getModel().isSelected();
+}
+
+/**
+ * Returns <code>true</code> if this Clickable's style is the same as the passed style.
+ * 
+ * @param style The style to be checked
+ * @return <code>true</code> if this Clickable's style is the same as the passed style
+ * @since 2.0
+ */
+public boolean isStyle(int style) {
+	return ((style & flags) == style);
+}
+
+/**
+ * If this Clickable has focus, this method paints a focus rectangle.
+ * 
+ * @param graphics Graphics handle for painting
+ */
+protected void paintBorder(Graphics graphics) {
+	super.paintBorder(graphics);
+	if (hasFocus()) {
+		graphics.setForegroundColor(ColorConstants.black);
+		graphics.setBackgroundColor(ColorConstants.white);
+
+		Rectangle area = getClientArea();
+		if (isStyle(STYLE_BUTTON))
+			graphics.drawFocus(area.x, area.y, area.width, area.height);
+		else
+			graphics.drawFocus(area.x, area.y, area.width - 1, area.height - 1);
+	}
+}
+
+/**
+ * Paints the area of this figure excluded by the borders. Induces a (1,1) pixel shift in
+ * the painting if the  mouse is armed, giving it the pressed appearance. 
+ *
+ * @param graphics  Graphics handle for painting
+ * @since 2.0
+ */
+protected void paintClientArea(Graphics graphics) {
+	if (isStyle(STYLE_BUTTON) && (getModel().isArmed() || getModel().isSelected())) {
+		graphics.translate(1, 1);
+		graphics.pushState();
+		super.paintClientArea(graphics);
+		graphics.popState();
+		graphics.translate(-1, -1);
+	} else 
+		super.paintClientArea(graphics);
+}
+
+/**
+ * Removes the given listener from the list of ActionListener's of this Clickable.
+ * 
+ * @param listener Listener to be removed from this figure
+ * @since 2.0
+ */
+public void removeActionListener(ActionListener listener) {
+	removeListener(ActionListener.class, listener);
+}
+
+/**
+ * Removes the given listener from the list of ChangeListener's of this clickable.
+ * 
+ * @param listener Listener to be removed from this figure
+ * @since 2.0
+ */
+public void removeChangeListener(ChangeListener listener) {
+	removeListener(ChangeListener.class, listener);
+}
+
+/**
+ * Sets the Figure which is the contents of this Clickable. This Figure occupies the
+ * entire clickable region.
+ *
+ * @param contents Contents of the clickable
+ * @since 2.0
+ */
+protected void setContents(IFigure contents) {
+	setLayoutManager(new StackLayout());
+	if (getChildren().size() > 0)
+		remove((IFigure)getChildren().get(0));
+	add(contents);
+}
+
+/**
+ * @see org.eclipse.draw2d.IFigure#setEnabled(boolean)
+ */
+public void setEnabled(boolean value) {
+	if (isEnabled() == value) 
+		return;
+	super.setEnabled(value);
+	getModel().setEnabled(value);
+	setChildrenEnabled(value);
+}
+
+/**
+ * Sets the event handler which interacts with the model to determine the behavior of this
+ * Clickable.
+ *
+ * @param h  Event handler for this clickable
+ * @since 2.0
+ */
+public void setEventHandler(ClickableEventHandler h) {
+	if (eventHandler != null) 
+		unhookEventHandler(eventHandler);
+	eventHandler = h;
+	if (eventHandler != null) 
+		hookEventHandler(eventHandler);
+}
+
+/**
+ * Determines how this clickable is to fire notifications to its listeners. In the default
+ * firing method ({@link #DEFAULT_FIRING}), an action is performed  every time the mouse
+ * is released. In the repeat firing method ({@link #REPEAT_FIRING}), firing starts as
+ * soon as it is pressed on this clickable, and keeps firing at prefixed intervals until
+ * the mouse is released.
+ *
+ * @param type  Type of firing
+ * @since 2.0
+ */
+public void setFiringMethod(int type) {
+	getModel().setFiringBehavior(type);
+}
+
+/**
+ * Sets the model to be used by this clickable for its state and behavior determination.
+ * This clickable removes any observers from the previous model before adding new ones to
+ * the new model.
+ *
+ * @param model The new model of this Clickable
+ * @since 2.0
+ */
+public void setModel(ButtonModel model) {
+	if (this.model != null) {
+		this.model.removeChangeListener(modelObserver);
+		this.model.removeActionListener(modelObserver);
+		modelObserver = null;
+	}
+	this.model = model;
+	if (model != null) {
+		modelObserver = createModelObserver();
+		model.addActionListener(modelObserver);
+		model.addChangeListener(modelObserver);
+	}
+}
+
+/**
+ * Enables or disables rollover feedback of this figure. Generally used in conjunction
+ * with the model to determine if feedback is to be shown. 
+ *
+ * @param value The rollover state to be set
+ * @since 2.0
+ */
+public void setRolloverEnabled(boolean value) {
+	if (isRolloverEnabled() == value)
+		return;
+	setFlag(ROLLOVER_ENABLED_FLAG, value);
+	repaint();
+}
+
+/**
+ * Sets the selected state of this Clickable. Since the model is responsible for all state
+ * based information, it is informed of the state change. Extending classes can choose
+ * selection information, if they do not represent any selection.
+ *
+ * @param value  New selected state of this clickable.
+ * @see  #isSelected()
+ * @since 2.0
+ */
+public void setSelected(boolean value) {
+	getModel().setSelected(value);
+}
+
+/**
+ * Sets this Clickable's style to the passed value, either {@link #STYLE_BUTTON} or 
+ * {@link #STYLE_TOGGLE}.
+ *
+ * @param style The button style 
+ * @since 2.0
+ */
+public void setStyle(int style) {
+	if ((style & STYLE_BUTTON) != 0) {
+		setFlag(STYLE_BUTTON_FLAG, true);
+		if (!(getBorder() instanceof ButtonBorder))
+			setBorder(new ButtonBorder());
+		setOpaque(true);
+	} else {
+		setFlag(STYLE_BUTTON_FLAG, false);
+		setOpaque(false);
+	}
+
+	if ((style & STYLE_TOGGLE) != 0) {
+		setFlag(STYLE_TOGGLE_FLAG, true);
+		setModel(createDefaultModel());
+	}
+}
+
+/**
+ * Removes the given ClickableEventHandler containing listeners from this Clickable.
+ *
+ * @param handler The event handler to be removed
+ * @since 2.0
+ */
+protected void unhookEventHandler(ClickableEventHandler handler) {
+	if (handler == null) 
+		return;
+	removeMouseListener(handler);
+	removeMouseMotionListener(handler);
+	removeChangeListener(handler);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ClickableEventHandler.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ClickableEventHandler.java
new file mode 100644
index 0000000..6a18c6a
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ClickableEventHandler.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+class ClickableEventHandler
+	extends MouseMotionListener.Stub
+	implements
+		MouseListener,
+		FigureListener,
+		ChangeListener,
+		KeyListener,
+		FocusListener
+{
+
+private MouseEvent lastEvent;
+
+public void focusLost(FocusEvent fe) {
+	Clickable loser = (Clickable)fe.loser;
+	loser.repaint();
+	loser.getModel().setArmed(false);
+	loser.getModel().setPressed(false);
+}
+
+public void focusGained(FocusEvent fe) {
+	Clickable clickable = (Clickable)fe.gainer;
+	clickable.repaint();
+}	
+
+public void figureMoved(IFigure source) {
+	if (lastEvent == null)
+		return;
+	mouseDragged(lastEvent);
+}
+
+public void handleStateChanged(ChangeEvent change) {
+	Clickable clickable = (Clickable)change.getSource();
+	if (change.getPropertyName() == ButtonModel.MOUSEOVER_PROPERTY
+		&& !clickable.isRolloverEnabled())
+		return;
+	clickable.repaint();
+}
+
+public void mouseDoubleClicked(MouseEvent me) { }
+
+public void mouseDragged(MouseEvent me) {
+	lastEvent = me;
+	Clickable click = (Clickable)me.getSource();
+	ButtonModel model = click.getModel();
+	if (model.isPressed()) {
+		boolean over = click.containsPoint(me.getLocation());
+			model.setArmed(over);
+			model.setMouseOver(over);
+	}
+}
+
+public void mouseEntered(MouseEvent me) {
+	Clickable click = (Clickable)me.getSource();
+	click.getModel().setMouseOver(true);
+	click.addFigureListener(this);
+}
+
+public void mouseExited(MouseEvent me) {
+	Clickable click = (Clickable)me.getSource();
+	click.getModel().setMouseOver(false);
+	click.removeFigureListener(this);
+}
+
+public void mouseMoved(MouseEvent me) { }
+
+public void mousePressed(MouseEvent me) {
+	if (me.button != 1)
+		return;
+	lastEvent = me;
+	Clickable click = (Clickable)me.getSource();
+	ButtonModel model = click.getModel();
+	click.requestFocus();
+	model.setArmed(true);
+	model.setPressed(true);
+	me.consume();
+}
+
+public void mouseReleased(MouseEvent me) {
+	if (me.button != 1)
+		return;
+	ButtonModel model = ((Clickable)me.getSource()).getModel();
+	if (!model.isPressed())
+		return;
+	model.setPressed(false);
+	model.setArmed(false);
+	me.consume();
+}
+
+public void keyPressed(KeyEvent ke) {	
+	ButtonModel model = ((Clickable)ke.getSource()).getModel();
+	if (ke.character == ' ' || ke.character == '\r') {
+		model.setPressed(true);
+		model.setArmed(true);
+	}
+}
+
+public void keyReleased(KeyEvent ke) {
+	ButtonModel model = ((Clickable)ke.getSource()).getModel();
+	if (ke.character == ' ' || ke.character == '\r') {
+		model.setPressed(false);
+		model.setArmed(false);
+	}
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ColorConstants.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ColorConstants.java
new file mode 100644
index 0000000..b705804
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ColorConstants.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * A collection of color-related constants.
+ */
+public interface ColorConstants {
+
+class SystemColorFactory {
+	private static Color getColor(final int which) {
+		Display display = Display.getCurrent();
+		if (display != null)
+			return display.getSystemColor(which);
+		display = Display.getDefault();
+		final Color result[] = new Color[1];
+		display.syncExec(new Runnable() {
+			public void run() {
+				synchronized (result) {
+					result[0] = Display.getCurrent().getSystemColor(which);					
+				}
+			}
+		});
+		synchronized (result) {
+			return result[0];
+		}
+	}
+}
+
+/**
+ * @see SWT#COLOR_WIDGET_HIGHLIGHT_SHADOW
+ */
+Color buttonLightest
+				= SystemColorFactory.getColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
+/**
+ * @see SWT#COLOR_WIDGET_BACKGROUND
+ */
+Color button
+				= SystemColorFactory.getColor(SWT.COLOR_WIDGET_BACKGROUND);
+/**
+ * @see SWT#COLOR_WIDGET_NORMAL_SHADOW
+ */
+Color buttonDarker
+				= SystemColorFactory.getColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
+/**
+ * @see SWT#COLOR_WIDGET_DARK_SHADOW
+ */
+Color buttonDarkest           
+				= SystemColorFactory.getColor(SWT.COLOR_WIDGET_DARK_SHADOW);
+
+/**
+ * @see SWT#COLOR_LIST_BACKGROUND
+ */
+Color listBackground          
+				= SystemColorFactory.getColor(SWT.COLOR_LIST_BACKGROUND);
+/**
+ * @see SWT#COLOR_LIST_FOREGROUND
+ */
+Color listForeground          
+				= SystemColorFactory.getColor(SWT.COLOR_LIST_FOREGROUND);
+
+/**
+ * @see SWT#COLOR_WIDGET_BACKGROUND
+ */
+Color menuBackground          
+				= SystemColorFactory.getColor(SWT.COLOR_WIDGET_BACKGROUND);
+/**
+ * @see SWT#COLOR_WIDGET_FOREGROUND
+ */
+Color menuForeground          
+				= SystemColorFactory.getColor(SWT.COLOR_WIDGET_FOREGROUND);
+/**
+ * @see SWT#COLOR_LIST_SELECTION
+ */
+Color menuBackgroundSelected  
+				= SystemColorFactory.getColor(SWT.COLOR_LIST_SELECTION);
+/**
+ * @see SWT#COLOR_LIST_SELECTION_TEXT
+ */
+Color menuForegroundSelected  
+				= SystemColorFactory.getColor(SWT.COLOR_LIST_SELECTION_TEXT);
+
+/**
+ * @see SWT#COLOR_TITLE_BACKGROUND
+ */
+Color titleBackground         
+				= SystemColorFactory.getColor(SWT.COLOR_TITLE_BACKGROUND);
+/**
+ * @see SWT#COLOR_TITLE_BACKGROUND_GRADIENT
+ */
+Color titleGradient           
+				= SystemColorFactory.getColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT);
+/**
+ * @see SWT#COLOR_TITLE_FOREGROUND
+ */
+Color titleForeground         
+				= SystemColorFactory.getColor(SWT.COLOR_TITLE_FOREGROUND);
+/**
+ * @see SWT#COLOR_TITLE_INACTIVE_FOREGROUND
+ */
+Color titleInactiveForeground 
+				= SystemColorFactory.getColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
+/**
+ * @see SWT#COLOR_TITLE_INACTIVE_FOREGROUND
+ */
+Color titleInactiveBackground 
+				= SystemColorFactory.getColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
+/**
+ * @see SWT#COLOR_TITLE_INACTIVE_FOREGROUND
+ */
+Color titleInactiveGradient   
+				= SystemColorFactory.getColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
+
+/**
+ * @see SWT#COLOR_INFO_FOREGROUND
+ */
+Color tooltipForeground       
+				= SystemColorFactory.getColor(SWT.COLOR_INFO_FOREGROUND);
+/**
+ * @see SWT#COLOR_INFO_BACKGROUND
+ */
+Color tooltipBackground       
+				= SystemColorFactory.getColor(SWT.COLOR_INFO_BACKGROUND);
+
+/*
+ * Misc. colors
+ */
+/** One of the pre-defined colors */
+Color white      = new Color(null, 255, 255, 255);
+/** One of the pre-defined colors */
+Color lightGray  = new Color(null, 192, 192, 192);
+/** One of the pre-defined colors */
+Color gray       = new Color(null, 128, 128, 128);
+/** One of the pre-defined colors */
+Color darkGray   = new Color(null,  64,  64,  64);
+/** One of the pre-defined colors */
+Color black      = new Color(null,   0,   0,   0);
+/** One of the pre-defined colors */
+Color red        = new Color(null, 255,   0,   0);
+/** One of the pre-defined colors */
+Color orange     = new Color(null, 255, 196,   0);
+/** One of the pre-defined colors */
+Color yellow     = new Color(null, 255, 255,   0);
+/** One of the pre-defined colors */
+Color green      = new Color(null,   0, 255,   0);
+/** One of the pre-defined colors */
+Color lightGreen = new Color(null,  96, 255,  96);
+/** One of the pre-defined colors */
+Color darkGreen  = new Color(null,   0, 127,   0);
+/** One of the pre-defined colors */
+Color cyan       = new Color(null,   0, 255, 255);
+/** One of the pre-defined colors */
+Color lightBlue  = new Color(null, 127, 127, 255);
+/** One of the pre-defined colors */
+Color blue       = new Color(null,   0,   0, 255);
+/** One of the pre-defined colors */
+Color darkBlue   = new Color(null,   0,   0, 127);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CompoundBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CompoundBorder.java
new file mode 100644
index 0000000..f4d8a61
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CompoundBorder.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+
+/**
+ * CompoundBorder allows for the nesting of two borders. The nested borders are referred
+ * to as the <i>inner</i> and <i>outer</i> borders.
+ */
+public class CompoundBorder
+	extends AbstractBorder
+{
+
+/** The inner Border. */
+protected Border inner;
+/** The outer Border. */
+protected Border outer;
+
+/**
+ * Constructs a default CompoundBorder with no borders under it.
+ * 
+ * @since 2.0
+ */
+public CompoundBorder() { }
+
+/**
+ * Constructs a CompoundBorder with the two borders specified as input. 
+ *
+ * @param outer  Border which is drawn on the outside
+ * @param inner  Border which is drawn inside the outer border
+ * 
+ * @since 2.0
+ */
+public CompoundBorder(Border outer, Border inner) {
+	this.outer = outer;
+	this.inner = inner;
+}
+
+/**
+ * Returns the inner border of this CompoundBorder.
+ * 
+ * @return The inner border
+ * @since 2.0
+ */
+public Border getInnerBorder() {
+	return inner;
+}
+
+/**
+ * Returns the total insets required to hold both the inner and outer borders of this
+ * CompoundBorder.
+ *
+ * @param figure  Figure for which this is the border
+ * @return  The total insets for this border
+ * @since 2.0
+ */
+public Insets getInsets(IFigure figure) {
+	Insets insets = null;
+	if (inner != null)
+		insets = inner.getInsets(figure);
+	else
+		insets = new Insets();
+	if (outer != null) {
+		Insets moreInsets = outer.getInsets(figure);
+		insets = insets.getAdded(moreInsets);
+	}
+	return insets;
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#getPreferredSize(IFigure)
+ */
+public Dimension getPreferredSize(IFigure fig) {
+	Dimension prefSize = new Dimension(inner.getPreferredSize(fig));
+	Insets outerInsets = outer.getInsets(fig);
+	prefSize.expand(outerInsets.getWidth(), outerInsets.getHeight());
+	prefSize.union(outer.getPreferredSize(fig));
+	return prefSize;
+}
+
+/**
+ * Returns the outer border of this CompoundBorder.
+ * 
+ * @return The outer border
+ * @since 2.0
+ */
+public Border getOuterBorder() {
+	return outer;
+}
+
+/**
+ * Returns <code>true</code> if this border is opaque. Return value is dependent on the 
+ * opaque state of both the borders it contains. Both borders have to be opaque for this
+ * border to be opaque. In the absence of any of the borders, this border is not opaque.
+ * 
+ * @return <code>true</code> if this border is opaque
+ */
+public boolean isOpaque() {
+	return ((inner != null) ? inner.isOpaque() : false) 
+			&& ((outer != null) ? outer.isOpaque() : false);
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#paint(IFigure, Graphics, Insets)
+ */
+public void paint(IFigure figure, Graphics g, Insets insets) {
+	if (outer != null) {
+		g.pushState();
+		outer.paint(figure, g, insets);
+		g.popState();
+
+		insets = insets.getAdded(outer.getInsets(figure));
+	}
+	if (inner != null)
+		inner.paint(figure, g, insets);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Connection.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Connection.java
new file mode 100644
index 0000000..f16b9e8
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Connection.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.PointList;
+
+/**
+ * A Connection is a figure that connects two objects.
+ */
+public interface Connection extends IFigure {
+
+/** 
+ * The connection router property.  Used to signify that the ConnectionRouter has changed.
+ */
+String PROPERTY_CONNECTION_ROUTER = "connectionRouter"; //$NON-NLS-1$
+/**
+ * The points property.  Used to signify the points in the Connection have changed.
+ */
+String PROPERTY_POINTS = "points"; //$NON-NLS-1$
+
+/**
+ * Returns the ConnectionRouter used to route this Connection.  Does not return null.
+ * 
+ * @return The ConnectionRouter for this Connection
+ */
+ConnectionRouter getConnectionRouter();
+
+/**
+ * Sets the ConnectionRouter for this Connection.
+ * 
+ * @param router The ConnectionRouter to set for this Connection
+ */
+void setConnectionRouter(ConnectionRouter router);
+
+/**
+ * Returns the ConnectionAnchor at the <b>source</b> end of this Connection.
+ * @return The ConnectionAnchor at the <b>source</b> end of this Connection
+ */
+ConnectionAnchor getSourceAnchor();
+
+/**
+ * Returns the ConnectionAnchor at the <b>target</b> end of this Connection.
+ * @return The ConnectionAnchor at the <b>target</b> end of this Connection
+ */
+ConnectionAnchor getTargetAnchor();
+
+/**
+ * Returns the routing constraint.  May be <code>null</code>.
+ * @return The routing constraint
+ */
+Object getRoutingConstraint();
+
+/**
+ * Sets the routing constraint used by the router.
+ * @param cons The routing constraint
+ */
+void setRoutingConstraint(Object cons);
+
+/**
+ * Sets the ConnectionAnchor to be used at the <i>source</i> end of this Connection.
+ * @param anchor The source anchor
+ */
+void setSourceAnchor(ConnectionAnchor anchor);
+
+/**
+ * Sets the ConnectionAnchor to be used at the <i>target</i> end of this Connection.
+ * @param anchor The target anchor
+ */
+void setTargetAnchor(ConnectionAnchor anchor);
+
+/**
+ * Returns the PointList containing the Points that make up this Connection.  This may be
+ * returned by reference.
+ * @return The points for this Connection
+ */
+PointList getPoints();
+
+/**
+ * Sets the PointList containing the Points that make up this Connection.
+ * @param list The points for this Connection
+ */
+void setPoints(PointList list);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionAnchor.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionAnchor.java
new file mode 100644
index 0000000..aa4293a
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionAnchor.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * An object to which a {@link Connection} will be anchored.  If the ConnectionAnchor
+ * moves, the Connection should move with it.
+ */
+public interface ConnectionAnchor {
+	
+/**
+ * Adds a listener interested in the movement of this ConnectionAnchor.
+ * @param listener The AnchorListener to be added
+ */
+void addAnchorListener(AnchorListener listener);
+
+/**
+ * Returns the location where the Connection should be anchored in absolute coordinates. 
+ * The anchor may use the given reference Point to calculate this location.
+ * @param reference The reference Point in absolute coordinates
+ * @return The anchor's location
+ */
+Point getLocation(Point reference);
+
+/**
+ * Returns the IFigure that contains this ConnectionAnchor.  Moving this figure will cause
+ * the anchor to move with it.
+ * @return The IFigure that contains this ConnectionAnchor
+ */
+IFigure getOwner();
+
+/**
+ * Returns the reference point for this anchor in absolute coordinates. This might be used
+ * by another anchor to determine its own location (i.e. {@link ChopboxAnchor}).
+ * @return The reference Point
+ */
+Point getReferencePoint();
+
+/**
+ * Removes the listener.
+ * @param listener The AnchorListener to be removed
+ */
+void removeAnchorListener(AnchorListener listener);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionAnchorBase.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionAnchorBase.java
new file mode 100644
index 0000000..55c9008
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionAnchorBase.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Provides support for a ConnectionAnchor. A ConnectionAnchor is one of the end points
+ * of a {@link Connection}. It holds listeners and notifies them if the anchor is moved.
+ */
+public abstract class ConnectionAnchorBase
+	implements ConnectionAnchor
+{
+
+/**
+ * The list of listeners
+ */
+protected List listeners = new ArrayList(1);
+
+/**
+ * @see org.eclipse.draw2d.ConnectionAnchor#addAnchorListener(AnchorListener)
+ */
+public void addAnchorListener(AnchorListener listener) {
+	listeners.add(listener);
+}
+
+/**
+ * @see org.eclipse.draw2d.ConnectionAnchor#removeAnchorListener(AnchorListener)
+ */
+public void removeAnchorListener(AnchorListener listener) {
+	listeners.remove(listener);
+}
+
+/** 
+ * Notifies all the listeners in the list of a change in position of this anchor. This is
+ * called from one of the implementing anchors when its location is changed.
+ * 
+ * @since 2.0
+ */
+protected void fireAnchorMoved() {
+	Iterator iter = listeners.iterator();
+	while (iter.hasNext())
+		((AnchorListener)iter.next()).anchorMoved(this);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionEndpointLocator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionEndpointLocator.java
new file mode 100644
index 0000000..342e9c9
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionEndpointLocator.java
@@ -0,0 +1,274 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.draw2d.geometry.Transposer;
+
+/**
+ * Used to place IFigures along the endpoint or starting point of a {@link Connection}. 
+ * <code>uDistance</code> represents the distance from the Connection's owner to the 
+ * IFigure. <code>vDistance</code> represents the distance from the IFigure to the
+ * Connection itself.
+ */
+public class ConnectionEndpointLocator 
+	implements Locator
+{
+
+private boolean end;
+private Connection conn;
+private int uDistance;
+private int vDistance;
+private static Rectangle figureBounds;
+
+/**
+ * Transposes the location if the connection point is along the top or bottom of its owner
+ * figure.
+ */
+protected Transposer transposer = new Transposer();
+
+/** 
+ * Constructs a ConnectionEndpointLocator using the given {@link Connection}.  If
+ * <i>isEnd</i> is <code>true</code>, the location is relative to the Connection's end (or
+ * target) point. If <i>isEnd</i> is <code>false</code>, the location is relative to the
+ * Connection's start (or source) point.
+ *
+ * @param c The Connection
+ * @param isEnd <code>true</code> is location is relative to end point
+ * @since 2.0
+ */
+public ConnectionEndpointLocator(Connection c, boolean isEnd) {
+	end = isEnd;
+	conn = c;
+	uDistance = 14;
+	vDistance = 4;
+	figureBounds = new Rectangle();
+}
+
+/*
+ * Returns an integer representing the side of the passed Rectangle that a point lies on.
+ *  1 == Top
+ *  2 == Right 
+ *  3 == Bottom 
+ *  4 == Left
+ *  
+ * @param loc The point that is to be located
+ */
+private int calculateConnectionLocation(Point loc, Point topLeft, Point center) {
+	double m1, m2 = 0;	
+	m1 = (double)(topLeft.y - center.y) / (double)(topLeft.x - center.x);
+	
+	if (loc.x - center.x != 0)	
+		m2 = (double)(loc.y - center.y) / (double)(loc.x - center.x);
+	
+	if (loc.x == center.x) { 
+		// Case where m2 is vertical
+		if (loc.y < center.y)
+			return 3;		
+		else
+			return 1;
+	} else if (Math.abs(m2) <= Math.abs(m1)) { 
+		// Connection start point along left or right side
+		if (loc.x < center.x) 
+			return 4;
+		else
+			return 2;
+	} else { 
+		// Connection start point along top or bottom
+		if (loc.y < center.y)
+			return 3;
+		else
+			return 1;
+	}
+}
+
+/*
+ * This method is used to calculate the "quadrant" value of a connection that does not
+ * have an owner on its starting point. 
+ * 
+ * 1 == Top
+ * 2 == Right
+ * 3 == Bottom
+ * 4 == Left
+ *
+ * @param startPoint The starting point of the connection.
+ * @param endPoint The end point of the connection.
+ */
+private int calculateConnectionLocation(Point startPoint, Point endPoint) {
+	if (Math.abs(endPoint.x - startPoint.x) > Math.abs(endPoint.y - startPoint.y)) {
+		if (endPoint.x > startPoint.x)
+			return 2;
+		else
+			return 4;
+	} else {
+		if (endPoint.y > startPoint.y)
+			return 1;
+		else
+			return 3;
+	}				
+}	
+
+/*
+ * Calculates 'tan' which is used as a factor for y adjustment when placing the connection
+ * label. 'tan' is capped at 1.0 in the positive direction and -1.0 in the negative
+ * direction.
+ * 
+ * @param startPoint The starting point of the connection.
+ * @param endPoint The end point of the connection.
+ * @since 2.0
+ */
+private double calculateTan(Point startPoint, Point endPoint) {
+	double tan = 0;
+	if (endPoint.x == startPoint.x)
+		tan = 1.0;
+	else
+		tan = (double)(endPoint.y - startPoint.y) 
+				/ (double)(endPoint.x - startPoint.x);	      		      
+	if (tan > 1)
+		tan = 1.0;
+	else if (tan < -1)
+		tan = -1.0;
+	
+	return tan;
+}
+
+private int calculateYShift(int figureWidth, int figureHeight) {
+	int yShift = 0;
+	if (vDistance < 0)
+		yShift = -figureHeight;
+	else if (vDistance == 0)
+		yShift = -figureHeight / 2;
+	return yShift;
+}
+
+private Connection getConnection() {
+	return conn;
+}
+
+private IFigure getConnectionOwner() {
+	IFigure connOwner;
+	if (isEnd())
+		connOwner = conn.getTargetAnchor().getOwner();
+	else
+		connOwner = conn.getSourceAnchor().getOwner();
+		
+	return connOwner;	
+}
+
+/**
+ * Returns the distance in pixels from the anchor's owner.
+ * @return the offset distance from the endpoint figure
+ */
+public int getUDistance() {
+	return uDistance;
+}
+
+/**
+ * Returns the distance in pixels from the connection
+ * @return the offset from the connection itself
+ */
+public int getVDistance() {
+	return vDistance;
+}
+
+private boolean isEnd() {
+	return end;
+}
+
+/**
+ * Relocates the given IFigure at either the source or target end of the Connection, 
+ * based on the <code>boolean</code> given in the constructor
+ * {@link #ConnectionEndpointLocator(Connection, boolean)}.
+ * 
+ * @param figure The figure to relocate
+ */
+public void relocate(IFigure figure) {
+	Connection conn = getConnection();
+	Point startPoint = Point.SINGLETON;
+	Point endPoint = new Point();
+	
+	int startPointPosition = 0;
+	int endPointPosition = 1;
+	if (isEnd()) {
+		startPointPosition = conn.getPoints().size() - 1;
+		endPointPosition = startPointPosition - 1;
+	}
+	
+	conn.getPoints().getPoint(startPoint, startPointPosition);
+	conn.getPoints().getPoint(endPoint, endPointPosition);
+	
+	IFigure connOwner = getConnectionOwner();
+	
+	int quadrant;
+	if (connOwner != null) {
+		Rectangle connOwnerBounds = connOwner.getBounds();
+		Point connOwnerCenter = connOwnerBounds.getCenter();
+		Point connOwnerTL = connOwnerBounds.getTopLeft();
+		quadrant = calculateConnectionLocation(startPoint, connOwnerTL, connOwnerCenter);
+	} else
+		quadrant = calculateConnectionLocation(startPoint, endPoint);
+
+	int cos = 1;
+	transposer.setEnabled(false);
+	
+	/*
+	 * Label placement calculations are done as if the connection point is along the left
+	 * or right side of the  figure. If the connection point is along the top or bottom,
+	 * values are transposed.
+	 */
+	if (quadrant == 1 || quadrant == 3)
+		transposer.setEnabled(true);
+	
+	if (quadrant == 3 || quadrant == 4)
+		cos = -1;		
+
+	Dimension figureSize = transposer.t(figure.getPreferredSize());
+	startPoint = transposer.t(startPoint);
+	endPoint = transposer.t(endPoint);
+
+	double tan = calculateTan(startPoint, endPoint);
+
+	int figureWidth = figureSize.width;
+	int figureHeight = figureSize.height;
+	int yShift = calculateYShift(figureWidth, figureHeight);
+	
+	Point figurePoint = 
+		new Point(startPoint.x + (uDistance * cos) + figureWidth * ((cos - 1) / 2),
+				(int)(startPoint.y + cos * uDistance * tan + vDistance + yShift));
+
+	figureBounds.setSize(transposer.t(figureSize));
+	figureBounds.setLocation(transposer.t(figurePoint));
+	figure.setBounds(figureBounds);
+}
+
+/**
+ * Sets the distance in pixels from the Connection's owner.
+ * 
+ * @param distance Number of pixels to place the ConnectionEndpointLocator from its owner.
+ * @since 2.0
+ */
+public void setUDistance(int distance) {
+	uDistance = distance;
+}
+
+/**
+ * Sets the distance in pixels from the Connection.
+ * 
+ * @param distance Number of pixels to place the ConnectionEndpointLocator from its
+ * Connection.
+ * @since 2.0
+ */
+public void setVDistance(int distance) {
+	vDistance = distance;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionLayer.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionLayer.java
new file mode 100644
index 0000000..6a72a39
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionLayer.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+
+/**
+ * Layer designed specifically to handle the presence of connections. This is done due to
+ * the necessity of having a router for the connections added.
+ */
+public class ConnectionLayer
+	extends FreeformLayer
+{
+
+int antialias = SWT.DEFAULT;
+
+/**
+ * The ConnectionRouter used to route all connections on this layer.
+ */
+protected ConnectionRouter connectionRouter;
+
+/**
+ * Adds the given figure with the given contraint at the given index. If the figure is a
+ * {@link Connection}, its {@link ConnectionRouter} is set.
+ *
+ * @param figure  Figure being added
+ * @param constraint  Constraint of the figure being added
+ * @param index  Index where the figure is to be added
+ * @since 2.0 
+ */
+public void add(IFigure figure, Object constraint, int index) {
+	super.add(figure, constraint, index);
+	
+	// If the connection layout manager is set, then every
+	// figure added should use this layout manager.
+	if (figure instanceof Connection && getConnectionRouter() != null)
+		((Connection)figure).setConnectionRouter(getConnectionRouter());
+}
+
+/**
+ * Returns the ConnectionRouter being used by this layer.
+ *
+ * @return  ConnectionRouter being used by this layer
+ * @since 2.0
+ */
+public ConnectionRouter getConnectionRouter() {
+	return connectionRouter;
+}
+
+/**
+ * @see IFigure#paint(Graphics)
+ */
+public void paint(Graphics graphics) {
+	if (antialias != SWT.DEFAULT)
+		graphics.setAntialias(antialias);
+	super.paint(graphics);
+}
+
+/**
+ * Removes the figure from this Layer.  If the figure is a {@link Connection}, that
+ * Connection's {@link ConnectionRouter} is set to <code>null</code>.
+ * 
+ * @param figure The figure to remove
+ */
+public void remove(IFigure figure) {
+	if (figure instanceof Connection)
+		((Connection)figure).setConnectionRouter(null);
+	super.remove(figure);
+}
+
+/**
+ * Sets the ConnectionRouter for this layer. This router is set as the ConnectionRouter
+ * for all the child connections of this Layer.
+ *
+ * @param router  The ConnectionRouter to set for this Layer
+ * @since 2.0
+ */
+public void setConnectionRouter(ConnectionRouter router) {
+	connectionRouter = router;
+	FigureIterator iter = new FigureIterator(this);
+	IFigure figure;
+	while (iter.hasNext()) {
+		figure = iter.nextFigure();
+		if (figure instanceof Connection)
+			((Connection)figure).setConnectionRouter(router);
+	}
+}
+
+/**
+ * Sets whether antialiasing should be enabled for the connection layer. If this value is
+ * set to something other than {@link SWT#DEFAULT}, {@link Graphics#setAntialias(int)}
+ * will be called with the given value when painting this layer.
+ * @param antialias the antialias setting
+ * @since 3.1
+ */
+public void setAntialias(int antialias) {
+	this.antialias = antialias;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionLocator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionLocator.java
new file mode 100644
index 0000000..2c40eb8
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionLocator.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+
+/**
+ * Repositions a {@link Figure} attached to a {@link Connection} when the Connection is
+ * moved.  Provides for alignment at the start (source), middle, or end (target) of the
+ * Connection.
+ */
+public class ConnectionLocator
+	extends AbstractLocator 
+{
+
+/** @deprecated Use {@link #SOURCE} */
+public static final int START  = 2;
+/** The start (or source) of the Connection */
+public static final int SOURCE = 2;
+
+/** @deprecated Use {@link #TARGET} */
+public static final int END    = 3;
+/** The end (or target) of the Connection */
+public static final int TARGET = 3;
+
+/**
+ * @deprecated Use {@link #MIDDLE} instead, since the location is not the midpoint of a
+ * line-segment, but the middle of a polyline.
+ */
+public static final int MIDPOINT   = 4;
+/** The middle of the Connection */
+public static final int MIDDLE     = 4;
+
+private Connection connection;
+private int alignment;
+
+/**
+ * Constructs a ConnectionLocator with the passed connection and {@link #MIDDLE}
+ * alignment.
+ * 
+ * @param connection The Connection
+ * @since 2.0
+ */
+public ConnectionLocator(Connection connection) {
+	this(connection, MIDDLE);
+}
+
+/**
+ * Constructs a ConnectionLocator with the passed Connection and alignment. Valid values 
+ * for the alignment are integer constants {@link #SOURCE}, {@link #MIDDLE}, and 
+ * {@link #TARGET}.
+ * 
+ * @param connection The Connection
+ * @param align The alignment
+ *               
+ * @since 2.0
+ */
+public ConnectionLocator(Connection connection, int align) {
+	setConnection(connection);
+	setAlignment(align);
+}
+
+/**
+ * Returns the alignment of ConnectionLocator.
+ * 
+ * @return The alignment
+ * @since 2.0
+ */
+public int getAlignment() {
+	return alignment;
+}
+
+/**
+ * Returns connection associated with ConnectionLocator.
+ * 
+ * @return The Connection
+ * @since 2.0
+ */
+protected Connection getConnection() {
+	return connection;
+}
+
+/**
+ * Returns ConnectionLocator's reference point in absolute coordinates.
+ * 
+ * @return The reference point
+ * @since 2.0
+ */
+protected Point getReferencePoint() {
+	Point p = getLocation(getConnection().getPoints());
+	getConnection().translateToAbsolute(p);
+	return p;
+}
+
+/**
+ * Returns a point from the passed PointList, dependent on ConnectionLocator's alignment.
+ * If the alignment is {@link #SOURCE}, it returns the first point in <i>points</i>. If
+ * {@link #TARGET}, it returns the last point in <i>points</i>. If {@link #MIDDLE}, it
+ * returns the middle of line represented by <i>points</i>.
+ * 
+ * @param points The points in the Connection
+ * @return The location 
+ * @since 2.0
+ */
+protected Point getLocation(PointList points) {
+	switch (getAlignment()) {
+		case SOURCE:
+			return points.getPoint(Point.SINGLETON, 0);
+		case TARGET:
+			return points.getPoint(Point.SINGLETON, points.size() - 1);
+		case MIDDLE:
+			if (points.size() % 2 == 0) {
+				int i = points.size() / 2;
+				int j = i - 1;
+				Point p1 = points.getPoint(j);
+				Point p2 = points.getPoint(i);
+				Dimension d = p2.getDifference(p1);
+				return Point.SINGLETON.setLocation(p1.x + d.width / 2, 
+													p1.y + d.height / 2);
+			}
+			int i = (points.size() - 1) / 2;
+			return points.getPoint(Point.SINGLETON, i);
+		default:
+			return new Point();
+	}
+}
+
+/**
+ * Sets the alignment.  Possible values are {@link #SOURCE}, {@link #MIDDLE}, and 
+ * {@link #TARGET}.
+ * 
+ * @param align The alignment
+ * @since 2.0
+ */
+protected void setAlignment(int align) {
+	alignment = align;
+}
+
+/**
+ * Sets the Connection to be associated with this ConnectionLocator.
+ * 
+ * @param connection The Connection
+ * @since 2.0
+ */
+protected void setConnection(Connection connection) {
+	this.connection = connection;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionRouter.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionRouter.java
new file mode 100644
index 0000000..d87e90e
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ConnectionRouter.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+
+/**
+ * Routes a {@link Connection}, possibly using a constraint.
+ */
+public interface ConnectionRouter {
+
+/**
+ * The default router for Connections.
+ */
+ConnectionRouter NULL = new NullConnectionRouter();
+
+/**
+ * Returns the constraint for the Connection.
+ * @param connection The connection
+ * @return The constraint
+ */
+Object getConstraint(Connection connection);
+
+/**
+ * Invalidates the given Connection.
+ * @param connection The connection to be invalidated
+ */
+void invalidate(Connection connection);
+
+/**
+ * Routes the Connection.
+ * @param connection The Connection to route
+ */
+void route(Connection connection);
+
+/**
+ * Removes the Connection from this router.
+ * @param connection The Connection to remove
+ */
+void remove(Connection connection);
+
+/**
+ * Maps the given constraint to the given Connection.
+ * @param connection The Connection
+ * @param constraint The constraint
+ */
+void setConstraint(Connection connection, Object constraint);
+
+/**
+ * Routes Connections directly from the source anchor to the target anchor with no
+ * bendpoints in between.
+ */
+class NullConnectionRouter
+	extends AbstractRouter
+{
+
+	/**
+	 * Constructs a new NullConnectionRouter.
+	 */
+	NullConnectionRouter() { }
+
+	/**
+	 * Routes the given Connection directly between the source and target anchors.
+	 * @param conn the connection to be routed
+	 */
+	public void route(Connection conn) {
+		PointList points = conn.getPoints();
+		points.removeAllPoints();
+		Point p;
+		conn.translateToRelative(p = getStartPoint(conn));
+		points.addPoint(p);
+		conn.translateToRelative(p = getEndPoint(conn));
+		points.addPoint(p);
+		conn.setPoints(points);
+	}
+
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CoordinateListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CoordinateListener.java
new file mode 100644
index 0000000..0889983
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/CoordinateListener.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.draw2d;
+
+/**
+ * @since 3.1
+ */
+public interface CoordinateListener {
+
+/**
+ * Indicates that the coordinate system has changed in a way that affects the absolute
+ * locations of contained figures.
+ * @param source the figure whose coordinate system changed
+ * @since 3.1
+ */
+void coordinateSystemChanged(IFigure source);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Cursors.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Cursors.java
new file mode 100644
index 0000000..4bd5832
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Cursors.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Cursor;
+
+/**
+ * A collection of cursors.
+ */
+public class Cursors {
+	
+/**
+ * Returns the cursor corresponding to the given direction, defined in 
+ * {@link PositionConstants}. Note that {@link #getDirectionalCursor(int, boolean)} should
+ * be used for applications which want to run properly when running in a mirrored
+ * environment. The behavior is the same as calling {@link #getDirectionalCursor(int,
+ * boolean) getDirectionalCursor(direction, false)}.
+ * 
+ * @param direction the relative direction of the desired cursor
+ * @return The appropriate directional cursor
+ */
+public static Cursor getDirectionalCursor(int direction) {
+	return getDirectionalCursor(direction, false);
+}
+
+/**
+ * Returns the cursor corresponding to the given direction and mirroring. The direction
+ * must be one of:
+ * <UL>
+ *   <LI>{@link PositionConstants#NORTH}
+ *   <LI>{@link PositionConstants#SOUTH}
+ *   <LI>{@link PositionConstants#EAST}
+ *   <LI>{@link PositionConstants#WEST}
+ *   <LI>{@link PositionConstants#NORTH_EAST}
+ *   <LI>{@link PositionConstants#NORTH_WEST}
+ *   <LI>{@link PositionConstants#SOUTH_EAST}
+ *   <LI>{@link PositionConstants#SOUTH_WEST}
+ * </UL>
+ * <P>The behavior is undefined for other values. If <code>isMirrored</code> is set to
+ * <code>true</code>, EAST and WEST will be inverted.
+ * @param direction the relative direction of the desired cursor
+ * @param isMirrored <code>true</code> if EAST and WEST should be inverted
+ * @return The appropriate directional cursor
+ */
+public static Cursor getDirectionalCursor(int direction, boolean isMirrored) {
+	if (isMirrored && (direction & PositionConstants.EAST_WEST) != 0)
+		direction = direction ^ PositionConstants.EAST_WEST; 
+	switch (direction) {
+		case PositionConstants.NORTH :
+			return SIZEN;
+		case PositionConstants.SOUTH:
+			return SIZES;
+		case PositionConstants.EAST :
+			return SIZEE;
+		case PositionConstants.WEST:
+			return SIZEW;
+		case PositionConstants.SOUTH_EAST:
+			return SIZESE;
+		case PositionConstants.SOUTH_WEST:
+			return SIZESW;
+		case PositionConstants.NORTH_EAST:
+			return SIZENE;
+		case PositionConstants.NORTH_WEST:
+			return SIZENW;
+		default:
+		 	break;
+	}
+	return null;
+}
+
+/**
+ * @see SWT#CURSOR_ARROW 
+ */
+public static final Cursor ARROW;
+/**
+ * @see SWT#CURSOR_SIZEN 
+ */
+public static final Cursor SIZEN;
+/**
+ * @see SWT#CURSOR_SIZENE 
+ */
+public static final Cursor SIZENE;
+/**
+ * @see SWT#CURSOR_SIZEE 
+ */
+public static final Cursor SIZEE;
+/**
+ * @see SWT#CURSOR_SIZESE 
+ */
+public static final Cursor SIZESE;
+/**
+ * @see SWT#CURSOR_SIZES 
+ */
+public static final Cursor SIZES;
+/**
+ * @see SWT#CURSOR_SIZESW 
+ */
+public static final Cursor SIZESW;
+/**
+ * @see SWT#CURSOR_SIZEW 
+ */
+public static final Cursor SIZEW;
+/**
+ * @see SWT#CURSOR_SIZENW 
+ */
+public static final Cursor SIZENW;
+/**
+ * @see SWT#CURSOR_APPSTARTING 
+ */
+public static final Cursor APPSTARTING;
+/**
+ * @see SWT#CURSOR_CROSS 
+ */
+public static final Cursor CROSS;
+/**
+ * @see SWT#CURSOR_HAND 
+ */
+public static final Cursor HAND;
+/**
+ * @see SWT#CURSOR_HELP 
+ */
+public static final Cursor HELP;
+/**
+ * @see SWT#CURSOR_IBEAM 
+ */
+public static final Cursor IBEAM;
+/**
+ * @see SWT#CURSOR_NO 
+ */
+public static final Cursor NO;
+/**
+ * @see SWT#CURSOR_SIZEALL 
+ */
+public static final Cursor SIZEALL;
+/**
+ * @see SWT#CURSOR_SIZENESW 
+ */
+public static final Cursor SIZENESW;
+/**
+ * @see SWT#CURSOR_SIZENWSE 
+ */
+public static final Cursor SIZENWSE;
+/**
+ * @see SWT#CURSOR_SIZEWE
+ */
+public static final Cursor SIZEWE;
+/**
+ * @see	SWT#CURSOR_SIZENS
+ */
+public static final Cursor SIZENS;
+/**
+ * @see SWT#CURSOR_UPARROW 
+ */
+public static final Cursor UPARROW;
+/**
+ * @see SWT#CURSOR_WAIT 
+ */
+public static final Cursor WAIT;
+
+static {
+	ARROW   = new Cursor(null, SWT.CURSOR_ARROW);
+	SIZEN   = new Cursor(null, SWT.CURSOR_SIZEN);
+	SIZENE  = new Cursor(null, SWT.CURSOR_SIZENE);
+	SIZEE   = new Cursor(null, SWT.CURSOR_SIZEE);
+	SIZESE  = new Cursor(null, SWT.CURSOR_SIZESE);
+	SIZES   = new Cursor(null, SWT.CURSOR_SIZES);
+	SIZESW  = new Cursor(null, SWT.CURSOR_SIZESW);
+	SIZEW   = new Cursor(null, SWT.CURSOR_SIZEW);
+	SIZENW  = new Cursor(null, SWT.CURSOR_SIZENW);
+	SIZENS  = new Cursor(null, SWT.CURSOR_SIZENS);
+	SIZEWE  = new Cursor(null, SWT.CURSOR_SIZEWE);
+	APPSTARTING	= new Cursor(null, SWT.CURSOR_APPSTARTING);
+	CROSS   = new Cursor(null, SWT.CURSOR_CROSS);
+	HAND    = new Cursor(null, SWT.CURSOR_HAND);
+	HELP    = new Cursor(null, SWT.CURSOR_HELP);
+	IBEAM   = new Cursor(null, SWT.CURSOR_IBEAM);
+	NO      = new Cursor(null, SWT.CURSOR_NO);
+	SIZEALL = new Cursor(null, SWT.CURSOR_SIZEALL);
+	SIZENESW = new Cursor(null, SWT.CURSOR_SIZENESW);
+	SIZENWSE = new Cursor(null, SWT.CURSOR_SIZENWSE);
+	UPARROW  = new Cursor(null, SWT.CURSOR_UPARROW);
+	WAIT     = new Cursor(null, SWT.CURSOR_WAIT);
+} 
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DefaultRangeModel.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DefaultRangeModel.java
new file mode 100644
index 0000000..5922866
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DefaultRangeModel.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ * Generic implementation for a RangeModel.
+ *
+ *
+ *<pre>
+ *                    |<----extent--->|                     
+ *    ----|-----------|---------------|---------------|----
+ *       min          |                              max
+ *                  value
+ * </pre>
+ */
+public class DefaultRangeModel 
+	implements RangeModel 
+{
+
+/**
+ * Listeners interested in the range model's property changes.
+ */
+protected PropertyChangeSupport propertyListeners = new PropertyChangeSupport(this);
+private int minimum = 0;
+private int maximum = 100;
+private int extent =  20;
+private int value = 0;
+
+/**
+ * Registers the given listener as a PropertyChangeListener.
+ * 
+ * @param listener the listener to be added
+ * @since 2.0
+ */
+public void addPropertyChangeListener(PropertyChangeListener listener) {
+	propertyListeners.addPropertyChangeListener(listener);
+}
+
+/**
+ * Notifies any listening PropertyChangeListeners that the property with the given id has 
+ * changed.
+ * 
+ * @param string the property name
+ * @param oldValue the old value
+ * @param newValue the new value
+ * @since 2.0
+ */
+protected void firePropertyChange(String string, int oldValue, int newValue) {
+	propertyListeners.firePropertyChange(string, oldValue, newValue);
+}
+
+/**
+ * @return the extent
+ */
+public int getExtent() {
+	return extent;
+}
+
+/**
+ * @return the maximum value
+ */
+public int getMaximum() {
+	return maximum;
+}
+
+/**
+ * @return the minimum value
+ */
+public int getMinimum() {
+	return minimum;
+}
+
+/**
+ * @return the current value
+ */
+public int getValue() {
+	return value;
+}
+
+/**
+ * @return whether the extent is between the minimum and maximum values
+ */
+public boolean isEnabled() {
+	return (getMaximum() - getMinimum()) > getExtent();
+}
+
+/**
+ * Removes the given PropertyChangeListener from the list of listeners.
+ * 
+ * @param listener the listener to be removed
+ */
+public void removePropertyChangeListener(PropertyChangeListener listener) {
+	propertyListeners.removePropertyChangeListener(listener);
+}
+
+/**
+ * @see org.eclipse.draw2d.RangeModel#setAll(int, int, int)
+ */
+public void setAll(int min, int ext, int max) {
+	int oldMin = minimum;
+	int oldExtent = extent;
+	int oldMax = maximum;
+	maximum = max;
+	minimum = min;
+	extent = ext;
+	if (oldMax != max)
+		firePropertyChange(PROPERTY_MAXIMUM, oldMax, max);
+	if (oldExtent != ext)
+		firePropertyChange(PROPERTY_EXTENT, oldExtent, ext);
+	if (oldMin != min)
+		firePropertyChange(PROPERTY_MINIMUM, oldMin, min);
+	setValue(getValue());
+}
+
+/**
+ * Sets this RangeModel's extent and fires a property change if the given value is 
+ * different from the current extent.
+ * 
+ * @param extent the new extent value
+ */
+public void setExtent(int extent) {
+	if (this.extent == extent)
+		return;
+	int oldValue = this.extent;
+	this.extent = extent;
+	firePropertyChange(PROPERTY_EXTENT, oldValue, extent);
+	setValue(getValue());
+}
+
+/**
+ * Sets this RangeModel's maximum value and fires a property change if the given value is 
+ * different from the current maximum value.
+ * 
+ * @param maximum the new maximum value
+ */
+public void setMaximum(int maximum) {
+	if (this.maximum == maximum)
+		return;
+	int oldValue = this.maximum;
+	this.maximum = maximum;
+	firePropertyChange(PROPERTY_MAXIMUM, oldValue, maximum);
+	setValue(getValue());
+}
+
+/**
+ * Sets this RangeModel's minimum value and fires a property change if the given value is 
+ * different from the current minimum value.
+ * 
+ * @param minimum the new minumum value
+ */
+public void setMinimum(int minimum) {
+	if (this.minimum == minimum)
+		return;
+	int oldValue = this.minimum;
+	this.minimum = minimum;
+	firePropertyChange(PROPERTY_MINIMUM, oldValue, minimum);
+	setValue(getValue());
+}
+
+/**
+ * Sets this RangeModel's current value.  If the given value is greater than the maximum, 
+ * the maximum value is used.  If the given value is less than the minimum, the minimum 
+ * value is used.  If the adjusted value is different from the current value, a property
+ * change is fired.
+ * 
+ * @param value the new value
+ */
+public void setValue(int value) {
+	value = Math.max(getMinimum(), Math.min(getMaximum() - getExtent(), value));
+	if (this.value == value)
+		return;
+	int oldValue = this.value;
+	this.value = value;
+	firePropertyChange(PROPERTY_VALUE, oldValue, value);
+}
+
+/**
+ * @see java.lang.Object#toString()
+ */
+public String toString() {
+	return super.toString() + " (" + minimum + ", " + maximum //$NON-NLS-2$ //$NON-NLS-1$
+			+ ", " + extent + ", " + value + ")"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DeferredUpdateManager.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DeferredUpdateManager.java
new file mode 100644
index 0000000..9774aff
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DeferredUpdateManager.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * An UpdateManager that asynchronously updates the affected figures.  
+ */
+public class DeferredUpdateManager
+	extends UpdateManager
+{
+
+/**
+ * Calls {@link DeferredUpdateManager#performUpdate()}.
+ */
+protected class UpdateRequest
+	implements Runnable
+{
+    
+	public UpdateRequest() {
+        super();
+    }
+
+    /**
+	 * Calls {@link DeferredUpdateManager#performUpdate()}.
+	 */
+	public void run() {
+		performUpdate();
+	}
+}
+private Rectangle damage;
+private Map dirtyRegions = new HashMap();
+
+private GraphicsSource graphicsSource;
+private List invalidFigures = new ArrayList();
+private IFigure root;
+private boolean updateQueued = false;
+
+private boolean updating;
+private RunnableChain afterUpdate;
+
+private static class RunnableChain {
+	RunnableChain next;
+	Runnable run;
+
+	RunnableChain(Runnable run, RunnableChain next) {
+		this.run = run;
+		this.next = next;
+	}
+	
+	void run() {
+		if (next != null)
+			next.run();
+		run.run();
+	}
+}
+
+/**
+ * Empty constructor.
+ */
+public DeferredUpdateManager() { }
+
+/**
+ * Constructs a new DererredUpdateManager with the given GraphicsSource.
+ * @param gs the graphics source
+ */
+public DeferredUpdateManager(GraphicsSource gs) {
+	setGraphicsSource(gs);
+}
+
+/**
+ * Adds a dirty region (defined by the rectangle <i>x, y, w, h</i>) to the update queue.
+ * If the figure isn't visible or either the width or height are 0, the method returns
+ * without queueing the dirty region.
+ * 
+ * @param figure the figure that contains the dirty region
+ * @param x the x coordinate of the dirty region
+ * @param y the y coordinate of the dirty region
+ * @param w the width of the dirty region
+ * @param h the height of the dirty region
+ */
+public synchronized void addDirtyRegion(IFigure figure, int x, int y, int w, int h) {
+	if (w == 0 || h == 0 || !figure.isShowing())
+		return;
+
+	Rectangle rect = (Rectangle)dirtyRegions.get(figure);
+	if (rect == null) {
+		rect = new Rectangle(x, y, w, h);
+		dirtyRegions.put(figure, rect);
+	} else
+		rect.union(x, y, w, h);
+	
+	queueWork();
+}
+
+/**
+ * Adds the given figure to the update queue.  Invalid figures will be validated before 
+ * the damaged regions are repainted.
+ * 
+ * @param f the invalid figure
+ */
+public synchronized void addInvalidFigure(IFigure f) {
+	if (invalidFigures.contains(f))
+		return;
+	queueWork();
+	invalidFigures.add(f);
+}
+
+/**
+ * Returns a Graphics object for the given region.
+ * @param region the region to be repainted
+ * @return the Graphics object
+ */
+protected Graphics getGraphics(Rectangle region) {
+	if (graphicsSource == null)
+		return null;
+	return graphicsSource.getGraphics(region);
+}
+
+void paint(GC gc) {
+	SWTGraphics graphics = new SWTGraphics(gc);
+	if (!updating) {
+		/**
+		 * If a paint occurs not as part of an update, we should notify that the region
+		 * is being painted. Otherwise, notification already occurs in repairDamage().
+		 */
+		HashMap map = new HashMap();
+		Rectangle rect = graphics.getClip(new Rectangle());
+		map.put(root, rect);
+		firePainting(rect, map);
+	}
+	root.paint(graphics);
+	graphics.dispose();
+}
+
+/**
+ * Performs the update.  Validates the invalid figures and then repaints the dirty
+ * regions.
+ * @see #validateFigures()
+ * @see #repairDamage()
+ */
+public synchronized void performUpdate() {
+	if (isDisposed() || updating)
+		return;
+	updating = true;
+	try {
+		performValidation();
+		updateQueued = false;
+		repairDamage();
+		if (afterUpdate != null) {
+			RunnableChain chain = afterUpdate;
+			afterUpdate = null;
+			chain.run(); //chain may queue additional Runnable.
+			if (afterUpdate != null)
+				queueWork();
+		}
+	} finally {
+		updating = false;
+	}
+}
+
+/**
+ * @see UpdateManager#performValidation()
+ */
+public void performValidation() {
+	if (invalidFigures.isEmpty())
+		return;
+	try {
+		IFigure fig;
+		fireValidating();
+		for (int i = 0; i < invalidFigures.size(); i++) {
+			fig = (IFigure) invalidFigures.get(i);
+			invalidFigures.set(i, null);
+			fig.validate();
+		}
+	} finally {
+		invalidFigures.clear();
+	}
+}
+
+/**
+ * Adds the given exposed region to the update queue and then performs the update.
+ * 
+ * @param exposed the exposed region
+ */
+public synchronized void performUpdate(Rectangle exposed) {
+	addDirtyRegion(root, exposed);
+	performUpdate();
+}
+
+/**
+ * Posts an {@link UpdateRequest} using {@link Display#asyncExec(Runnable)}.  If work has
+ * already been queued, a new request is not needed.
+ */
+protected void queueWork() {
+	if (!updateQueued) {
+		sendUpdateRequest();
+		updateQueued = true;
+	}
+}
+
+/**
+ * Fires the <code>UpdateRequest</code> to the current display asynchronously.
+ * @since 3.2
+ */
+protected void sendUpdateRequest() {
+    Display.getCurrent().asyncExec(new UpdateRequest());
+}
+
+/**
+ * Releases the graphics object, which causes the GraphicsSource to flush.
+ * @param graphics the graphics object
+ */
+protected void releaseGraphics(Graphics graphics) {
+	graphics.dispose();
+	graphicsSource.flushGraphics(damage);
+}
+
+/**
+ * Repaints the dirty regions on the update queue and calls 
+ * {@link UpdateManager#firePainting(Rectangle, Map)}, unless there are no dirty regions.
+ */
+protected void repairDamage() {
+	Iterator keys = dirtyRegions.keySet().iterator();
+	Rectangle contribution;
+	IFigure figure;
+	IFigure walker;
+
+	while (keys.hasNext()) {
+		figure = (IFigure)keys.next();
+		walker = figure.getParent();
+		contribution = (Rectangle)dirtyRegions.get(figure);
+		//A figure can't paint beyond its own bounds
+		contribution.intersect(figure.getBounds());
+		while (!contribution.isEmpty() && walker != null) {
+			walker.translateToParent(contribution);
+			contribution.intersect(walker.getBounds());
+			walker = walker.getParent();
+		}
+		if (damage == null)
+			damage = new Rectangle(contribution);
+		else
+			damage.union(contribution);
+	}
+
+	if (!dirtyRegions.isEmpty()) {
+		Map oldRegions = dirtyRegions;		
+		dirtyRegions = new HashMap();
+		firePainting(damage, oldRegions);
+	}
+	
+	if (damage != null && !damage.isEmpty()) {
+		//ystem.out.println(damage);
+		Graphics graphics = getGraphics(damage);
+		if (graphics != null) {
+			root.paint(graphics);
+			releaseGraphics(graphics);
+		}
+	}
+	damage = null;
+}
+
+/**
+ * Adds the given runnable and queues an update if an update is not under progress.
+ * @param runnable the runnable
+ */
+public synchronized void runWithUpdate(Runnable runnable) {
+	afterUpdate = new RunnableChain(runnable, afterUpdate);
+	if (!updating)
+		queueWork();
+}
+
+/**
+ * Sets the graphics source.
+ * @param gs the graphics source
+ */
+public void setGraphicsSource(GraphicsSource gs) {
+	graphicsSource = gs;
+}
+
+/**
+ * Sets the root figure.
+ * @param figure the root figure
+ */
+public void setRoot(IFigure figure) {
+	root = figure;
+}
+
+/**
+ * Validates all invalid figures on the update queue and calls 
+ * {@link UpdateManager#fireValidating()} unless there are no invalid figures.
+ */
+protected void validateFigures() {
+	performValidation();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DelegatingLayout.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DelegatingLayout.java
new file mode 100644
index 0000000..3778a0f
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/DelegatingLayout.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.draw2d.geometry.Dimension;
+
+/**
+ * Figures using a DelegatingLayout as their layout manager give 
+ * location responsibilities to their children. The children
+ * of a Figure using a DelegatingLayout should have a 
+ * {@link Locator Locator} as a constraint whose 
+ * {@link Locator#relocate(IFigure target) relocate} method is 
+ * responsible for placing the child.
+ */
+public class DelegatingLayout 
+	extends AbstractLayout 
+{
+
+private Map constraints = new HashMap();
+
+/**
+ * Calculates the preferred size of the given Figure.
+ * For the DelegatingLayout, this is the largest width and height
+ * values of the passed Figure's children.
+ * 
+ * @param parent the figure whose preferred size is being calculated
+ * @param wHint the width hint
+ * @param hHint the height hint
+ * @return the preferred size
+ * @since 2.0
+ */
+protected Dimension calculatePreferredSize(IFigure parent, int wHint, int hHint) {
+	List children = parent.getChildren();
+	Dimension d = new Dimension();
+	for (int i = 0; i < children.size(); i++) {
+		IFigure child = (IFigure)children.get(i);
+		d.union(child.getPreferredSize());
+	}
+	return d;
+}
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#getConstraint(org.eclipse.draw2d.IFigure)
+ */
+public Object getConstraint(IFigure child) {
+	return constraints.get(child);
+}
+
+/**
+ * Lays out the given figure's children based on their {@link Locator} constraint.
+ * @param parent the figure whose children should be layed out
+ */
+public void layout(IFigure parent) {
+	List children = parent.getChildren();
+	for (int i = 0; i < children.size(); i++) {
+		IFigure child = (IFigure)children.get(i);
+		Locator locator = (Locator)constraints.get(child);
+		if (locator != null) {
+			locator.relocate(child);
+		}
+	}
+}
+
+/**
+ * Removes the locator for the given figure.
+ * @param child the child being removed
+ */
+public void remove(IFigure child) {
+	constraints.remove(child);
+}
+
+/**
+ * Sets the constraint for the given figure.
+ * @param figure the figure whose contraint is being set
+ * @param constraint the new constraint
+ */
+public void setConstraint(IFigure figure, Object constraint) {
+	super.setConstraint(figure, constraint);
+	if (constraint != null)
+		constraints.put(figure, constraint);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Ellipse.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Ellipse.java
new file mode 100644
index 0000000..2462c4a
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Ellipse.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Alex Selkov - Fix for Bug# 22701
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * An figure that draws an ellipse filling its bounds.
+ */
+public class Ellipse
+	extends Shape
+{
+
+/**
+ * Constructs a new Ellipse with the default values of a Shape.
+ * @since 2.0
+ */
+public Ellipse() { }
+
+/**
+ * Returns <code>true</code> if the given point (x,y) is contained within this ellipse.
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @return <code>true</code>if the given point is contained
+ */
+public boolean containsPoint(int x, int y) {
+	if (!super.containsPoint(x, y))
+		return false;
+	Rectangle r = getBounds();
+	long ux = x - r.x - r.width / 2;
+	long uy = y - r.y - r.height / 2;
+	return ((ux * ux) << 10) / (r.width * r.width) 
+		 + ((uy * uy) << 10) / (r.height * r.height) <= 256;
+}
+
+/**
+ * Fills the ellipse.
+ * @see org.eclipse.draw2d.Shape#fillShape(org.eclipse.draw2d.Graphics)
+ */
+protected void fillShape(Graphics graphics) {
+	graphics.fillOval(getBounds());
+}
+
+/**
+ * Outlines the ellipse.
+ * @see org.eclipse.draw2d.Shape#outlineShape(org.eclipse.draw2d.Graphics)
+ */
+protected void outlineShape(Graphics graphics) {
+	Rectangle r = Rectangle.SINGLETON;
+	r.setBounds(getBounds());
+	r.width--;
+	r.height--;
+	r.shrink((lineWidth - 1) / 2, (lineWidth - 1) / 2);
+	graphics.drawOval(r);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EllipseAnchor.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EllipseAnchor.java
new file mode 100644
index 0000000..f838523
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EllipseAnchor.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * Similar to a {@link org.eclipse.draw2d.ChopboxAnchor}, except this anchor is located on
+ * the ellipse defined by the owners bounding box.
+ * @author Alex Selkov
+ * Created 31.08.2002 23:11:43
+ */
+public class EllipseAnchor extends AbstractConnectionAnchor {
+
+/**
+ * @see org.eclipse.draw2d.AbstractConnectionAnchor#AbstractConnectionAnchor()
+ */
+public EllipseAnchor() { }
+
+/**
+ * @see org.eclipse.draw2d.AbstractConnectionAnchor#AbstractConnectionAnchor(IFigure)
+ */
+public EllipseAnchor(IFigure owner) {
+	super(owner);
+}
+
+/**
+ * Returns a point on the ellipse (defined by the owner's bounding box) where the
+ * connection should be anchored.
+ * @see org.eclipse.draw2d.ConnectionAnchor#getLocation(Point)
+ */
+public Point getLocation(Point reference) {
+	Rectangle r = Rectangle.SINGLETON;
+	r.setBounds(getOwner().getBounds());
+	r.translate(-1, -1);
+	r.resize(1, 1);
+	getOwner().translateToAbsolute(r);
+	
+	Point ref = r.getCenter().negate().translate(reference);
+	
+	if (ref.x == 0)
+		return new Point(reference.x, (ref.y > 0) ? r.bottom() : r.y);
+	if (ref.y == 0)
+		return new Point((ref.x > 0) ? r.right() : r.x, reference.y);
+	
+	float dx = (ref.x > 0) ? 0.5f : -0.5f;
+	float dy = (ref.y > 0) ? 0.5f : -0.5f;
+	  
+	// ref.x, ref.y, r.width, r.height != 0 => safe to proceed
+	  
+	float k = (float)(ref.y * r.width) / (ref.x * r.height);
+	k = k * k;
+	  
+	return r.getCenter().translate((int)(r.width * dx / Math.sqrt(1 + k)),
+	                                (int)(r.height * dy / Math.sqrt(1 + 1 / k)));
+}
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EventDispatcher.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EventDispatcher.java
new file mode 100644
index 0000000..1994746
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EventDispatcher.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.accessibility.AccessibleControlEvent;
+import org.eclipse.swt.accessibility.AccessibleControlListener;
+import org.eclipse.swt.accessibility.AccessibleListener;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+
+/**
+ * Listens to various SWT events and dispatches these events to interested Draw2d objects. 
+ */
+public abstract class EventDispatcher {
+	
+	/**
+	 * Combines {@link AccessibleControlListener} and {@link AccessibleListener}.  
+	 * Implements {@link AccessibleControlListener#getChild(AccessibleControlEvent)} to do
+	 * nothing.
+	 */
+	public abstract static class AccessibilityDispatcher
+		implements AccessibleControlListener, AccessibleListener
+	{
+		/** @see AccessibleControlListener#getChild(AccessibleControlEvent) */
+		public void getChild(AccessibleControlEvent e) { }
+	}
+
+/**
+ * Dispatches a focus gained event.
+ * @param e the event
+ */
+public abstract void dispatchFocusGained(FocusEvent e);
+
+/**
+ * Dispatches a focus lost event.
+ * @param e the event
+ */
+public abstract void dispatchFocusLost(FocusEvent e);
+
+/**
+ * Dispatches a key pressed event.
+ * @param e the event
+ */
+public abstract void dispatchKeyPressed(KeyEvent e);
+
+/**
+ * Dispatches a key released event.
+ * @param e the event
+ */
+public abstract void dispatchKeyReleased(KeyEvent e);
+
+/**
+ * Dispatches a key traversed event.
+ * @param e the event
+ */
+public abstract void dispatchKeyTraversed(TraverseEvent e);
+
+/**
+ * Dispatches a mouse double clicked event.
+ * @param me the event
+ */
+public abstract void dispatchMouseDoubleClicked(MouseEvent me);
+
+/**
+ * Dispatches a mouse entered event.
+ * @param e the event
+ */
+public abstract void dispatchMouseEntered(MouseEvent e);
+
+/**
+ * Dispatches a mouse exited event.
+ * @param e the event
+ */
+public abstract void dispatchMouseExited(MouseEvent e);
+
+/**
+ * Dispatches a mouse hover event.
+ * @param me the event
+ */
+public abstract void dispatchMouseHover(MouseEvent me);
+
+/**
+ * Dispatches a moved event event.
+ * @param me the event
+ */
+public abstract void dispatchMouseMoved(MouseEvent me);
+
+/**
+ * Dispatches a mouse pressed event.
+ * @param me the event
+ */
+public abstract void dispatchMousePressed(MouseEvent me);
+
+/**
+ * Dispatches a mouse released event.
+ * @param me the event
+ */
+public abstract void dispatchMouseReleased(MouseEvent me);
+
+/**
+ * Dispatches a MouseWheel event. Does nothing by default.
+ * @param event the SWT event
+ * @since 3.1
+ */
+public void dispatchMouseWheelScrolled(Event event) { }
+
+/**
+ * Returns the AccessibilityDispatcher.
+ * @return the AccessibilityDispatcher
+ */
+protected abstract AccessibilityDispatcher getAccessibilityDispatcher();
+
+/**
+ * @return the IFigure that currently has focus
+ */
+/*package*/ abstract IFigure getFocusOwner();
+
+/**
+ * @return whether events are captured by a figure
+ */
+public abstract boolean isCaptured();
+
+/**
+ * Releases capture initiated by {@link #setCapture(IFigure)}.
+ */
+protected abstract void releaseCapture();
+
+/**
+ * Requests focus for the given figure.
+ * @param fig the figure requesting focus
+ */
+public abstract void requestFocus(IFigure fig);
+
+/**
+ * Requests focus to be removed from the given figure.
+ * @param fig the figure requesting focus be removed
+ */
+public abstract void requestRemoveFocus(IFigure fig);
+
+/**
+ * Sets capture to the given figure.  All subsequent events will be sent to the given 
+ * figure until {@link #releaseCapture()} is called.
+ * 
+ * @param figure the figure capturing the events
+ */
+protected abstract void setCapture(IFigure figure);
+
+/**
+ * Sets the contol associated with this event dispatcher.
+ * @param control the control
+ */
+public abstract void setControl(Control control);
+
+/**
+ * Sets the root figure for this dispatcher.
+ * @param figure the root figure
+ */
+public abstract void setRoot(IFigure figure);
+
+/**
+ * Updates the cursor.
+ */
+protected abstract void updateCursor();
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EventListenerList.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EventListenerList.java
new file mode 100644
index 0000000..b22a217
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/EventListenerList.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Iterator;
+
+/**
+ * This class is intended for internal use only.
+ * TODO: If this is for internal use only, we should move it to the internal package.
+ */
+public final class EventListenerList {
+
+private volatile Object array[];
+
+/**
+ * Adds a listener of type <i>c</i> to the list.
+ * @param c the class
+ * @param listener the listener
+ */
+public synchronized void addListener(Class c, Object listener) {
+	if (listener == null || c == null)
+		throw new IllegalArgumentException();
+
+	int oldSize = (array == null) ? 0 : array.length;
+	Object[] newArray = new Object[oldSize + 2];
+	if (oldSize != 0)
+		System.arraycopy(array, 0, newArray, 0, oldSize);
+	newArray[oldSize++] = c;
+	newArray[oldSize] = listener;
+	array = newArray;
+}
+
+/**
+ * Returns <code>true</code> if this list of listeners contains a listener of type 
+ * <i>c</i>.
+ * @param c the type
+ * @return whether this list contains a listener of type <i>c</i>
+ */
+public synchronized boolean containsListener(Class c) {
+	if (array == null)
+		return false;
+	for (int i = 0; i < array.length; i += 2)
+		if (array[i] == c)
+			return true;
+	return false;
+}
+
+static class TypeIterator implements Iterator {
+	private final Object[] items;
+	private final Class type;
+	private int index;
+	TypeIterator(Object items[], Class type) {
+		this.items = items;
+		this.type = type;
+	}
+	public Object next() {
+		Object result = items[index + 1];
+		index += 2;
+		return result;
+	}
+
+	public boolean hasNext() {
+		if (items == null)
+			return false;
+		while (index < items.length && items[index] != type)
+			index += 2;
+		return index < items.length;
+	}
+
+	public void remove() {
+		throw new UnsupportedOperationException("Iterator removal not supported"); //$NON-NLS-1$
+	}
+}
+
+/**
+ * Returns an Iterator of all the listeners of type <i>c</i>.
+ * @param listenerType the type
+ * @return an Iterator of all the listeners of type <i>c</i>
+ */
+public synchronized Iterator getListeners(final Class listenerType) {
+	return new TypeIterator(array, listenerType);
+}
+
+/**
+ * Removes the first <i>listener</i> of the specified type by identity.
+ * @param c the type
+ * @param listener the listener
+ */
+public synchronized void removeListener(Class c, Object listener) {
+	if (array == null || array.length == 0)
+		return;
+	if (listener == null || c == null)
+		throw new IllegalArgumentException();
+	
+	int index = 0;
+	while (index < array.length) {
+		if (array[index] == c && array[index + 1] == listener)
+			break;
+		index += 2;
+	}
+	if (index == array.length)
+		return; //listener was not found
+	
+	Object newArray[] = new Object[array.length - 2];
+	System.arraycopy(array, 0, newArray, 0, index);
+	System.arraycopy(array, index + 2, newArray, index, array.length - index - 2);
+	array = newArray;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ExclusionSearch.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ExclusionSearch.java
new file mode 100644
index 0000000..457d910
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ExclusionSearch.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Collection;
+
+/**
+ * A <code>TreeSearch</code> that excludes figures contained in a {@link
+ * java.util.Collection}.
+ * @author hudsonr
+ * @since 2.1
+ */
+public class ExclusionSearch implements TreeSearch {
+
+private final Collection c;
+
+/**
+ * Constructs an Exclusion search using the given collection.
+ * @param collection the exclusion set
+ */
+public ExclusionSearch(Collection collection) {
+	this.c = collection;
+}
+
+/**
+ * @see org.eclipse.draw2d.TreeSearch#accept(IFigure)
+ */
+public boolean accept(IFigure figure) {
+	//Prune is called before accept, so there is no reason to check the collection again.
+	return true;
+}
+
+/**
+ * Returns <code>true</code> if the figure is a member of the Collection.
+ * @see org.eclipse.draw2d.TreeSearch#prune(IFigure)
+ */
+public boolean prune(IFigure f) {
+	return c.contains(f);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FanRouter.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FanRouter.java
new file mode 100644
index 0000000..a702bee
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FanRouter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.Ray;
+
+/**
+ * Automatic router that spreads its {@link Connection Connections} in a fan-like fashion 
+ * upon collision.
+ */
+public class FanRouter
+	extends AutomaticRouter
+{
+
+private int separation = 10;
+
+/**
+ * Returns the separation in pixels between fanned connections.
+ * 
+ * @return the separation
+ * @since 2.0
+ */
+public int getSeparation() {
+	return separation;	
+}
+
+/**
+ * Modifies a given PointList that collides with some other PointList.  The given 
+ * <i>index</i> indicates that this it the i<sup>th</sup> PointList in a group of 
+ * colliding points.
+ * 
+ * @param points the colliding points
+ * @param index the index
+ */
+protected void handleCollision(PointList points, int index) {
+	Point start = points.getFirstPoint();
+	Point end = points.getLastPoint();
+	
+	if (start.equals(end))
+		return;
+	
+	Point midPoint = new Point((end.x + start.x) / 2, (end.y + start.y) / 2);
+	int position = end.getPosition(start);
+	Ray ray;
+	if (position == PositionConstants.SOUTH || position == PositionConstants.EAST)
+		ray = new Ray(start, end);
+	else
+		ray = new Ray(end, start);
+	double length = ray.length();
+
+	double xSeparation = separation * ray.x / length;
+	double ySeparation = separation * ray.y / length;
+	
+	Point bendPoint;
+		
+	if (index % 2 == 0) {
+		bendPoint = new Point(
+			midPoint.x + (index / 2) * (-1 * ySeparation),
+			midPoint.y + (index / 2) * xSeparation);
+	} else {
+		bendPoint = new Point(
+			midPoint.x + (index / 2) * ySeparation,
+			midPoint.y + (index / 2) * (-1 * xSeparation));
+	}
+	if (!bendPoint.equals(midPoint))
+		points.insertPoint(bendPoint, 1);
+}
+
+/**
+ * Sets the colliding {@link Connection Connection's} separation in pixels.
+ * 
+ * @param value the separation
+ * @since 2.0 
+ */
+public void setSeparation(int value) {
+	separation = value;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Figure.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Figure.java
new file mode 100644
index 0000000..33166b9
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Figure.java
@@ -0,0 +1,1870 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.draw2d.geometry.Translatable;
+
+/**
+ * The base implementation for graphical figures.
+ */
+public class Figure
+	implements IFigure
+{
+
+private static final Rectangle PRIVATE_RECT = new Rectangle();
+private static final Point PRIVATE_POINT = new Point();
+private static final int
+	FLAG_VALID = new Integer(1).intValue(),
+	FLAG_OPAQUE = new Integer(1 << 1).intValue(),
+	FLAG_VISIBLE = new Integer(1 << 2).intValue(),
+	FLAG_FOCUSABLE = new Integer(1 << 3).intValue(),
+	FLAG_ENABLED = new Integer(1 << 4).intValue(),
+	FLAG_FOCUS_TRAVERSABLE = new Integer(1 << 5).intValue();
+
+static final int
+	FLAG_REALIZED = 1 << 31;
+
+/**
+ * The largest flag defined in this class.  If subclasses define flags, they should
+ * declare them as larger than this value and redefine MAX_FLAG to be their largest flag
+ * value.
+ * <P>
+ * This constant is evaluated at runtime and will not be inlined by the compiler.
+ */
+protected static int MAX_FLAG = FLAG_FOCUS_TRAVERSABLE;
+
+/**
+ * The rectangular area that this Figure occupies.
+ */
+protected Rectangle bounds = new Rectangle(0, 0, 0, 0);
+
+private LayoutManager layoutManager;
+
+/**
+ * The flags for this Figure.
+ */
+protected int flags = FLAG_VISIBLE | FLAG_ENABLED;
+
+private IFigure parent;
+private Cursor cursor;
+
+private PropertyChangeSupport propertyListeners;
+private EventListenerList eventListeners = new EventListenerList();
+
+private List children = Collections.EMPTY_LIST;
+
+/**
+ * This Figure's preferred size.
+ */
+protected Dimension prefSize;
+
+/**
+ * This Figure's minimum size.
+ */
+protected Dimension minSize;
+
+/**
+ * This Figure's maximum size.
+ */
+protected Dimension maxSize;
+
+/** 
+ * @deprecated access using {@link #getLocalFont()}
+ */
+protected Font font;
+
+/**
+ * @deprecated access using {@link #getLocalBackgroundColor()}.
+ */
+protected Color bgColor;
+
+/**
+ * @deprecated access using {@link #getLocalForegroundColor()}.
+ */
+protected Color fgColor;
+
+/**
+ * @deprecated access using {@link #getBorder()}
+ */
+protected Border border;
+
+/**
+ * @deprecated access using {@link #getToolTip()}
+ */
+protected IFigure toolTip;
+
+private AncestorHelper ancestorHelper;
+
+/**
+ * Calls {@link #add(IFigure, Object, int)} with -1 as the index.
+ * @see IFigure#add(IFigure, Object)
+ */
+public final void add(IFigure figure, Object constraint) {
+	add(figure, constraint, -1);
+}
+
+/**
+ * @see IFigure#add(IFigure, Object, int)
+ */
+public void add(IFigure figure, Object constraint, int index) {
+	if (children == Collections.EMPTY_LIST)
+		children = new ArrayList(2);
+	if (index < -1 || index > children.size())
+		throw new IndexOutOfBoundsException("Index does not exist"); //$NON-NLS-1$
+
+	//Check for Cycle in hierarchy
+	for (IFigure f = this; f != null; f = f.getParent())
+		if (figure == f)
+			throw new IllegalArgumentException(
+						"Figure being added introduces cycle"); //$NON-NLS-1$
+
+	//Detach the child from previous parent
+	if (figure.getParent() != null)
+		figure.getParent().remove(figure);
+
+	if (index == -1)
+		children.add(figure);
+	else
+		children.add(index, figure);
+	figure.setParent(this);
+
+	if (layoutManager != null)
+		layoutManager.setConstraint(figure, constraint);
+
+	revalidate();
+
+	if (getFlag(FLAG_REALIZED))
+		figure.addNotify();
+	figure.repaint();
+}
+
+/**
+ * Calls {@link #add(IFigure, Object, int)} with <code>null</code> as the constraint and 
+ * -1 as the index.
+ * @see IFigure#add(IFigure)
+ */
+public final void add(IFigure figure) {
+	add(figure, null, -1);
+}
+
+/**
+ * Calls {@link #add(IFigure, Object, int)} with <code>null</code> as the constraint.
+ * @see IFigure#add(IFigure, int)
+ */
+public final void add(IFigure figure, int index) {
+	add(figure, null, index);
+}
+/**
+ * @see IFigure#addAncestorListener(AncestorListener)
+ */
+public void addAncestorListener(AncestorListener ancestorListener) {
+	if (ancestorHelper == null)
+		ancestorHelper = new AncestorHelper(this);
+	ancestorHelper.addAncestorListener(ancestorListener);
+}
+
+/**
+ * @see IFigure#addCoordinateListener(CoordinateListener)
+ */
+public void addCoordinateListener(CoordinateListener listener) {
+	eventListeners.addListener(CoordinateListener.class, listener);
+}
+
+/**
+ * @see IFigure#addFigureListener(FigureListener)
+ */
+public void addFigureListener(FigureListener listener) {
+	eventListeners.addListener(FigureListener.class, listener);
+}
+
+/**
+ * @see IFigure#addFocusListener(FocusListener)
+ */
+public void addFocusListener(FocusListener listener) {
+	eventListeners.addListener(FocusListener.class, listener);
+}
+
+/**
+ * @see IFigure#addKeyListener(KeyListener)
+ */
+public void addKeyListener(KeyListener listener) {
+	eventListeners.addListener(KeyListener.class, listener);
+}	
+
+/**
+ * Appends the given layout listener to the list of layout listeners.
+ * @since 3.1
+ * @param listener the listener being added
+ */
+public void addLayoutListener(LayoutListener listener) {
+	if (layoutManager instanceof LayoutNotifier) {
+		LayoutNotifier notifier = (LayoutNotifier)layoutManager;
+		notifier.listeners.add(listener);
+	} else
+		layoutManager = new LayoutNotifier(layoutManager, listener);
+}
+
+/**
+ * Adds a listener of type <i>clazz</i> to this Figure's list of event listeners.
+ * @param clazz The listener type
+ * @param listener The listener
+ */
+protected void addListener(Class clazz, Object listener) {
+	eventListeners.addListener(clazz, listener);
+}
+
+/**
+ * @see IFigure#addMouseListener(MouseListener)
+ */
+public void addMouseListener(MouseListener listener) {
+	eventListeners.addListener(MouseListener.class, listener);
+}
+
+/**
+ * @see IFigure#addMouseMotionListener(MouseMotionListener)
+ */
+public void addMouseMotionListener(MouseMotionListener listener) {
+	eventListeners.addListener(MouseMotionListener.class, listener);
+}
+
+/**
+ * Called after the receiver's parent has been set and it has been added to its parent.
+ * 
+ * @since 2.0
+ */
+public void addNotify() {
+	if (getFlag(FLAG_REALIZED))
+		throw new RuntimeException("addNotify() should not be called multiple times"); //$NON-NLS-1$
+	setFlag(FLAG_REALIZED, true);
+	for (int i = 0; i < children.size(); i++)
+		((IFigure)children.get(i)).addNotify();
+}
+
+/**
+ * @see IFigure#addPropertyChangeListener(String,
+ * PropertyChangeListener)
+ */
+public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
+	if (propertyListeners == null)
+		propertyListeners = new PropertyChangeSupport(this);
+	propertyListeners.addPropertyChangeListener(property, listener);
+}
+
+/**
+ * @see IFigure#addPropertyChangeListener(PropertyChangeListener)
+ */
+public void addPropertyChangeListener(PropertyChangeListener listener) {
+	if (propertyListeners == null)
+		propertyListeners = new PropertyChangeSupport(this);
+	propertyListeners.addPropertyChangeListener(listener);
+}
+
+/**
+ * This method is final.  Override {@link #containsPoint(int, int)} if needed.
+ * @see IFigure#containsPoint(Point)
+ * @since 2.0
+ */
+public final boolean containsPoint(Point p) {
+	return containsPoint(p.x, p.y);
+}
+
+/**
+ * @see IFigure#containsPoint(int, int)
+ */
+public boolean containsPoint(int x, int y) {
+	return getBounds().contains(x, y);
+}
+
+/**
+ * @see IFigure#erase()
+ */
+public void erase() {
+	if (getParent() == null || !isVisible())
+		return;
+	
+	Rectangle r = new Rectangle(getBounds());
+	getParent().translateToParent(r);
+	getParent().repaint(r.x, r.y, r.width, r.height);
+}
+
+/**
+ * Returns a descendant of this Figure such that the Figure returned contains the point
+ * (x, y), and is accepted by the given TreeSearch. Returns <code>null</code> if none 
+ * found.
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @param search the TreeSearch
+ * @return The descendant Figure at (x,y)
+ */
+protected IFigure findDescendantAtExcluding(int x, int y, TreeSearch search) {
+	PRIVATE_POINT.setLocation(x, y);
+	translateFromParent(PRIVATE_POINT);
+	if (!getClientArea(Rectangle.SINGLETON).contains(PRIVATE_POINT))
+		return null;
+
+	x = PRIVATE_POINT.x;
+	y = PRIVATE_POINT.y;
+	IFigure fig;
+	for (int i = children.size(); i > 0;) {
+		i--;
+		fig = (IFigure)children.get(i);
+		if (fig.isVisible()) {
+			fig = fig.findFigureAt(x, y, search);
+			if (fig != null)
+				return fig;
+		}
+	}
+	//No descendants were found
+	return null;
+}
+
+/**
+ * @see IFigure#findFigureAt(Point)
+ */
+public final IFigure findFigureAt(Point pt) {
+	return findFigureAtExcluding(pt.x, pt.y, Collections.EMPTY_LIST);
+}
+
+/**
+ * @see IFigure#findFigureAt(int, int)
+ */
+public final IFigure findFigureAt(int x, int y) {
+	return findFigureAt(x, y, IdentitySearch.INSTANCE);
+}
+
+/**
+ * @see IFigure#findFigureAt(int, int, TreeSearch)
+ */
+public IFigure findFigureAt(int x, int y, TreeSearch search) {
+	if (!containsPoint(x, y))
+		return null;
+	if (search.prune(this))
+		return null;
+	IFigure child = findDescendantAtExcluding(x, y, search);
+	if (child != null)
+		return child;
+	if (search.accept(this))
+		return this;
+	return null;
+}
+
+/**
+ * @see IFigure#findFigureAtExcluding(int, int, Collection)
+ */
+public final IFigure findFigureAtExcluding(int x, int y, Collection c) {
+	return findFigureAt(x, y, new ExclusionSearch(c));
+}
+
+/**
+ * Returns the deepest descendant for which {@link #isMouseEventTarget()} returns
+ * <code>true</code> or <code>null</code> if none found. The Parameters <i>x</i> and
+ * <i>y</i> are absolute locations. Any Graphics transformations applied by this Figure to
+ * its children during {@link #paintChildren(Graphics)} (thus causing the children to
+ * appear transformed to the user) should be applied inversely to the points <i>x</i> and
+ * <i>y</i> when called on the children.
+ * 
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return The deepest descendant for which isMouseEventTarget() returns true
+ */
+public IFigure findMouseEventTargetAt(int x, int y) {
+	if (!containsPoint(x, y))
+		return null;
+	IFigure f = findMouseEventTargetInDescendantsAt(x, y);
+	if (f != null)
+		return f;
+	if (isMouseEventTarget())
+		return this;
+	return null;
+}
+
+/**
+ * Searches this Figure's children for the deepest descendant for which 
+ * {@link #isMouseEventTarget()} returns <code>true</code> and returns that descendant or
+ * <code>null</code> if none found.
+ * @see #findMouseEventTargetAt(int, int)
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return The deepest descendant for which isMouseEventTarget() returns true
+ */
+protected IFigure findMouseEventTargetInDescendantsAt(int x, int y) {
+	PRIVATE_POINT.setLocation(x, y);
+	translateFromParent(PRIVATE_POINT);
+
+	if (!getClientArea(Rectangle.SINGLETON).contains(PRIVATE_POINT))
+		return null;
+
+	IFigure fig;
+	for (int i = children.size(); i > 0;) {
+		i--;
+		fig = (IFigure)children.get(i);
+		if (fig.isVisible() && fig.isEnabled()) {
+			if (fig.containsPoint(PRIVATE_POINT.x, PRIVATE_POINT.y)) {
+				fig = fig.findMouseEventTargetAt(PRIVATE_POINT.x, PRIVATE_POINT.y);
+				return fig;
+			}
+		}
+	}
+	return null;
+}
+
+/**
+ * Notifies to all {@link CoordinateListener}s that this figure's local coordinate system
+ * has changed in a way which affects the absolute bounds of figures contained within. 
+ * 
+ * @since 3.1
+ */
+protected void fireCoordinateSystemChanged() {
+	if (!eventListeners.containsListener(CoordinateListener.class))
+		return;
+	Iterator figureListeners = eventListeners.getListeners(CoordinateListener.class);
+	while (figureListeners.hasNext())
+		((CoordinateListener)figureListeners.next()).
+			coordinateSystemChanged(this);
+}
+
+/**
+ * Notifies to all {@link FigureListener}s that this figure has moved. Moved means
+ * that the bounds have changed in some way, location and/or size. 
+ * @since 3.1
+ */
+protected void fireFigureMoved() {
+	if (!eventListeners.containsListener(FigureListener.class))
+		return;
+	Iterator figureListeners = eventListeners.getListeners(FigureListener.class);
+	while (figureListeners.hasNext())
+		((FigureListener)figureListeners.next()).
+			figureMoved(this);
+}
+
+/**
+ * Fires both figuremoved and coordinate system changed. This method exists for
+ * compatibility. Some listeners which used to listen for figureMoved now listen for
+ * coordinates changed.  So to be sure that those new listeners are notified, any client
+ * code which used called this method will also result in notification of coordinate
+ * changes.
+ * @since 2.0
+ * @deprecated call fireFigureMoved() or fireCoordinateSystemChanged() as appropriate
+ */
+protected void fireMoved() {
+	fireFigureMoved();
+	fireCoordinateSystemChanged();
+}
+
+/**
+ * Notifies any {@link PropertyChangeListener PropertyChangeListeners} listening to this
+ * Figure that the boolean property with id <i>property</i> has changed.
+ * @param property The id of the property that changed
+ * @param old The old value of the changed property
+ * @param current The current value of the changed property
+ * @since 2.0
+ */
+protected void firePropertyChange(String property, boolean old, boolean current) {
+	if (propertyListeners == null) 
+		return;
+	propertyListeners.firePropertyChange(property, old, current);
+}
+
+/**
+ * Notifies any {@link PropertyChangeListener PropertyChangeListeners} listening to this
+ * figure that the Object property with id <i>property</i> has changed.
+ * @param property The id of the property that changed
+ * @param old The old value of the changed property
+ * @param current The current value of the changed property
+ * @since 2.0
+ */
+protected void firePropertyChange(String property, Object old, Object current) {
+	if (propertyListeners == null) 
+		return;
+	propertyListeners.firePropertyChange(property, old, current);
+}
+
+/**
+ * Notifies any {@link PropertyChangeListener PropertyChangeListeners} listening to this
+ * figure that the integer property with id <code>property</code> has changed.
+ * @param property The id of the property that changed
+ * @param old The old value of the changed property
+ * @param current The current value of the changed property
+ * @since 2.0
+ */
+protected void firePropertyChange(String property, int old, int current) {
+	if (propertyListeners == null) 
+		return;
+	propertyListeners.firePropertyChange(property, old, current);
+}
+
+/**
+ * Returns this Figure's background color.  If this Figure's background color is
+ * <code>null</code> and its parent is not <code>null</code>, the background color is
+ * inherited from the parent.
+ * @see IFigure#getBackgroundColor()
+ */
+public Color getBackgroundColor() {
+	if (bgColor == null && getParent() != null)
+		return getParent().getBackgroundColor();
+	return bgColor;
+}
+
+/**
+ * @see IFigure#getBorder()
+ */
+public Border getBorder() {
+	return border;
+}
+
+/**
+ * Returns the smallest rectangle completely enclosing the figure. Implementors may return
+ * the Rectangle by reference. For this reason, callers of this method must not modify the
+ * returned Rectangle.
+ * @return The bounds of this Figure
+ */
+public Rectangle getBounds() {
+	return bounds;
+}
+
+/**
+ * @see IFigure#getChildren()
+ */
+public List getChildren() {
+	return children;
+}
+
+/**
+ * @see IFigure#getClientArea(Rectangle)
+ */
+public Rectangle getClientArea(Rectangle rect) {
+	rect.setBounds(getBounds());
+	rect.crop(getInsets());
+	if (useLocalCoordinates())
+		rect.setLocation(0, 0);
+	return rect;
+}
+
+/**
+ * @see IFigure#getClientArea()
+ */
+public final Rectangle getClientArea() {
+	return getClientArea(new Rectangle());
+}
+
+/**
+ * @see IFigure#getCursor()
+ */
+public Cursor getCursor() {
+	if (cursor == null && getParent() != null)
+		return getParent().getCursor();
+	return cursor;
+}
+
+/**
+ * Returns the value of the given flag.
+ * @param flag The flag to get
+ * @return The value of the given flag
+ */
+protected boolean getFlag(int flag) {
+	return (flags & flag) != 0;
+}
+
+/**
+ * @see IFigure#getFont()
+ */
+public Font getFont() {
+	if (font != null)
+		return font;
+	if (getParent() != null)
+		return getParent().getFont();
+	return null;
+}
+
+/**
+ * @see IFigure#getForegroundColor()
+ */
+public Color getForegroundColor() {
+	if (fgColor == null && getParent() != null)
+		return getParent().getForegroundColor();
+	return fgColor;
+}
+
+/**
+ * Returns the border's Insets if the border is set. Otherwise returns NO_INSETS, an
+ * instance of Insets with all 0s. Returns Insets by reference.  DO NOT Modify returned
+ * value. Cannot return null.
+ * @return This Figure's Insets
+ */
+public Insets getInsets() {
+	if (getBorder() != null)
+		return getBorder().getInsets(this);
+	return NO_INSETS;
+}
+
+/**
+ * @see IFigure#getLayoutManager()
+ */
+public LayoutManager getLayoutManager() {
+	if (layoutManager instanceof LayoutNotifier)
+		return ((LayoutNotifier)layoutManager).realLayout;
+	return layoutManager;
+}
+
+/**
+ * Returns an Iterator over the listeners of type <i>clazz</i> that are listening to
+ * this Figure. If there are no listeners of type <i>clazz</i>, an empty iterator is
+ * returned.
+ * @param clazz The type of listeners to get
+ * @return An Iterator over the requested listeners
+ * @since 2.0
+ */
+protected Iterator getListeners(Class clazz) {
+	if (eventListeners == null)
+		return Collections.EMPTY_LIST.iterator();
+	return eventListeners.getListeners(clazz);
+}
+
+/**
+ * Returns <code>null</code> or the local background Color of this Figure. Does not
+ * inherit this Color from the parent.
+ * @return bgColor <code>null</code> or the local background Color
+ */
+public Color getLocalBackgroundColor() {
+	return bgColor;
+}	
+
+/**
+ * Returns <code>null</code> or the local font setting for this figure.  Does not return
+ * values inherited from the parent figure.
+ * @return <code>null</code> or the local font
+ * @since 3.1
+ */
+protected Font getLocalFont() {
+	return font;
+}
+
+/**
+ * Returns <code>null</code> or the local foreground Color of this Figure. Does not
+ * inherit this Color from the parent.
+ * @return fgColor <code>null</code> or the local foreground Color
+ */
+public Color getLocalForegroundColor() {
+	return fgColor;
+}	
+
+/**
+ * Returns the top-left corner of this Figure's bounds.
+ * @return The top-left corner of this Figure's bounds
+ * @since 2.0
+ */
+public final Point getLocation() {
+	return getBounds().getLocation();
+}
+
+/**
+ * @see IFigure#getMaximumSize()
+ */
+public Dimension getMaximumSize() {
+	if (maxSize != null)
+		return maxSize;
+	return MAX_DIMENSION;
+}
+
+/**
+ * @see IFigure#getMinimumSize()
+ */
+public final Dimension getMinimumSize() {
+	return getMinimumSize(-1, -1);
+}
+
+/**
+ * @see IFigure#getMinimumSize(int, int)
+ */
+public Dimension getMinimumSize(int wHint, int hHint) {
+	if (minSize != null)
+		return minSize;
+	if (getLayoutManager() != null) {
+		Dimension d = getLayoutManager().getMinimumSize(this, wHint, hHint);
+		if (d != null)
+			return d;
+	}
+	return getPreferredSize(wHint, hHint);
+}
+
+/**
+ * @see IFigure#getParent()
+ */
+public IFigure getParent() {
+	return parent;
+}
+
+/**
+ * @see IFigure#getPreferredSize()
+ */
+public final Dimension getPreferredSize() {
+	return getPreferredSize(-1, -1);
+}
+
+/**
+ * @see IFigure#getPreferredSize(int, int)
+ */
+public Dimension getPreferredSize(int wHint, int hHint) {
+	if (prefSize != null)
+		return prefSize;
+	if (getLayoutManager() != null) {
+		Dimension d = getLayoutManager().getPreferredSize(this, wHint, hHint);
+		if (d != null)
+			return d;
+	}
+	return getSize();
+}
+
+/**
+ * @see IFigure#getSize()
+ */
+public final Dimension getSize() {
+	return getBounds().getSize();
+}
+
+/**
+ * @see IFigure#getToolTip()
+ */
+public IFigure getToolTip() {
+	return toolTip;
+}
+
+/**
+ * @see IFigure#getUpdateManager()
+ */
+public UpdateManager getUpdateManager() {
+	if (getParent() != null) 
+		return getParent().getUpdateManager();
+	// Only happens when the figure has not been realized
+	return NO_MANAGER;
+}
+
+/**
+ * @see IFigure#handleFocusGained(FocusEvent)
+ */
+public void handleFocusGained(FocusEvent event) {
+	Iterator iter = eventListeners.getListeners(FocusListener.class);
+	while (iter.hasNext())
+		((FocusListener)iter.next()).
+			focusGained(event);
+}
+
+/**
+ * @see IFigure#handleFocusLost(FocusEvent)
+ */
+public void handleFocusLost(FocusEvent event) {
+	Iterator iter = eventListeners.getListeners(FocusListener.class);
+	while (iter.hasNext())
+		((FocusListener)iter.next()).
+			focusLost(event);
+}
+
+/**
+ * @see IFigure#handleKeyPressed(KeyEvent)
+ */
+public void handleKeyPressed(KeyEvent event) {
+	Iterator iter = eventListeners.getListeners(KeyListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((KeyListener)iter.next()).
+			keyPressed(event);
+}
+
+/**
+ * @see IFigure#handleKeyReleased(KeyEvent)
+ */
+public void handleKeyReleased(KeyEvent event) {
+	Iterator iter = eventListeners.getListeners(KeyListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((KeyListener)iter.next()).
+			keyReleased(event);
+}
+
+/**
+ * @see IFigure#handleMouseDoubleClicked(MouseEvent)
+ */
+public void handleMouseDoubleClicked(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseListener)iter.next()).
+			mouseDoubleClicked(event);
+}
+
+/**
+ * @see IFigure#handleMouseDragged(MouseEvent)
+ */
+public void handleMouseDragged(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseMotionListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseMotionListener)iter.next()).
+			mouseDragged(event);
+}
+
+/**
+ * @see IFigure#handleMouseEntered(MouseEvent)
+ */
+public void handleMouseEntered(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseMotionListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseMotionListener)iter.next()).
+			mouseEntered(event);
+}
+
+/**
+ * @see IFigure#handleMouseExited(MouseEvent)
+ */
+public void handleMouseExited(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseMotionListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseMotionListener)iter.next()).
+			mouseExited(event);
+}
+
+/**
+ * @see IFigure#handleMouseHover(MouseEvent)
+ */
+public void handleMouseHover(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseMotionListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseMotionListener)iter.next()).
+			mouseHover(event);
+}
+
+/**
+ * @see IFigure#handleMouseMoved(MouseEvent)
+ */
+public void handleMouseMoved(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseMotionListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseMotionListener)iter.next()).
+			mouseMoved(event);
+}
+
+/**
+ * @see IFigure#handleMousePressed(MouseEvent)
+ */
+public void handleMousePressed(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseListener)iter.next()).
+			mousePressed(event);
+}
+
+/**
+ * @see IFigure#handleMouseReleased(MouseEvent)
+ */
+public void handleMouseReleased(MouseEvent event) {
+	Iterator iter = eventListeners.getListeners(MouseListener.class);
+	while (!event.isConsumed() && iter.hasNext()) 
+		((MouseListener)iter.next()).
+			mouseReleased(event);
+}
+
+/**
+ * @see IFigure#hasFocus()
+ */
+public boolean hasFocus() {
+	EventDispatcher dispatcher = internalGetEventDispatcher();
+	if (dispatcher == null)
+		return false;
+	return dispatcher.getFocusOwner() == this;
+}
+
+/**
+ * @see IFigure#internalGetEventDispatcher()
+ */
+public EventDispatcher internalGetEventDispatcher() {
+	if (getParent() != null)
+		return getParent().internalGetEventDispatcher();
+	return null;
+}
+
+/**
+ * @see IFigure#intersects(Rectangle)
+ */
+public boolean intersects(Rectangle rect) {
+	return getBounds().intersects(rect);
+}
+
+/**
+ * @see IFigure#invalidate()
+ */
+public void invalidate() {
+	if (layoutManager != null)
+		layoutManager.invalidate();
+	setValid(false);
+}
+
+/**
+ * @see IFigure#invalidateTree()
+ */
+public void invalidateTree() {
+	invalidate();
+	for (Iterator iter = children.iterator(); iter.hasNext();) {
+		IFigure child = (IFigure) iter.next();
+		child.invalidateTree();
+	}
+}
+
+/**
+ * @see IFigure#isCoordinateSystem()
+ */
+public boolean isCoordinateSystem() {
+	return useLocalCoordinates();
+}
+
+/**
+ * @see IFigure#isEnabled()
+ */
+public boolean isEnabled() {
+	return (flags & FLAG_ENABLED) != 0;
+}
+
+/**
+ * @see IFigure#isFocusTraversable()
+ */
+public boolean isFocusTraversable() {
+	return (flags & FLAG_FOCUS_TRAVERSABLE) != 0;
+}
+
+/**
+ * Returns <code>true</code> if this Figure can receive {@link MouseEvent MouseEvents}.
+ * @return <code>true</code> if this Figure can receive {@link MouseEvent MouseEvents}
+ * @since 2.0
+ */
+protected boolean isMouseEventTarget() {
+	return (eventListeners.containsListener(MouseListener.class)
+		|| eventListeners.containsListener(MouseMotionListener.class));
+}
+
+/**
+ * @see org.eclipse.draw2d.IFigure#isMirrored()
+ */
+public boolean isMirrored() {
+	if (getParent() != null)
+		return getParent().isMirrored();
+	return false;
+}
+
+/**
+ * @see IFigure#isOpaque()
+ */
+public boolean isOpaque() {
+	return (flags & FLAG_OPAQUE) != 0;
+}
+
+/**
+ * @see IFigure#isRequestFocusEnabled()
+ */
+public boolean isRequestFocusEnabled() {
+	return (flags & FLAG_FOCUSABLE) != 0;
+}
+
+/**
+ * @see IFigure#isShowing()
+ */
+public boolean isShowing() {
+	return isVisible()
+	  && (getParent() == null
+		|| getParent().isShowing());
+}
+
+/**
+ * Returns <code>true</code> if this Figure is valid.
+ * @return <code>true</code> if this Figure is valid
+ * @since 2.0
+ */
+protected boolean isValid() {
+	return (flags & FLAG_VALID) != 0;
+}
+
+/**
+ * Returns <code>true</code> if revalidating this Figure does not require revalidating its
+ * parent.
+ * @return <code>true</code> if revalidating this Figure doesn't require revalidating its
+ * parent.
+ * @since 2.0
+ */
+protected boolean isValidationRoot() {
+	return false;
+}
+
+/**
+ * @see IFigure#isVisible()
+ */
+public boolean isVisible() {
+	return getFlag(FLAG_VISIBLE);
+}
+
+/**
+ * Lays out this Figure using its {@link LayoutManager}.
+ * 
+ * @since 2.0
+ */
+protected void layout() {
+	if (layoutManager != null)
+		layoutManager.layout(this);
+}
+
+/**
+ * Paints this Figure and its children.
+ * @param graphics The Graphics object used for painting
+ * @see #paintFigure(Graphics)
+ * @see #paintClientArea(Graphics)
+ * @see #paintBorder(Graphics)
+ */
+public void paint(Graphics graphics) {
+	if (getLocalBackgroundColor() != null)
+		graphics.setBackgroundColor(getLocalBackgroundColor());
+	if (getLocalForegroundColor() != null)
+		graphics.setForegroundColor(getLocalForegroundColor());
+	if (font != null)
+		graphics.setFont(font);
+
+	graphics.pushState();
+	try {
+		paintFigure(graphics);
+		graphics.restoreState();
+		paintClientArea(graphics);
+		paintBorder(graphics);
+	} finally {
+		graphics.popState();
+	}
+}
+
+/**
+ * Paints the border associated with this Figure, if one exists.
+ * @param graphics The Graphics used to paint
+ * @see Border#paint(IFigure, Graphics, Insets)
+ * @since 2.0
+ */
+protected void paintBorder(Graphics graphics) {
+	if (getBorder() != null)
+		getBorder().paint(this, graphics, NO_INSETS);
+}
+
+/**
+ * Paints this Figure's children. The caller must save the state of the graphics prior to
+ * calling this method, such that <code>graphics.restoreState()</code> may be called
+ * safely, and doing so will return the graphics to its original state when the method was
+ * entered.
+ * <P>
+ * This method must leave the Graphics in its original state upon return.
+ * @param graphics the graphics used to paint
+ * @since 2.0
+ */
+protected void paintChildren(Graphics graphics) {
+	IFigure child;
+
+	Rectangle clip = Rectangle.SINGLETON;
+	for (int i = 0; i < children.size(); i++) {
+		child = (IFigure)children.get(i);
+		if (child.isVisible() && child.intersects(graphics.getClip(clip))) {
+			graphics.clipRect(child.getBounds());
+			child.paint(graphics);
+			graphics.restoreState();
+		}
+	}
+}
+
+/**
+ * Paints this Figure's client area. The client area is typically defined as the anything
+ * inside the Figure's {@link Border} or {@link Insets}, and by default includes the
+ * children of this Figure. On return, this method must leave the given Graphics in its
+ * initial state.
+ * @param graphics The Graphics used to paint
+ * @since 2.0
+ */
+protected void paintClientArea(Graphics graphics) {
+	if (children.isEmpty())
+		return;
+
+	boolean optimizeClip = getBorder() == null || getBorder().isOpaque();
+
+	if (useLocalCoordinates()) {
+		graphics.translate(
+			getBounds().x + getInsets().left,
+			getBounds().y + getInsets().top);
+		if (!optimizeClip)
+			graphics.clipRect(getClientArea(PRIVATE_RECT));
+		graphics.pushState();
+		paintChildren(graphics);
+		graphics.popState();
+		graphics.restoreState();
+	} else {
+		if (optimizeClip)
+			paintChildren(graphics);
+		else {
+			graphics.clipRect(getClientArea(PRIVATE_RECT));
+			graphics.pushState();
+			paintChildren(graphics);
+			graphics.popState();
+			graphics.restoreState();
+		}
+	}
+}
+
+/**
+ * Paints this Figure's primary representation, or background. Changes made to the
+ * graphics to the graphics current state will not affect the subsequent calls to {@link
+ * #paintClientArea(Graphics)} and {@link #paintBorder(Graphics)}. Furthermore, it is safe
+ * to call <code>graphics.restoreState()</code> within this method, and doing so will
+ * restore the graphics to its original state upon entry.
+ * @param graphics The Graphics used to paint
+ * @since 2.0
+ */
+protected void paintFigure(Graphics graphics) {
+	if (isOpaque())
+		graphics.fillRectangle(getBounds());
+}
+
+/**
+ * Translates this Figure's bounds, without firing a move.
+ * @param dx The amount to translate horizontally
+ * @param dy The amount to translate vertically
+ * @see #translate(int, int)
+ * @since 2.0
+ */
+protected void primTranslate(int dx, int dy) {
+	bounds.x += dx;
+	bounds.y += dy;
+	if (useLocalCoordinates()) {
+		fireCoordinateSystemChanged();
+		return;
+	}
+	for (int i = 0; i < children.size(); i++)
+		((IFigure)children.get(i)).translate(dx, dy);
+}
+
+/**
+ * Removes the given child Figure from this Figure's hierarchy and revalidates this
+ * Figure. The child Figure's {@link #removeNotify()} method is also called.
+ * @param figure The Figure to remove
+ */
+public void remove(IFigure figure) {
+	if ((figure.getParent() != this))
+		throw new IllegalArgumentException(
+				"Figure is not a child"); //$NON-NLS-1$
+	if (getFlag(FLAG_REALIZED))
+		figure.removeNotify();
+	if (layoutManager != null)
+		layoutManager.remove(figure);
+	// The updates in the UpdateManager *have* to be
+	// done asynchronously, else will result in 
+	// incorrect dirty region corrections.
+	figure.erase();
+	figure.setParent(null);
+	children.remove(figure);
+	revalidate();
+}
+
+/**
+ * Removes all children from this Figure.
+ * 
+ * @see #remove(IFigure)
+ * @since 2.0
+ */
+public void removeAll() {
+	List list = new ArrayList(getChildren());
+	for (int i = 0; i < list.size(); i++) {
+		remove((IFigure)list.get(i));
+	}
+}
+
+/**
+ * @see IFigure#removeAncestorListener(AncestorListener)
+ */
+public void removeAncestorListener(AncestorListener listener) {
+	if (ancestorHelper != null) {
+		ancestorHelper.removeAncestorListener(listener);
+		if (ancestorHelper.isEmpty()) {
+			ancestorHelper.dispose();
+			ancestorHelper = null;
+		}
+	}
+}
+
+/**
+ * @see IFigure#removeCoordinateListener(CoordinateListener)
+ */
+public void removeCoordinateListener(CoordinateListener listener) {
+	eventListeners.removeListener(CoordinateListener.class, listener);
+}
+
+/**
+ * @see IFigure#removeFigureListener(FigureListener)
+ */
+public void removeFigureListener(FigureListener listener) {
+	eventListeners.removeListener(FigureListener.class, listener);
+}
+
+/**
+ * @see IFigure#removeFocusListener(FocusListener)
+ */
+public void removeFocusListener(FocusListener listener) {
+	eventListeners.removeListener(FocusListener.class, listener);
+}
+
+/**
+ * @see IFigure#removeKeyListener(KeyListener)
+ */
+public void removeKeyListener(KeyListener listener) {
+	eventListeners.removeListener(KeyListener.class, listener);
+}
+
+/**
+ * Removes the first occurence of the given listener.
+ * @since 3.1
+ * @param listener the listener being removed
+ */
+public void removeLayoutListener(LayoutListener listener) {
+	if (layoutManager instanceof LayoutNotifier) {
+		LayoutNotifier notifier = (LayoutNotifier)layoutManager;
+		notifier.listeners.remove(listener);
+		if (notifier.listeners.isEmpty())
+			layoutManager = notifier.realLayout;
+	}
+}
+
+/**
+ * Removes <i>listener</i> of type <i>clazz</i> from this Figure's list of listeners.
+ * @param clazz The type of listener
+ * @param listener The listener to remove
+ * @since 2.0
+ */
+protected void removeListener(Class clazz, Object listener) {
+	if (eventListeners == null)
+		return;
+	eventListeners.removeListener(clazz, listener);
+}
+
+/**
+ * @see IFigure#removeMouseListener(MouseListener)
+ */
+public void removeMouseListener(MouseListener listener) {
+	eventListeners.removeListener(MouseListener.class, listener);
+}
+
+/**
+ * @see IFigure#removeMouseMotionListener(MouseMotionListener)
+ */
+public void removeMouseMotionListener(MouseMotionListener listener) {
+	eventListeners.removeListener(MouseMotionListener.class, listener);
+}
+
+/**
+ * Called prior to this figure's removal from its parent
+ */
+public void removeNotify() {
+	for (int i = 0; i < children.size(); i++)
+		((IFigure)children.get(i)).removeNotify();
+	if (internalGetEventDispatcher() != null)
+		internalGetEventDispatcher().requestRemoveFocus(this);
+	setFlag(FLAG_REALIZED, false);
+}
+
+/**
+ * @see IFigure#removePropertyChangeListener(PropertyChangeListener)
+ */
+public void removePropertyChangeListener(PropertyChangeListener listener) {
+	if (propertyListeners == null) return;
+	propertyListeners.removePropertyChangeListener(listener);
+}
+
+/**
+ * @see IFigure#removePropertyChangeListener(String, PropertyChangeListener)
+ */
+public void removePropertyChangeListener(
+	String property,
+	PropertyChangeListener listener) {
+	if (propertyListeners == null) return;
+	propertyListeners.removePropertyChangeListener(property, listener);
+}
+
+/**
+ * @see IFigure#repaint(Rectangle)
+ */
+public final void repaint(Rectangle rect) {
+	repaint(rect.x, rect.y, rect.width, rect.height);
+}
+
+/**
+ * @see IFigure#repaint(int, int, int, int)
+ */
+public void repaint(int x, int y, int w, int h) {
+	if (isVisible())
+		getUpdateManager().addDirtyRegion(this, x, y, w, h);
+}
+
+/**
+ * @see IFigure#repaint()
+ */
+public void repaint() {
+	repaint(getBounds());
+}
+
+/**
+ * @see IFigure#requestFocus()
+ */
+public final void requestFocus() {
+	if (!isRequestFocusEnabled() || hasFocus())
+		return;
+	EventDispatcher dispatcher = internalGetEventDispatcher();
+	if (dispatcher == null)
+		return;
+	dispatcher.requestFocus(this);
+}
+
+/**
+ * @see IFigure#revalidate()
+ */
+public void revalidate() {
+	invalidate();
+	if (getParent() == null || isValidationRoot())
+		getUpdateManager().addInvalidFigure(this);
+	else
+		getParent().revalidate();
+}
+
+/**
+ * @see IFigure#setBackgroundColor(Color)
+ */
+public void setBackgroundColor(Color bg) {
+	bgColor = bg;
+	repaint();
+}
+
+/**
+ * @see IFigure#setBorder(Border)
+ */
+public void setBorder(Border border) {
+	this.border = border;
+	revalidate();
+}
+
+/**
+ * Sets the bounds of this Figure to the Rectangle <i>rect</i>. Note that <i>rect</i> is
+ * compared to the Figure's current bounds to determine what needs to be repainted and/or
+ * exposed and if validation is required. Since {@link #getBounds()} may return the
+ * current bounds by reference, it is not safe to modify that Rectangle and then call
+ * setBounds() after making modifications. The figure would assume that the bounds are
+ * unchanged, and no layout or paint would occur. For proper behavior, always use a copy.
+ * @param rect The new bounds
+ * @since 2.0
+ */
+public void setBounds(Rectangle rect) {
+	int x = bounds.x,
+	    y = bounds.y;
+
+	boolean resize = (rect.width != bounds.width) || (rect.height != bounds.height),
+		  translate = (rect.x != x) || (rect.y != y);
+
+	if ((resize || translate) && isVisible())
+		erase();
+	if (translate) {
+		int dx = rect.x - x;
+		int dy = rect.y - y;
+		primTranslate(dx, dy);
+	}
+	
+	bounds.width = rect.width;
+	bounds.height = rect.height;
+	
+	if (translate || resize) {
+		if (resize)
+			invalidate();
+		fireFigureMoved();
+		repaint();
+	}
+}
+
+/**
+ * Sets the direction of any {@link Orientable} children.  Allowable values for
+ * <code>dir</code> are found in {@link PositionConstants}.
+ * @param direction The direction
+ * @see Orientable#setDirection(int)
+ * @since 2.0
+ */
+protected void setChildrenDirection(int direction) {
+	FigureIterator iterator = new FigureIterator(this);
+	IFigure child;
+	while (iterator.hasNext()) {
+		child = iterator.nextFigure();
+		if (child instanceof Orientable)
+			((Orientable)child).setDirection(direction);
+	}
+}
+
+/**
+ * Sets all childrens' enabled property to <i>value</i>.
+ * @param value The enable value
+ * @see #setEnabled(boolean)
+ * @since 2.0
+ */
+protected void setChildrenEnabled(boolean value) {
+	FigureIterator iterator = new FigureIterator(this);
+	while (iterator.hasNext())
+		iterator.nextFigure().setEnabled(value);
+}
+
+/**
+ * Sets the orientation of any {@link Orientable} children. Allowable values for
+ * <i>orientation</i> are found in {@link PositionConstants}.
+ * @param orientation The Orientation
+ * @see Orientable#setOrientation(int)
+ * @since 2.0
+ */
+protected void setChildrenOrientation(int orientation) {
+	FigureIterator iterator = new FigureIterator(this);
+	IFigure child;
+	while (iterator.hasNext()) {
+		child = iterator.nextFigure();
+		if (child instanceof Orientable)
+			((Orientable)child).setOrientation(orientation);
+	}
+}
+
+/**
+ * @see IFigure#setConstraint(IFigure, Object)
+ */
+public void setConstraint(IFigure child, Object constraint) {
+	if (child.getParent() != this)
+		throw new IllegalArgumentException(
+			"Figure must be a child"); //$NON-NLS-1$
+	
+	if (layoutManager != null)
+		layoutManager.setConstraint(child, constraint);
+	revalidate();
+}
+
+/**
+ * @see IFigure#setCursor(Cursor)
+ */
+public void setCursor(Cursor cursor) {
+	if (this.cursor == cursor)
+		return;
+	this.cursor = cursor;
+	EventDispatcher dispatcher = internalGetEventDispatcher();
+	if (dispatcher != null)
+		dispatcher.updateCursor();
+}
+
+/**
+ * @see IFigure#setEnabled(boolean)
+ */
+public void setEnabled(boolean value) {
+	if (isEnabled() == value) 
+		return;
+	setFlag(FLAG_ENABLED, value);
+}
+
+/**
+ * Sets the given flag to the given value.
+ * @param flag The flag to set
+ * @param value The value
+ * @since 2.0
+ */
+protected final void setFlag(int flag, boolean value) {
+	if (value) 
+		flags |= flag;
+	else 
+		flags &= ~flag;
+}
+
+/**
+ * @see IFigure#setFocusTraversable(boolean)
+ */
+public void setFocusTraversable(boolean focusTraversable) {
+	if (isFocusTraversable() == focusTraversable)
+		return;
+	setFlag(FLAG_FOCUS_TRAVERSABLE, focusTraversable);	
+}
+
+/**
+ * @see IFigure#setFont(Font)
+ */
+public void setFont(Font f) {
+	if (font != f) {
+		font = f;
+		revalidate();
+	}
+}
+
+/**
+ * @see IFigure#setForegroundColor(Color)
+ */
+public void setForegroundColor(Color fg) {
+	if (fgColor != null && fgColor.equals(fg)) 
+		return;
+	fgColor = fg;
+	repaint();
+}
+
+/**
+ * @see IFigure#setLayoutManager(LayoutManager)
+ */
+public void setLayoutManager(LayoutManager manager) {
+	if (layoutManager instanceof LayoutNotifier)
+		((LayoutNotifier)layoutManager).realLayout = manager;
+	else
+		layoutManager = manager;
+	revalidate();
+}
+
+/**
+ * @see IFigure#setLocation(Point)
+ */
+public void setLocation(Point p) {
+	if (getLocation().equals(p)) 
+		return;
+	Rectangle r = new Rectangle(getBounds());
+	r.setLocation(p);
+	setBounds(r);
+}
+
+/**
+ * @see IFigure#setMaximumSize(Dimension)
+ */
+public void setMaximumSize(Dimension d) {
+	if (maxSize != null && maxSize.equals(d)) 
+		return;
+	maxSize = d;
+	revalidate();
+}
+
+/**
+ * @see IFigure#setMinimumSize(Dimension)
+ */
+public void setMinimumSize(Dimension d) {
+	if (minSize != null && minSize.equals(d)) 
+		return;
+	minSize = d;
+	revalidate();
+}
+
+/**
+ * @see IFigure#setOpaque(boolean)
+ */
+public void setOpaque(boolean opaque) {
+	if (isOpaque() == opaque)
+		return;
+	setFlag(FLAG_OPAQUE, opaque);
+	repaint();
+}
+
+/**
+ * @see IFigure#setParent(IFigure)
+ */
+public void setParent(IFigure p) {
+	IFigure oldParent = parent;
+	parent = p;
+	firePropertyChange("parent", oldParent, p);//$NON-NLS-1$
+}
+
+/**
+ * @see IFigure#setPreferredSize(Dimension)
+ */
+public void setPreferredSize(Dimension size) {
+	if (prefSize != null && prefSize.equals(size))
+		return;
+	prefSize = size;
+	revalidate();
+}
+
+/**
+ * Sets the preferred size of this figure.
+ * @param w The new preferred width
+ * @param h The new preferred height
+ * @see #setPreferredSize(Dimension)
+ * @since 2.0
+ */
+public final void setPreferredSize(int w, int h) {
+	setPreferredSize(new Dimension(w, h));
+}
+
+/**
+ * @see IFigure#setRequestFocusEnabled(boolean)
+ */
+public void setRequestFocusEnabled(boolean requestFocusEnabled) {
+	if (isRequestFocusEnabled() == requestFocusEnabled)
+		return;
+	setFlag(FLAG_FOCUSABLE, requestFocusEnabled);	
+}
+
+/**
+ * @see IFigure#setSize(Dimension)
+ */
+public final void setSize(Dimension d) {
+	setSize(d.width, d.height);
+}
+
+/**
+ * @see IFigure#setSize(int, int)
+ */
+public void setSize(int w, int h) {
+	Rectangle bounds = getBounds();
+	if (bounds.width == w && bounds.height == h)
+		return;
+	Rectangle r = new Rectangle(getBounds());
+	r.setSize(w, h);
+	setBounds(r);
+}
+
+/**
+ * @see IFigure#setToolTip(IFigure)
+ */
+public void setToolTip(IFigure f) {
+	if (toolTip == f)
+		return;
+	toolTip = f;
+}
+
+/**
+ * Sets this figure to be valid if <i>value</i> is <code>true</code> and invalid
+ * otherwise.
+ * @param value The valid value 
+ * @since 2.0
+ */
+public void setValid(boolean value) {
+	setFlag(FLAG_VALID, value);
+}
+
+/**
+ * @see IFigure#setVisible(boolean)
+ */
+public void setVisible(boolean visible) {
+	boolean currentVisibility = isVisible();
+	if (visible == currentVisibility) 
+		return;
+	if (currentVisibility) 
+		erase();
+	setFlag(FLAG_VISIBLE, visible);
+	if (visible) 
+		repaint();
+	revalidate();
+}
+
+/**
+ * @see IFigure#translate(int, int)
+ */
+public final void translate(int x, int y) {
+	primTranslate(x, y);
+	fireFigureMoved();
+}
+
+/**
+ * @see IFigure#translateFromParent(Translatable)
+ */
+public void translateFromParent(Translatable t) {
+	if (useLocalCoordinates())
+		t.performTranslate(
+			-getBounds().x - getInsets().left,
+			-getBounds().y - getInsets().top);
+}
+
+/**
+ * @see IFigure#translateToAbsolute(Translatable)
+ */
+public final void translateToAbsolute(Translatable t) {
+	if (getParent() != null) {
+		getParent().translateToParent(t);
+		getParent().translateToAbsolute(t);
+	}
+}
+
+/**
+ * @see IFigure#translateToParent(Translatable)
+ */
+public void translateToParent(Translatable t) {
+	if (useLocalCoordinates())
+		t.performTranslate(
+			getBounds().x + getInsets().left,
+			getBounds().y + getInsets().top);
+}
+
+/**
+ * @see IFigure#translateToRelative(Translatable)
+ */
+public final void translateToRelative(Translatable t) {
+	if (getParent() != null) {
+		getParent().translateToRelative(t);
+		getParent().translateFromParent(t);
+	}
+}
+
+/**
+ * Returns <code>true</code> if this Figure uses local coordinates. This means its
+ * children are placed relative to this Figure's top-left corner.
+ * @return <code>true</code> if this Figure uses local coordinates
+ * @since 2.0
+ */
+protected boolean useLocalCoordinates() {
+	return false;
+}
+
+/**
+ * @see IFigure#validate()
+ */
+public void validate() {
+	if (isValid())
+		return;
+	setValid(true);
+	layout();
+	for (int i = 0; i < children.size(); i++)
+		((IFigure)children.get(i)).validate();
+}
+
+/**
+ * A search which does not filter any figures.
+ * since 3.0
+ */
+protected static final class IdentitySearch implements TreeSearch {
+	/**
+	 * The singleton instance.
+	 */
+	public static final TreeSearch INSTANCE = new IdentitySearch();
+	private IdentitySearch() { }
+	/**
+	 * Always returns <code>true</code>.
+	 * @see TreeSearch#accept(IFigure)
+	 */
+	public boolean accept(IFigure f) {
+		return true;
+	}
+	/**
+	 * Always returns <code>false</code>.
+	 * @see TreeSearch#prune(IFigure)
+	 */
+	public boolean prune(IFigure f) {
+		return false;
+	}
+}
+
+final class LayoutNotifier implements LayoutManager {
+	
+	LayoutManager realLayout;
+	List listeners = new ArrayList(1);
+	
+	LayoutNotifier(LayoutManager layout, LayoutListener listener) {
+		realLayout = layout;
+		listeners.add(listener);
+	}
+		
+	public Object getConstraint(IFigure child) {
+		if (realLayout != null)
+			return realLayout.getConstraint(child);
+		return null;
+	}
+
+	public Dimension getMinimumSize(IFigure container, int wHint, int hHint) {
+		if (realLayout != null)
+			return realLayout.getMinimumSize(container, wHint, hHint);
+		return null;
+	}
+
+	public Dimension getPreferredSize(IFigure container, int wHint, int hHint) {
+		if (realLayout != null)
+			return realLayout.getPreferredSize(container, wHint, hHint);
+		return null;
+	}
+
+	public void invalidate() {
+		for (int i = 0; i < listeners.size(); i++)
+			((LayoutListener)listeners.get(i)).invalidate(Figure.this);
+		
+		if (realLayout != null)
+			realLayout.invalidate();
+	}
+
+	public void layout(IFigure container) {
+		boolean consumed = false;
+		for (int i = 0; i < listeners.size(); i++)
+			consumed |= ((LayoutListener)listeners.get(i)).layout(container);
+
+		if (realLayout != null && !consumed)
+			realLayout.layout(container);
+		for (int i = 0; i < listeners.size(); i++)
+			((LayoutListener)listeners.get(i)).postLayout(container);
+	}
+
+	public void remove(IFigure child) {
+		for (int i = 0; i < listeners.size(); i++)
+			((LayoutListener)listeners.get(i)).remove(child);
+		if (realLayout != null)
+			realLayout.remove(child);
+	}
+
+	public void setConstraint(IFigure child, Object constraint) {
+		for (int i = 0; i < listeners.size(); i++)
+			((LayoutListener)listeners.get(i)).setConstraint(child, constraint);
+		if (realLayout != null)
+			realLayout.setConstraint(child, constraint);
+	}
+}
+
+/**
+ * Iterates over a Figure's children.
+ */
+public static class FigureIterator {
+	private List list;
+	private int index;
+	/**
+	 * Constructs a new FigureIterator for the given Figure.
+	 * @param figure The Figure whose children to iterate over
+	 */
+	public FigureIterator(IFigure figure) {
+		list = figure.getChildren();
+		index = list.size();
+	}
+	/**
+	 * Returns the next Figure.
+	 * @return The next Figure
+	 */
+	public IFigure nextFigure() {
+		return (IFigure)list.get(--index);
+	}
+	/**
+	 * Returns <code>true</code> if there's another Figure to iterate over.
+	 * @return <code>true</code> if there's another Figure to iterate over
+	 */
+	public boolean hasNext() {
+		return index > 0;
+	}
+}
+
+/**
+ * An UpdateManager that does nothing.
+ */
+protected static final UpdateManager NO_MANAGER = new UpdateManager() {
+	public void addDirtyRegion (IFigure figure, int x, int y, int w, int h) { }
+	public void addInvalidFigure(IFigure f) { }
+	public void performUpdate() { }
+	public void performUpdate(Rectangle region) { }
+	public void setRoot(IFigure root) { }
+	public void setGraphicsSource(GraphicsSource gs) { }
+};
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureCanvas.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureCanvas.java
new file mode 100644
index 0000000..4676650
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureCanvas.java
@@ -0,0 +1,482 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A Canvas that contains {@link Figure Figures}.
+ * 
+ * <p>
+ * Note: Only one of the styles RIGHT_TO_LEFT, LEFT_TO_RIGHT may be specified.
+ * </p>
+ */
+public class FigureCanvas
+	extends Canvas
+{
+
+/** Never show scrollbar */
+public static int NEVER = 0;
+/** Automatically show scrollbar when needed */
+public static int AUTOMATIC = 1;
+/** Always show scrollbar */
+public static int ALWAYS = 2;
+
+private int vBarVisibility = AUTOMATIC;
+private int hBarVisibility = AUTOMATIC;
+private Viewport viewport;
+private Font font;
+private int hBarOffset;
+private int vBarOffset;
+
+private PropertyChangeListener horizontalChangeListener = new PropertyChangeListener() {
+	public void propertyChange(PropertyChangeEvent event) {
+		RangeModel model = getViewport().getHorizontalRangeModel();
+		hBarOffset = Math.max(0, -model.getMinimum());
+		getHorizontalBar().setValues(
+			model.getValue() + hBarOffset,
+			model.getMinimum() + hBarOffset,
+			model.getMaximum() + hBarOffset,
+			model.getExtent(),
+			Math.max(1, model.getExtent() / 20),
+			Math.max(1, model.getExtent() * 3 / 4));
+	}
+};
+
+private PropertyChangeListener verticalChangeListener = new PropertyChangeListener() {
+	public void propertyChange(PropertyChangeEvent event) {
+		RangeModel model = getViewport().getVerticalRangeModel();
+		vBarOffset = Math.max(0, -model.getMinimum());
+		getVerticalBar().setValues(
+			model.getValue() + vBarOffset,
+			model.getMinimum() + vBarOffset,
+			model.getMaximum() + vBarOffset,
+			model.getExtent(),
+			Math.max(1, model.getExtent() / 20),
+			Math.max(1, model.getExtent() * 3 / 4));
+	}
+};
+
+private final LightweightSystem lws;
+
+/**
+ * Creates a new FigureCanvas with the given parent.
+ * 
+ * @param parent the parent
+ */
+public FigureCanvas(Composite parent) {
+	this(parent, SWT.DOUBLE_BUFFERED, new LightweightSystem());
+}
+
+/**
+ * Constructor
+ * @param parent the parent composite
+ * @param style look at class javadoc for valid styles
+ * @since 3.1
+ */
+public FigureCanvas(Composite parent, int style) {
+	this(parent, style, new LightweightSystem());
+}
+
+/**
+ * Constructs a new FigureCanvas with the given parent and LightweightSystem.
+ * @param parent the parent
+ * @param lws the LightweightSystem
+ */
+public FigureCanvas(Composite parent, LightweightSystem lws) {
+	this(parent, SWT.DOUBLE_BUFFERED, lws);
+}
+
+/**
+ * Constructor
+ * @param parent the parent composite
+ * @param style look at class javadoc for valid styles
+ * @param lws the lightweight system
+ * @since 3.1
+ */
+public FigureCanvas(Composite parent, int style, LightweightSystem lws) {
+	super(parent, checkStyle(style | SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND
+			| SWT.V_SCROLL | SWT.H_SCROLL));
+	getHorizontalBar().setVisible(false);
+	getVerticalBar().setVisible(false);
+	this.lws = lws;
+	lws.setControl(this);
+	hook();
+}
+
+private static int checkStyle(int style) {
+	int validStyles = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT | SWT.V_SCROLL | SWT.H_SCROLL
+			| SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED;
+	if ((style & ~validStyles) != 0)
+		throw new IllegalArgumentException("Invalid style being set on FigureCanvas"); //$NON-NLS-1$
+	return style;
+}
+
+/**
+ * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
+ */
+public org.eclipse.swt.graphics.Point computeSize(int wHint, int hHint, boolean changed) {
+	// TODO not accounting for scrollbars and trim
+	Dimension size = getLightweightSystem().getRootFigure().getPreferredSize(wHint, hHint);
+	size.union(new Dimension(wHint, hHint));
+	return new org.eclipse.swt.graphics.Point(size.width, size.height);
+}
+
+/**
+ * @return the contents of the {@link Viewport}.
+ */
+public IFigure getContents() {
+	return getViewport().getContents();
+}
+
+/**
+ * @see org.eclipse.swt.widgets.Control#getFont()
+ */
+public Font getFont() {
+	if (font == null)
+		font = super.getFont();
+	return font;
+}
+
+/**
+ * @return the horizontal scrollbar visibility.
+ */
+public int getHorizontalScrollBarVisibility() {
+	return hBarVisibility;
+}
+
+/**
+ * @return the LightweightSystem
+ */
+public LightweightSystem getLightweightSystem() {
+	return lws;
+}
+
+/**
+ * @return the vertical scrollbar visibility.
+ */
+public int getVerticalScrollBarVisibility() {
+	return vBarVisibility;
+}
+
+/**
+ * Returns the Viewport.  If it's <code>null</code>, a new one is created.
+ * @return the viewport
+ */
+public Viewport getViewport() {
+	if (viewport == null)
+		setViewport(new Viewport(true));
+	return viewport;
+}
+
+/**
+ * Adds listeners for scrolling.
+ */
+private void hook() {
+	getLightweightSystem().getUpdateManager().addUpdateListener(new UpdateListener() {
+		public void notifyPainting(Rectangle damage, java.util.Map dirtyRegions) { }
+		public void notifyValidating() {
+			if (!isDisposed())
+				layoutViewport();
+		}
+	});
+
+	getHorizontalBar().addSelectionListener(new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent event) {
+			scrollToX(getHorizontalBar().getSelection() - hBarOffset);
+		}
+	});
+
+	getVerticalBar().addSelectionListener(new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent event) {
+			scrollToY(getVerticalBar().getSelection() - vBarOffset);
+		}
+	});
+}
+
+private void hookViewport() {
+	getViewport()
+		.getHorizontalRangeModel()
+		.addPropertyChangeListener(horizontalChangeListener);
+	getViewport()
+		.getVerticalRangeModel()
+		.addPropertyChangeListener(verticalChangeListener);
+}
+
+private void unhookViewport() {
+	getViewport()
+		.getHorizontalRangeModel()
+		.removePropertyChangeListener(horizontalChangeListener);
+	getViewport()
+		.getVerticalRangeModel()
+		.removePropertyChangeListener(verticalChangeListener);
+}
+
+private void layoutViewport() {
+	ScrollPaneSolver.Result result;
+	result = ScrollPaneSolver.solve(new Rectangle(getBounds()).setLocation(0, 0),
+		getViewport(),
+		getHorizontalScrollBarVisibility(),
+		getVerticalScrollBarVisibility(),
+		computeTrim(0, 0, 0, 0).width,
+		computeTrim(0, 0, 0, 0).height);
+	getLightweightSystem().setIgnoreResize(true);
+	try {
+		if (getHorizontalBar().getVisible() != result.showH)
+			getHorizontalBar().setVisible(result.showH);
+		if (getVerticalBar().getVisible() != result.showV)
+			getVerticalBar().setVisible(result.showV);
+		Rectangle r = new Rectangle(getClientArea());
+		r.setLocation(0, 0);
+		getLightweightSystem().getRootFigure().setBounds(r);
+	} finally {
+		getLightweightSystem().setIgnoreResize(false);
+	}
+}
+
+/**
+ * Scrolls in an animated way to the new x and y location.
+ * @param x the x coordinate to scroll to
+ * @param y the y coordinate to scroll to
+ */
+public void scrollSmoothTo(int x, int y) {
+	// Ensure newHOffset and newVOffset are within the appropriate ranges
+	x = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), x);
+	y = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), y);
+
+	int oldX = getViewport().getViewLocation().x;
+	int oldY = getViewport().getViewLocation().y;
+	int dx = x - oldX;
+	int dy = y - oldY;
+
+	if (dx == 0 && dy == 0)
+		return; //Nothing to do.
+
+	Dimension viewingArea = getViewport().getClientArea().getSize();
+
+	int minFrames = 3;
+	int maxFrames = 6;
+	if (dx == 0 || dy == 0) {
+		minFrames = 6;
+		maxFrames = 13;
+	}
+	int frames = (Math.abs(dx) + Math.abs(dy)) / 15;
+	frames = Math.max(frames, minFrames);
+	frames = Math.min(frames, maxFrames);
+
+	int stepX = Math.min((dx / frames), (viewingArea.width / 3));
+	int stepY = Math.min((dy / frames), (viewingArea.height / 3));
+
+	for (int i = 1; i < frames; i++) {
+		scrollTo(oldX + i * stepX, oldY + i * stepY);
+		getViewport().getUpdateManager().performUpdate();
+	}
+	scrollTo(x, y);
+}
+
+/**
+ * Scrolls the contents to the new x and y location.  If this scroll operation only 
+ * consists of a vertical or horizontal scroll, a call will be made to 
+ * {@link #scrollToY(int)} or {@link #scrollToX(int)}, respectively, to increase 
+ * performance.
+ * 
+ * @param x the x coordinate to scroll to
+ * @param y the y coordinate to scroll to
+ */
+public void scrollTo(int x, int y) {
+	x = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), x);
+	y = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), y);
+	if (x == getViewport().getViewLocation().x)
+		scrollToY(y);
+	else if (y == getViewport().getViewLocation().y)
+		scrollToX(x);
+	else
+		getViewport().setViewLocation(x, y);
+}
+/**
+ * Scrolls the contents horizontally so that they are offset by <code>hOffset</code>. 
+ * 
+ * @param hOffset the new horizontal offset
+ */
+public void scrollToX(int hOffset) {
+	hOffset = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), hOffset);
+	int hOffsetOld = getViewport().getViewLocation().x;
+	if (hOffset == hOffsetOld)
+		return;
+	int dx = -hOffset + hOffsetOld;
+	
+	Rectangle clientArea = getViewport().getBounds().getCropped(getViewport().getInsets());
+	Rectangle blit = clientArea.getResized(-Math.abs(dx), 0);
+	Rectangle expose = clientArea.getCopy();
+	Point dest = clientArea.getTopLeft();
+	expose.width = Math.abs(dx);
+	if (dx < 0) { //Moving left?
+		blit.translate(-dx, 0); //Move blit area to the right
+		expose.x = dest.x + blit.width;
+	} else //Moving right
+		dest.x += dx; //Move expose area to the right
+
+	// fix for bug 41111
+	Control[] children = getChildren();
+	boolean[] manualMove = new boolean[children.length];
+	for (int i = 0; i < children.length; i++) {
+		org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
+		manualMove[i] = blit.width <= 0 || bounds.x > blit.x + blit.width 
+				|| bounds.y > blit.y + blit.height || bounds.x + bounds.width < blit.x 
+				|| bounds.y + bounds.height < blit.y;
+	}
+	scroll(dest.x, dest.y, blit.x, blit.y, blit.width, blit.height,	true);
+	for (int i = 0; i < children.length; i++) {
+		org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
+		if (manualMove[i])
+			children[i].setBounds(bounds.x + dx, bounds.y, bounds.width, bounds.height);
+	}
+
+	getViewport().setIgnoreScroll(true);
+	getViewport().setHorizontalLocation(hOffset);
+	getViewport().setIgnoreScroll(false);
+	redraw(expose.x, expose.y, expose.width, expose.height, true);
+}
+
+/**
+ * Scrolls the contents vertically so that they are offset by <code>vOffset</code>. 
+ * 
+ * @param vOffset the new vertical offset
+ */
+public void scrollToY(int vOffset) {
+	vOffset = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), vOffset);
+	int vOffsetOld = getViewport().getViewLocation().y;
+	if (vOffset == vOffsetOld)
+		return;
+	int dy = -vOffset + vOffsetOld;
+	
+	Rectangle clientArea = getViewport().getBounds().getCropped(getViewport().getInsets());
+	Rectangle blit = clientArea.getResized(0, -Math.abs(dy));
+	Rectangle expose = clientArea.getCopy();
+	Point dest = clientArea.getTopLeft();
+	expose.height = Math.abs(dy);
+	if (dy < 0) { //Moving up?
+		blit.translate(0, -dy); //Move blit area down
+		expose.y = dest.y + blit.height; //Move expose area down
+	} else //Moving down
+		dest.y += dy;
+
+	// fix for bug 41111
+	Control[] children = getChildren();
+	boolean[] manualMove = new boolean[children.length];
+	for (int i = 0; i < children.length; i++) {
+		org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
+		manualMove[i] = blit.height <= 0 || bounds.x > blit.x + blit.width 
+				|| bounds.y > blit.y + blit.height || bounds.x + bounds.width < blit.x 
+				|| bounds.y + bounds.height < blit.y;
+	}
+	scroll(dest.x, dest.y, blit.x, blit.y, blit.width, blit.height,	true);
+	for (int i = 0; i < children.length; i++) {
+		org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
+		if (manualMove[i])
+			children[i].setBounds(bounds.x, bounds.y + dy, bounds.width, bounds.height);
+	}
+	
+	getViewport().setIgnoreScroll(true);
+	getViewport().setVerticalLocation(vOffset);
+	getViewport().setIgnoreScroll(false);
+	redraw(expose.x, expose.y, expose.width, expose.height, true);
+}
+
+/**
+ * Sets the given border on the LightweightSystem's root figure.
+ * 
+ * @param	border	The new border
+ */
+public void setBorder(Border border) {
+	getLightweightSystem().getRootFigure().setBorder(border);
+}
+
+/**
+ * Sets the contents of the {@link Viewport}.
+ * 
+ * @param figure the new contents
+ */
+public void setContents(IFigure figure) {
+	getViewport().setContents(figure);
+}
+
+/**
+ * @see org.eclipse.swt.widgets.Control#setFont(org.eclipse.swt.graphics.Font)
+ */
+public void setFont(Font font) {
+	this.font = font;
+	super.setFont(font);
+}
+
+/**
+ * Sets the horizontal scrollbar visibility.  Possible values are {@link #AUTOMATIC}, 
+ * {@link #ALWAYS}, and {@link #NEVER}.
+ * 
+ * @param v the new visibility
+ */
+public void setHorizontalScrollBarVisibility(int v) {
+	hBarVisibility = v;
+}
+
+/**
+ * Sets both the horizontal and vertical scrollbar visibility to the given value.  
+ * Possible values are {@link #AUTOMATIC}, {@link #ALWAYS}, and {@link #NEVER}.
+ * @param both the new visibility
+ */
+public void setScrollBarVisibility(int both) {
+	setHorizontalScrollBarVisibility(both);
+	setVerticalScrollBarVisibility(both);
+}
+
+/**
+ * Sets the vertical scrollbar visibility.  Possible values are {@link #AUTOMATIC}, 
+ * {@link #ALWAYS}, and {@link #NEVER}.
+ * 
+ * @param v the new visibility
+ */
+public void setVerticalScrollBarVisibility(int v) {
+	vBarVisibility = v;
+}
+
+/**
+ * Sets the Viewport. The given Viewport must use "fake" scrolling. That is, it must be
+ * constructed using <code>new Viewport(true)</code>.
+ * 
+ * @param vp the new viewport
+ */
+public void setViewport(Viewport vp) {
+	if (viewport != null)
+		unhookViewport();
+	viewport = vp;
+	lws.setContents(viewport);
+	hookViewport();
+}
+
+private int verifyScrollBarOffset(RangeModel model, int value) {
+	value = Math.max(model.getMinimum(), value);
+	return Math.min(model.getMaximum() - model.getExtent(), value);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureListener.java
new file mode 100644
index 0000000..d1e4a12
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureListener.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * A listener interface for receiving notification that an IFigure has moved.
+ */
+public interface FigureListener {
+
+/**
+ * Called when the given IFigure has moved.
+ * @param source The IFigure that has moved.
+ */
+void figureMoved(IFigure source);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureUtilities.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureUtilities.java
new file mode 100644
index 0000000..249b9ba
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FigureUtilities.java
@@ -0,0 +1,431 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.ArrayList;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * Provides miscellaneous Figure operations.
+ */
+public class FigureUtilities {
+
+private static final float RGB_VALUE_MULTIPLIER = 0.6f;
+private static GC gc;
+private static Font appliedFont;
+private static FontMetrics metrics;
+private static Color ghostFillColor = new Color(null, 31, 31, 31);
+
+/**
+ * Returns a new Color the same as the passed color in a darker hue.
+ * 
+ * @param color the color to darken
+ * @return the darkened color
+ * @since 2.0
+ */
+public static Color darker(Color color) {
+	return new Color(null,
+		(int)(color.getRed()   * RGB_VALUE_MULTIPLIER),
+		(int)(color.getGreen() * RGB_VALUE_MULTIPLIER),
+		(int)(color.getBlue()  * RGB_VALUE_MULTIPLIER));
+}
+
+/**
+ * Returns the FontMetrics associated with the passed Font.
+ * 
+ * @param f the font
+ * @return the FontMetrics for the given font
+ * @see GC#getFontMetrics()
+ * @since 2.0
+ */
+public static FontMetrics getFontMetrics(Font f) {
+	setFont(f);
+	if (metrics == null)
+		metrics = getGC().getFontMetrics();
+	return metrics;
+}
+
+/**
+ * Returns the GC used for various utilities. Advanced graphics must not be switched on by
+ * clients using this GC.
+ * @deprecated do not mess with this GC
+ * @return the GC
+ */
+protected static GC getGC() {
+	if (gc == null) {
+		gc = new GC(new Shell());
+		appliedFont = gc.getFont();
+	}
+	return gc;
+}
+
+/**
+ * Returns the dimensions of the String <i>s</i> using the font <i>f</i>.  Tab expansion 
+ * and carriage return processing are performed.
+ * @param s the string
+ * @param f the font
+ * @return the text's dimensions
+ * @see GC#textExtent(String)
+ */
+protected static org.eclipse.swt.graphics.Point getTextDimension(String s, Font f) {
+	setFont(f);
+	return getGC().textExtent(s);
+}
+
+/**
+ * Returns the highest ancestor for the given figure
+ * @since 3.0
+ * @param figure a figure
+ * @return the root ancestor
+ */
+public static IFigure getRoot(IFigure figure) {
+	while (figure.getParent() != null)
+		figure = figure.getParent();
+	return figure;
+}
+
+/**
+ * Returns the dimensions of the String <i>s</i> using the font <i>f</i>. No tab
+ * expansion or carriage return processing will be performed.
+ * @param s the string
+ * @param f the font
+ * @return the string's dimensions
+ * @see GC#stringExtent(java.lang.String)
+ */
+protected static org.eclipse.swt.graphics.Point getStringDimension(String s, Font f) {
+	setFont(f);
+	return getGC().stringExtent(s);
+}
+
+/**
+ * Returns the largest substring of <i>s</i> in Font <i>f</i> that can be confined to the 
+ * number of pixels in <i>availableWidth<i>.
+ * 
+ * @param s the original string
+ * @param f the font
+ * @param availableWidth the available width
+ * @return the largest substring that fits in the given width
+ * @since 2.0
+ */
+static int getLargestSubstringConfinedTo(String s, Font f, int availableWidth) {
+	FontMetrics metrics = getFontMetrics(f);
+	int min, max;
+	float avg = metrics.getAverageCharWidth();
+	min = 0;
+	max = s.length() + 1;
+
+	//The size of the current guess
+	int guess = 0,
+	    guessSize = 0;
+	while ((max - min) > 1) {
+		//Pick a new guess size
+		//	New guess is the last guess plus the missing width in pixels
+		//	divided by the average character size in pixels
+		guess = guess + (int)((availableWidth - guessSize) / avg);
+
+		if (guess >= max) guess = max - 1;
+		if (guess <= min) guess = min + 1;
+
+		//Measure the current guess
+		guessSize = getTextExtents(s.substring(0, guess), f).width;
+
+		if (guessSize < availableWidth)
+			//We did not use the available width
+			min = guess;
+		else
+			//We exceeded the available width
+			max = guess;
+	}
+	return min;
+}
+
+/**
+ * Returns the Dimensions of the given text, converting newlines and tabs appropriately.
+ * 
+ * @param text the text
+ * @param f the font
+ * @return the dimensions of the given text
+ * @since 2.0
+ */
+public static Dimension getTextExtents(String text, Font f) {
+	return new Dimension(getTextDimension(text, f));
+}
+
+/**
+ * Returns the Dimensions of <i>s</i> in Font <i>f</i>.
+ * 
+ * @param s the string
+ * @param f the font
+ * @return the dimensions of the given string
+ * @since 2.0
+ */
+public static Dimension getStringExtents(String s, Font f) {
+	return new Dimension(getStringDimension(s, f));
+}
+
+/**
+ * Returns the Dimensions of the given text, converting newlines and tabs appropriately.
+ * 
+ * @param s the string
+ * @param f the font
+ * @param result the Dimension that will contain the result of this calculation
+ * @since 2.0
+ */
+public static void getTextExtents(String s, Font f, Dimension result) {
+	org.eclipse.swt.graphics.Point pt = getTextDimension(s, f);
+	result.width = pt.x;
+	result.height = pt.y;
+}
+
+/**
+ * Returns the width of <i>s</i> in Font <i>f</i>.
+ * 
+ * @param s the string
+ * @param f the font
+ * @return the width
+ * @since 2.0
+ */
+public static int getTextWidth(String s, Font f) {
+	return getTextDimension(s, f).x;
+}
+
+/**
+ * Returns a Color the same as the passed color in a lighter hue.
+ * 
+ * @param rgb the color
+ * @return the lighter color
+ * @since 2.0
+ */
+public static Color lighter(Color rgb) {
+	int r = rgb.getRed(),
+	    g = rgb.getGreen(),
+	    b = rgb.getBlue();
+
+	return new Color(null,
+		Math.max(2, Math.min((int)(r / RGB_VALUE_MULTIPLIER), 255)),
+		Math.max(2, Math.min((int)(g / RGB_VALUE_MULTIPLIER), 255)),
+		Math.max(2, Math.min((int)(b / RGB_VALUE_MULTIPLIER), 255))
+	);
+}
+
+/**
+ * Produces a ghosting effect on the shape <i>s</i>.
+ * 
+ * @param s the shape
+ * @return the ghosted shape
+ * @since 2.0
+ */
+public static Shape makeGhostShape(Shape s) {
+	s.setBackgroundColor(ghostFillColor);
+	s.setFillXOR(true);
+	s.setOutlineXOR(true);
+	return s;
+}
+
+/**
+ * Mixes the passed Colors and returns the resulting Color.
+ * 
+ * @param c1 the first color
+ * @param c2 the second color
+ * @param weight the first color's weight from 0-1
+ * @return the new color
+ * @since 2.0
+ */
+public static Color mixColors(Color c1, Color c2, double weight) {
+	return new Color(null,
+			(int)(c1.getRed() * weight + c2.getRed() * (1 - weight)),
+			(int)(c1.getGreen() * weight + c2.getGreen() * (1 - weight)),
+			(int)(c1.getBlue() * weight + c2.getBlue() * (1 - weight)));
+}
+
+
+/**
+ * Mixes the passed Colors and returns the resulting Color.
+ * 
+ * @param c1 the first color
+ * @param c2 the second color
+ * @return the new color
+ * @since 2.0
+ */
+public static Color mixColors(Color c1, Color c2) {
+	return new Color(null,
+		(c1.getRed() + c2.getRed()) / 2,
+		(c1.getGreen() + c2.getGreen()) / 2,
+		(c1.getBlue() + c2.getBlue()) / 2);
+}
+
+/**
+ * Paints a border with an etching effect, having a shadow of Color <i>shadow</i> and
+ * highlight of Color <i>highlight</i>.
+ * 
+ * @param g the graphics object
+ * @param r the bounds of the border
+ * @param shadow the shadow color
+ * @param highlight the highlight color
+ * @since 2.0
+ */
+public static void paintEtchedBorder(Graphics g, Rectangle r, 
+										Color shadow, Color highlight) {
+	int x = r.x,
+		y = r.y,
+		w = r.width,
+		h = r.height;
+
+	g.setLineStyle(Graphics.LINE_SOLID);
+	g.setLineWidth(1);
+	g.setXORMode(false);
+
+   	w -= 2;
+	h -= 2;
+
+	g.setForegroundColor(shadow);
+	g.drawRectangle(x, y, w, h);
+
+	x++;
+	y++;
+	g.setForegroundColor(highlight);
+	g.drawRectangle(x, y, w, h);
+}
+
+/**
+ * Helper method to paint a grid.  Painting is optimized as it is restricted to the
+ * Graphics' clip.
+ * 
+ * @param	g			The Graphics object to be used for painting
+ * @param	f			The figure in which the grid is to be painted
+ * @param	origin		Any point where the grid lines are expected to intersect
+ * @param	distanceX	Distance between vertical grid lines; if 0 or less, vertical grid
+ * 						lines will not be drawn
+ * @param	distanceY	Distance between horizontal grid lines; if 0 or less, horizontal
+ * 						grid lines will not be drawn
+ * 
+ * @since 3.0
+ */
+public static void paintGrid(Graphics g, IFigure f, 
+		org.eclipse.draw2d.geometry.Point origin, int distanceX, int distanceY) {
+	Rectangle clip = g.getClip(Rectangle.SINGLETON);
+	
+	if (distanceX > 0) {
+		if (origin.x >= clip.x)
+			while (origin.x - distanceX >= clip.x)
+				origin.x -= distanceX;
+		else
+			while (origin.x < clip.x)
+				origin.x += distanceX;
+		for (int i = origin.x; i < clip.x + clip.width; i += distanceX)
+			g.drawLine(i, clip.y, i, clip.y + clip.height);
+	}
+	
+	if (distanceY > 0) {
+		if (origin.y >= clip.y)
+			while (origin.y - distanceY >= clip.y)
+				origin.y -= distanceY;
+		else
+			while (origin.y < clip.y)
+				origin.y += distanceY;
+		for (int i = origin.y; i < clip.y + clip.height; i += distanceY)
+			g.drawLine(clip.x, i, clip.x + clip.width, i);
+	}
+}
+
+/**
+ * Paints a border with an etching effect, having a shadow of a darker version of g's 
+ * background color, and a highlight a lighter version of g's background color.
+ * 
+ * @param g the graphics object
+ * @param r the bounds of the border
+ * @since 2.0
+ */
+public static void paintEtchedBorder(Graphics g, Rectangle r) {
+	Color rgb = g.getBackgroundColor(),
+	    shadow = darker(rgb),
+	    highlight = lighter(rgb);
+	paintEtchedBorder(g, r, shadow, highlight);
+}
+
+/**
+ * Sets Font to passed value.
+ * 
+ * @param f the new font
+ * @since 2.0
+ */
+protected static void setFont(Font f) {
+	if (appliedFont == f || f.equals(appliedFont))
+		return;
+	getGC().setFont(f);
+	appliedFont = f;
+	metrics = null;
+}
+
+/**
+ * Returns the figure which is the ancestor of both figures, or <code>null</code>. A
+ * figure is an ancestor if it is the parent of another figure, or if it is the ancestor
+ * of that figure's parent. If one figure contains the other, <code>null</code> is
+ * returned.
+ * @since 3.1
+ * @param l left
+ * @param r right
+ * @return the common ancestor
+ */
+public static IFigure findCommonAncestor(IFigure l, IFigure r) {
+	if (l == r)
+		return l;
+	ArrayList left = new ArrayList();
+	ArrayList right = new ArrayList();
+	while (l != null) {
+		left.add(l);
+		l = l.getParent();
+	}
+	while (r != null) {
+		right.add(r);
+		r = r.getParent();
+	}
+	if (left.isEmpty() || right.isEmpty())
+		return null;
+    
+    int il = left.size() - 1;
+    int ir = right.size() - 1;
+    do {
+        if (left.get(il) != right.get(ir))
+                break;
+        il--;
+        ir--;           
+    } while (il >= 0 && ir >= 0);
+
+    return (IFigure) left.get(il + 1);
+}
+
+/**
+ *  Returns <code>true</code> if the ancestor contains the descendant, or is the ancestor
+ *  of the descendant's parent.
+ * @param ancestor the ancestor
+ * @param descendant the descendant
+ * @return <code>true</code> if ancestor
+ * @since 3.2
+ */
+public static boolean isAncestor(final IFigure ancestor, IFigure descendant) {
+	while (descendant != null) {
+		descendant = descendant.getParent();
+		if (descendant == ancestor)
+			return true;
+	}
+	return false;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FlowLayout.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FlowLayout.java
new file mode 100644
index 0000000..6c54b66
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FlowLayout.java
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.draw2d.geometry.Transposer;
+
+/**
+ * Lays out children in rows or columns, wrapping when the current row/column is filled.
+ * The aligment and spacing of rows in the parent can be configured.  The aligment and
+ * spacing of children within a row can be configured.
+ */
+public class FlowLayout
+	extends AbstractHintLayout
+{
+
+/** Constant to specify components to be aligned in the center */
+public static final int ALIGN_CENTER = 0;
+/** Constant to specify components to be aligned on the left/top */
+public static final int ALIGN_LEFTTOP = 1;
+/** Constant to specify components to be aligned on the right/bottom */
+public static final int ALIGN_RIGHTBOTTOM = 2;
+
+/** Constant to specify components should be layed out horizontally */
+public static final boolean HORIZONTAL = true;
+/** Constant to specify components should be layed out vertically */
+public static final boolean VERTICAL = false;
+
+/** The horizontal property. */
+protected boolean horizontal = true;
+/** 
+ * The property that determines whether leftover space at the end of a row/column should
+ * be filled by the last item in that row/column. 
+ */
+protected boolean fill = false;
+
+/** The transposer used in converting horizontal layout to vertical. */
+protected Transposer transposer; {
+	transposer = new Transposer();
+	transposer.setEnabled(!horizontal);
+}
+
+/** The alignment along the major axis. */
+protected int majorAlignment = ALIGN_LEFTTOP;
+/** The alignment along the minor axis. */
+protected int minorAlignment = ALIGN_LEFTTOP;
+/** The spacing along the minor axis. */
+protected int minorSpacing = 5;
+/** The spacing along the major axis. */
+protected int majorSpacing = 5;
+private WorkingData data = null;
+
+/**
+ * Holds the necessary information for layout calculations.
+ */
+class WorkingData {
+	int rowHeight, rowWidth, rowCount, rowX, rowY, maxWidth;
+	Rectangle bounds[], area;
+	IFigure row[];
+}
+
+/**
+ * Constructs a FlowLayout with horizontal orientation.
+ * @since 2.0
+ */
+public FlowLayout() { }
+
+/**
+ * Constructs a FlowLayout whose orientation is given in the input.
+ * @param isHorizontal <code>true</code> if the layout should be horizontal
+ * @since 2.0
+ */
+public FlowLayout(boolean isHorizontal) {
+	setHorizontal(isHorizontal);
+}
+
+/**
+ * @see org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(IFigure, int, int)
+ */
+protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
+	// Subtract out the insets from the hints
+	if (wHint > -1)
+		wHint = Math.max(0, wHint - container.getInsets().getWidth());
+	if (hHint > -1)
+		hHint = Math.max(0, hHint - container.getInsets().getHeight());
+	
+	// Figure out the new hint that we are interested in based on the orientation
+	// Ignore the other hint (by setting it to -1).  NOTE: The children of the
+	// parent figure will then be asked to ignore that hint as well.  
+	int maxWidth;
+	if (isHorizontal()) {
+		maxWidth = wHint;
+		hHint = -1;
+	} else {
+		maxWidth = hHint;
+		wHint = -1;
+	}
+	if (maxWidth < 0) {
+		maxWidth = Integer.MAX_VALUE;
+	}
+
+	// The preferred dimension that is to be calculated and returned
+	Dimension prefSize = new Dimension();
+
+	List children = container.getChildren();
+	int width = 0;
+	int height = 0;
+	IFigure child;
+	Dimension childSize;
+	
+	//Build the sizes for each row, and update prefSize accordingly
+	for (int i = 0; i < children.size(); i++) {
+		child = (IFigure)children.get(i);
+		childSize = transposer.t(getChildSize(child, wHint, hHint));
+		if (i == 0) {
+			width = childSize.width;
+			height = childSize.height;
+		} else if (width + childSize.width + getMinorSpacing() > maxWidth) {
+			// The current row is full, start a new row.
+			prefSize.height += height + getMajorSpacing();
+			prefSize.width = Math.max(prefSize.width, width);
+			width = childSize.width;
+			height = childSize.height;
+		} else {
+			// The current row can fit another child.
+			width += childSize.width + getMinorSpacing();
+			height = Math.max(height, childSize.height);
+		}
+	}
+
+	// Flush out the last row's data
+	prefSize.height += height;
+	prefSize.width = Math.max(prefSize.width, width);
+
+	// Transpose the dimension back, and compensate for the border.
+	prefSize = transposer.t(prefSize);
+	prefSize.width += container.getInsets().getWidth();
+	prefSize.height += container.getInsets().getHeight();
+	prefSize.union(getBorderPreferredSize(container));
+
+	return prefSize;
+}
+
+/**
+ * Provides the given child's preferred size.
+ * 
+ * @param child the Figure whose preferred size needs to be calculated
+ * @param wHint the width hint
+ * @param hHint the height hint
+ * @return the child's preferred size
+ */
+protected Dimension getChildSize(IFigure child, int wHint, int hHint) {
+	return child.getPreferredSize(wHint, hHint);
+}
+
+
+/**
+ * Returns the alignment used for an entire row/column.
+ * <P>
+ * Possible values are :
+ * <ul>
+ *   <li>{@link #ALIGN_CENTER}
+ * 	 <li>{@link #ALIGN_LEFTTOP}
+ * 	 <li>{@link #ALIGN_RIGHTBOTTOM}
+ * </ul>
+ *
+ * @return the major alignment
+ * @since 2.0
+ */
+public int getMajorAlignment() {
+	return majorAlignment;
+}
+
+/**
+ * Returns the spacing in pixels to be used between children in the direction parallel to
+ * the layout's orientation.
+ * @return the major spacing
+ */
+public int getMajorSpacing() {
+	return majorSpacing;
+}
+
+/** 
+ * Returns the alignment used for children within a row/column.
+ * <P>
+ * Possible values are :
+ * <ul>
+ *   <li>{@link #ALIGN_CENTER}
+ * 	 <li>{@link #ALIGN_LEFTTOP}
+ * 	 <li>{@link #ALIGN_RIGHTBOTTOM}
+ * </ul>
+ *
+ * @return the minor alignment
+ * @since 2.0
+ */
+public int getMinorAlignment() {
+	return minorAlignment;
+}
+
+/**
+ * Returns the spacing to be used between children within a row/column.
+ * @return the minor spacing
+ */
+public int getMinorSpacing() {
+	return minorSpacing;
+}
+
+/**
+ * Initializes the state of row data, which is internal to the layout process. 
+ */
+private void initRow() {
+	data.rowX = 0;
+	data.rowHeight = 0;
+	data.rowWidth = 0;
+	data.rowCount = 0;
+}
+
+/**
+ * Initializes state data for laying out children, based on the Figure given as input.
+ *
+ * @param parent the parent figure
+ * @since 2.0 
+ */
+private void initVariables(IFigure parent) {
+	data.row = new IFigure[parent.getChildren().size()];
+	data.bounds = new Rectangle[data.row.length];
+	data.maxWidth = data.area.width;
+}
+
+/**
+ * Returns <code>true</code> if the orientation of the layout is horizontal.
+ *
+ * @return <code>true</code> if the orientation of the layout is horizontal
+ * @since 2.0
+ */
+public boolean isHorizontal() {
+	return horizontal;
+}
+
+/**
+ * @see org.eclipse.draw2d.AbstractHintLayout#isSensitiveHorizontally(IFigure)
+ */
+protected boolean isSensitiveHorizontally(IFigure parent) {
+	return isHorizontal();
+}
+
+/**
+ * @see org.eclipse.draw2d.AbstractHintLayout#isSensitiveVertically(IFigure)
+ */
+protected boolean isSensitiveVertically(IFigure parent) {
+	return !isHorizontal();
+}
+
+/**
+ * @see org.eclipse.draw2d.LayoutManager#layout(IFigure)
+ */
+public void layout(IFigure parent) {
+	data = new WorkingData();
+	Rectangle relativeArea = parent.getClientArea();
+	data.area = transposer.t(relativeArea);
+
+	Iterator iterator = parent.getChildren().iterator();
+	int dx;
+
+	//Calculate the hints to be passed to children
+	int wHint = -1;
+	int hHint = -1;
+	if (isHorizontal())
+		wHint = parent.getClientArea().width;
+	else
+		hHint = parent.getClientArea().height;
+
+	initVariables(parent);
+	initRow();
+	int i = 0; 
+	while (iterator.hasNext()) {
+		IFigure f = (IFigure)iterator.next();
+		Dimension pref = transposer.t(getChildSize(f, wHint, hHint));
+		Rectangle r = new Rectangle(0, 0, pref.width, pref.height);
+
+		if (data.rowCount > 0) {
+			if (data.rowWidth + pref.width > data.maxWidth)
+				layoutRow(parent);
+		}
+		r.x = data.rowX;
+		r.y = data.rowY;
+		dx = r.width + getMinorSpacing();
+		data.rowX += dx;
+		data.rowWidth += dx;
+		data.rowHeight = Math.max(data.rowHeight, r.height);
+		data.row [data.rowCount] = f;
+		data.bounds[data.rowCount] = r;
+		data.rowCount++;
+		i++;
+	}
+	if (data.rowCount != 0)
+		layoutRow(parent);
+	data = null;
+}
+
+/**
+ * Layouts one row of components. This is done based on the layout's orientation, minor 
+ * alignment and major alignment.
+ *
+ * @param parent the parent figure
+ * @since 2.0
+ */
+protected void layoutRow(IFigure parent) {
+	int majorAdjustment = 0;
+	int minorAdjustment = 0;
+	int correctMajorAlignment = majorAlignment;
+	int correctMinorAlignment = minorAlignment;
+
+	majorAdjustment = data.area.width - data.rowWidth + getMinorSpacing();
+	
+	switch (correctMajorAlignment) {
+		case ALIGN_LEFTTOP: 
+			majorAdjustment = 0;
+			break;
+		case ALIGN_CENTER:
+			majorAdjustment /= 2;
+			break;
+		case ALIGN_RIGHTBOTTOM:
+			break;
+	}
+
+	for (int j = 0; j < data.rowCount; j++) {
+		if (fill) {
+			data.bounds[j].height = data.rowHeight;	
+		} else {
+			minorAdjustment = data.rowHeight - data.bounds[j].height;
+			switch (correctMinorAlignment) {
+				case ALIGN_LEFTTOP: 
+					minorAdjustment = 0;
+					break;
+				case ALIGN_CENTER:
+					minorAdjustment /= 2;
+				break;
+				case ALIGN_RIGHTBOTTOM:
+					break;
+			}
+			data.bounds[j].y += minorAdjustment;
+		}
+		data.bounds[j].x += majorAdjustment;
+		
+		setBoundsOfChild(parent, data.row[j], transposer.t(data.bounds[j]));
+	}
+	data.rowY += getMajorSpacing() + data.rowHeight;
+	initRow();
+}
+
+/**
+ * Sets the given bounds for the child figure input.
+ *
+ * @param parent the parent figure
+ * @param child the child figure
+ * @param bounds the size of the child to be set
+ * @since 2.0
+ */
+protected void setBoundsOfChild(IFigure parent, IFigure child, Rectangle bounds) {
+	parent.getClientArea(Rectangle.SINGLETON);
+	bounds.translate(Rectangle.SINGLETON.x, Rectangle.SINGLETON.y);
+	child.setBounds(bounds);
+}
+
+/**
+ * Sets flag based on layout orientation. If in horizontal orientation, all figures will 
+ * have the same height. If in vertical orientation, all figures will have the same width.
+ *
+ * @param value fill state desired
+ * @since 2.0
+ */
+public void setStretchMinorAxis(boolean value) {
+	fill = value;
+}
+
+/**
+ * Sets the orientation of the layout. 
+ *
+ * @param flag <code>true</code> if this layout should be horizontal
+ * @since 2.0
+ */
+public void setHorizontal(boolean flag) {
+	if (horizontal == flag) return;
+	invalidate();
+	horizontal = flag;
+	transposer.setEnabled(!horizontal);
+}
+
+/**
+ * Sets the alignment for an entire row/column within the parent figure.
+ * <P>
+ * Possible values are :
+ * <ul>
+ *   <li>{@link #ALIGN_CENTER}
+ * 	 <li>{@link #ALIGN_LEFTTOP}
+ * 	 <li>{@link #ALIGN_RIGHTBOTTOM}
+ * </ul>
+ *
+ * @param align the major alignment
+ * @since 2.0
+ */
+public void setMajorAlignment(int align) {
+	majorAlignment = align;
+}
+
+/**
+ * Sets the spacing in pixels to be used between children in the direction parallel to the
+ * layout's orientation.
+ *
+ * @param n the major spacing
+ * @since 2.0
+ */
+public void setMajorSpacing(int n) {
+	majorSpacing = n;
+}
+
+/**
+ * Sets the alignment to be used within a row/column.
+ * <P>
+ * Possible values are :
+ * <ul>
+ *   <li>{@link #ALIGN_CENTER}
+ * 	 <li>{@link #ALIGN_LEFTTOP}
+ * 	 <li>{@link #ALIGN_RIGHTBOTTOM}
+ * </ul>
+ *
+ * @param align the minor alignment
+ * @since 2.0
+ */
+public void setMinorAlignment(int align) {
+	minorAlignment = align;
+}
+
+/**
+ * Sets the spacing to be used between children within a row/column.
+ *
+ * @param n the minor spacing
+ * @since 2.0
+ */
+public void setMinorSpacing(int n) {
+	minorSpacing = n;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusBorder.java
new file mode 100644
index 0000000..e399d4b
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusBorder.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Insets;
+
+/**
+ * A Border that looks like the system's focus rectangle.
+ */
+public class FocusBorder
+	extends AbstractBorder
+{
+
+/**
+ * Constructs a new FocusBorder.
+ */
+public FocusBorder() { }
+
+/**
+ * @see org.eclipse.draw2d.Border#getInsets(IFigure)
+ */
+public Insets getInsets(IFigure figure) {
+	return new Insets(1);
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#isOpaque()
+ */
+public boolean isOpaque() {
+	return true;
+}
+
+/**
+ * Paints a focus rectangle.
+ * @see org.eclipse.draw2d.Border#paint(IFigure, Graphics, Insets)
+ */
+public void paint(IFigure figure, Graphics graphics, Insets insets) {
+	tempRect.setBounds(getPaintRectangle(figure, insets));
+	tempRect.width--;
+	tempRect.height--;
+	graphics.setForegroundColor(ColorConstants.black);
+	graphics.setBackgroundColor(ColorConstants.white);
+	graphics.drawFocus(tempRect);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusEvent.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusEvent.java
new file mode 100644
index 0000000..15e5931
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusEvent.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * An event that occurs when an {@link org.eclipse.draw2d.IFigure} gains or loses focus.
+ */
+public class FocusEvent {
+
+/** The figure losing focus */
+public IFigure loser;
+/** The figure gaining focus */
+public IFigure gainer;
+
+/**
+ * Constructs a new FocusEvent.
+ * @param loser the figure losing focus
+ * @param gainer the figure gaining focus
+ */
+public FocusEvent(IFigure loser, IFigure gainer) {
+	this.loser = loser;
+	this.gainer = gainer;
+}	
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusListener.java
new file mode 100644
index 0000000..e1f45ec
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusListener.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * A listener interface for receiving {@link FocusEvent FocusEvents}.
+ */
+public interface FocusListener {
+	
+/**
+ * Called when the listened to object has gained focus.
+ * @param fe The FocusEvent object
+ */
+void focusGained(FocusEvent fe);
+
+/**
+ * Called when the listened to object has lost focus.
+ * @param fe The FocusEvent object
+ */
+void focusLost(FocusEvent fe);
+
+/**
+ * An empty implementation of FocusListener for convenience.
+ */
+public class Stub 
+	implements FocusListener
+{
+	/**
+	 * @see org.eclipse.draw2d.FocusListener#focusGained(FocusEvent)
+	 */
+	public void focusGained(FocusEvent fe) { }
+	/**
+	 * @see org.eclipse.draw2d.FocusListener#focusLost(FocusEvent)
+	 */
+	public void focusLost(FocusEvent fe) { }
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusTraverseManager.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusTraverseManager.java
new file mode 100644
index 0000000..e3309be
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FocusTraverseManager.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.List;
+
+/**
+ * This class is a helper to the {@link SWTEventDispatcher}. It handles the task of 
+ * determining which Figure will gain focus upon a tab/shift-tab. It also keeps track of 
+ * the Figure with current focus.
+ * <p>
+ * Note: When a Canvas with a {@link LightweightSystem} gains focus, it gives focus to the 
+ * child Figure who had focus when this Canvas lost focus. If the canvas is gaining focus 
+ * for the first time, focus is given to its first child Figure.
+ */
+public class FocusTraverseManager {
+
+IFigure currentFocusOwner;
+
+/**
+ * Default constructor.
+ */
+public FocusTraverseManager() { }
+
+private IFigure findDeepestRightmostChildOf(IFigure fig) {
+	while (fig.getChildren().size() != 0) {
+		fig = (IFigure)fig.getChildren().get(fig.getChildren().size() - 1);
+	}	
+	return fig;
+}
+
+/**
+ * Returns the IFigure that will receive focus upon a 'tab' traverse event.
+ * 
+ * @param root the {@link LightweightSystem LightweightSystem's} root figure
+ * @param prevFocus the IFigure who currently owns focus
+ * @return the next focusable figure
+ */
+public IFigure getNextFocusableFigure(IFigure root, IFigure prevFocus) {
+	boolean found = false;
+	IFigure nextFocus = prevFocus;
+	
+	/*
+	 * If no Figure currently has focus, apply focus to root's first focusable child.
+	 */
+	if (prevFocus == null) {
+		if (root.getChildren().size() != 0) {
+			nextFocus = ((IFigure)root.getChildren().get(0));
+			if (isFocusEligible(nextFocus))
+				return nextFocus;
+		} else
+			return null;
+	}
+	
+	int siblingPos = nextFocus.getParent().getChildren().indexOf(nextFocus);
+	while (!found) {
+		IFigure parent = nextFocus.getParent();
+		
+		/*
+		 * Figure traversal is implemented using the pre-order left to right
+		 * tree traversal algorithm.
+		 *  
+		 * If the focused sibling has children, traverse to its leftmost child.
+		 * If the focused sibling has no children, traverse to the sibling
+		 * to its right.
+		 * If there is no sibling to the right, go up the tree until a node
+		 * with un-traversed siblings is found.
+		 */
+		List siblings = parent.getChildren();
+
+		if (nextFocus.getChildren().size() != 0) {
+			nextFocus = (IFigure)nextFocus.getChildren().get(0);
+			siblingPos = 0;
+			if (isFocusEligible(nextFocus))
+				found = true;	
+		} else if (siblingPos < siblings.size() - 1) {
+			nextFocus = ((IFigure)(siblings.get(++siblingPos)));
+			if (isFocusEligible(nextFocus))
+				found = true;
+		} else {
+			boolean untraversedSiblingFound = false;			
+			while (!untraversedSiblingFound) {
+				IFigure p = nextFocus.getParent();	
+				IFigure gp = p.getParent();
+				
+				if (gp != null) {
+					int parentSiblingCount = gp.getChildren().size();
+					int parentIndex = gp.getChildren().indexOf(p);
+					if (parentIndex < parentSiblingCount - 1) {
+						nextFocus = ((IFigure)p.getParent()
+								.getChildren().get(parentIndex + 1));
+						siblingPos = parentIndex + 1;
+						untraversedSiblingFound = true;
+						if (isFocusEligible(nextFocus))		
+							found = true;
+					} else
+						nextFocus = p;
+				} else {
+					nextFocus = null;
+					untraversedSiblingFound = true;
+					found = true;
+				}
+			}
+		}		
+	}
+	return nextFocus;
+}
+
+/**
+ * Returns the IFigure that will receive focus upon a 'shift-tab' traverse event.
+ * 
+ * @param root The {@link LightweightSystem LightweightSystem's} root figure
+ * @param prevFocus The IFigure who currently owns focus 
+ * @return the previous focusable figure
+ */
+public IFigure getPreviousFocusableFigure(IFigure root, IFigure prevFocus) {
+	if (prevFocus == null)
+		return null;
+	
+	boolean found = false;
+	IFigure nextFocus = prevFocus;
+ 	while (!found) {
+ 		IFigure parent = nextFocus.getParent();
+		
+		/* 
+		 * At root, return null to indicate traversal
+		 * is complete.
+		 */
+		if (parent == null)
+			return null;
+		
+		List siblings = parent.getChildren();
+		int siblingPos = siblings.indexOf(nextFocus);
+		
+		/*
+		 * Figure traversal is implemented using the post-order right to left 
+		 * tree traversal algorithm.
+		 * 
+		 * Find the rightmost child.
+		 * If this child is focusable, return it
+		 * If not focusable, traverse to its sibling and repeat.
+		 * If there is no sibling, traverse its parent.
+		 */
+		if (siblingPos != 0) {
+			IFigure child = 
+					findDeepestRightmostChildOf((IFigure)siblings.get(siblingPos - 1));
+			if (isFocusEligible(child)) {
+				found = true;
+				nextFocus = child;
+			} else if (child.equals(nextFocus)) {
+				if (isFocusEligible(nextFocus))
+					found = true;
+			} else
+				nextFocus = child;			
+		} else {
+			nextFocus = parent;
+				if (isFocusEligible(nextFocus))
+					found = true;
+		}
+	}
+	return nextFocus;
+}
+
+/**
+ * @return the figure that currently has focus
+ */
+public IFigure getCurrentFocusOwner() {
+	return currentFocusOwner;
+}	
+
+private boolean isFocusEligible(IFigure fig) {
+	return (fig != null && fig.isFocusTraversable() && fig.isShowing());
+}
+
+/**
+ * Sets the currently focused figure.
+ * @param fig the figure to get focus
+ */
+public void setCurrentFocusOwner(IFigure fig) {
+	currentFocusOwner = fig;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FrameBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FrameBorder.java
new file mode 100644
index 0000000..e2ee86c
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FrameBorder.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * Provides for a frame-like border which contains a title bar for holding the title of a 
+ * Figure.
+ */
+public class FrameBorder
+	extends CompoundBorder
+	implements LabeledBorder
+{
+
+/**
+ * The border scheme that determines the border highlight and shadow colors, as well as
+ * the border width (3).
+ */
+protected static final SchemeBorder.Scheme
+	SCHEME_FRAME = new SchemeBorder.Scheme(
+		new Color[] {
+						ColorConstants.button, 
+						ColorConstants.buttonLightest, 
+						ColorConstants.button
+					 },
+		new Color[] {	
+						ColorConstants.buttonDarkest, 
+						ColorConstants.buttonDarker, 
+						ColorConstants.button
+					 }
+	);
+
+{
+	createBorders();
+}
+
+/**
+ * Constructs a FrameBorder with its label set to the name of the {@link TitleBarBorder}
+ * class.
+ * 
+ * @since 2.0
+ */
+public FrameBorder() { }
+
+/**
+ * Constructs a FrameBorder with the title set to the passed String.
+ *
+ * @param label  label or title of the frame.
+ * @since 2.0
+ */
+public FrameBorder(String label) {
+	setLabel(label);
+}
+
+/**
+ * Creates the necessary borders for this FrameBorder. The inner border is a 
+ * {@link TitleBarBorder}. The outer border is a {@link SchemeBorder}.
+ * 
+ * @since 2.0
+ */
+protected void createBorders() {
+	inner = new TitleBarBorder();
+	outer = new SchemeBorder(SCHEME_FRAME);
+}
+
+/**
+ * Returns the inner border of this FrameBorder, which contains the label for the 
+ * FrameBorder.
+ *
+ * @return  the border holding the label.
+ * @since 2.0
+ */
+protected LabeledBorder getLabeledBorder() {
+	return (LabeledBorder)inner;
+}
+
+/**
+ * @return the label for this border
+ */
+public String getLabel() {
+	return getLabeledBorder().getLabel();
+}
+
+/**
+ * Sets the label for this border.
+ * @param label the label
+ */
+public void setLabel(String label) {
+	getLabeledBorder().setLabel(label);
+}
+
+/**
+ * Sets the font for this border's label.
+ * @param font the font
+ */
+public void setFont(Font font) {
+	getLabeledBorder().setFont(font);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformFigure.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformFigure.java
new file mode 100644
index 0000000..1626bf4
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformFigure.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A figure that allows its children to extend into negative coordinates.  This figure
+ * must be placed in a {@link org.eclipse.draw2d.FreeformViewport}.  Also, you shouldn't
+ * call {@link IFigure#setBounds(Rectangle)} on this figure.  The bounds will be 
+ * calculated based on the extent of its children.  A FreeformFigure's bounds will be the 
+ * smallest rectangle that will contain all of its children.
+ */
+public interface FreeformFigure
+	extends IFigure
+{
+
+/**
+ * Adds a FreeformListener to this FreeformFigure.
+ * @param listener the listener
+ */
+void addFreeformListener(FreeformListener listener);
+
+/**
+ * Notifies listeners that the freeform extent (i.e. bounds) has changed.
+ */
+void fireExtentChanged();
+
+/**
+ * Returns the freeform extent, essentially the bounds of the FreeformFigure.  This is
+ * based on the extent of its children.  
+ * @return the freeform extent
+ */
+Rectangle getFreeformExtent();
+
+/**
+ * Removes the given listener from this FreeformFigure.
+ * @param listener the listener
+ */
+void removeFreeformListener(FreeformListener listener);
+
+/**
+ * Sets the freeform bounds of this FreeformFigure.
+ * @param bounds the new freeform bounds
+ */
+void setFreeformBounds(Rectangle bounds);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformHelper.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformHelper.java
new file mode 100644
index 0000000..30b6d96
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformHelper.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.List;
+
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+class FreeformHelper
+	implements FreeformListener
+{
+
+class ChildTracker implements FigureListener {
+	public void figureMoved(IFigure source) {
+		invalidate();
+	}
+}
+
+private FreeformFigure host;
+private Rectangle freeformExtent;
+private FigureListener figureListener = new ChildTracker();
+
+FreeformHelper(FreeformFigure host) {
+	this.host = host;
+}
+
+public Rectangle getFreeformExtent() {
+	if (freeformExtent != null)
+		return freeformExtent;
+	Rectangle r;
+	List children = host.getChildren();
+	for (int i = 0; i < children.size(); i++) {
+		IFigure child = (IFigure)children.get(i);
+		if (child instanceof FreeformFigure)
+			r = ((FreeformFigure) child).getFreeformExtent();
+		else
+			r = child.getBounds();
+		if (freeformExtent == null)
+			freeformExtent = r.getCopy();
+		else
+			freeformExtent.union(r);
+	}
+	Insets insets = host.getInsets();
+	if (freeformExtent == null)
+		freeformExtent = new Rectangle(0, 0, insets.getWidth(), insets.getHeight());
+	else {
+		host.translateToParent(freeformExtent);
+		freeformExtent.expand(insets);
+	}
+//	System.out.println("New extent calculated for " + host + " = " + freeformExtent);
+	return freeformExtent;
+}
+
+public void hookChild(IFigure child) {
+	invalidate();
+	if (child instanceof FreeformFigure)
+		((FreeformFigure)child).addFreeformListener(this);
+	else
+		child.addFigureListener(figureListener);
+}
+
+void invalidate() {
+	freeformExtent = null;
+	host.fireExtentChanged();
+	if (host.getParent() != null)
+		host.getParent().revalidate();
+	else
+		host.revalidate();
+}
+
+public void notifyFreeformExtentChanged() {
+	//A childs freeform extent has changed, therefore this extent must be recalculated
+	invalidate();
+}
+
+public void setFreeformBounds(Rectangle bounds) {
+	host.setBounds(bounds);
+	bounds = bounds.getCopy();
+	host.translateFromParent(bounds);
+	List children = host.getChildren();
+	for (int i = 0; i < children.size(); i++) {
+		IFigure child = (IFigure)children.get(i);
+		if (child instanceof FreeformFigure)
+			((FreeformFigure) child).setFreeformBounds(bounds);
+	}
+}
+
+public void unhookChild(IFigure child) {
+	invalidate();
+	if (child instanceof FreeformFigure)
+		((FreeformFigure)child).removeFreeformListener(this);
+	else
+		child.removeFigureListener(figureListener);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayer.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayer.java
new file mode 100644
index 0000000..5379f47
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayer.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Iterator;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A Layer that can extend in all 4 directions.
+ */
+public class FreeformLayer
+	extends Layer
+	implements FreeformFigure
+{
+
+private FreeformHelper helper = new FreeformHelper(this);
+
+/**
+ * @see IFigure#add(IFigure, Object, int)
+ */
+public void add(IFigure child, Object constraint, int index) {
+	super.add(child, constraint, index);
+	helper.hookChild(child);
+}
+
+/**
+ * @see FreeformFigure#addFreeformListener(FreeformListener)
+ */
+public void addFreeformListener(FreeformListener listener) {
+	addListener(FreeformListener.class, listener);
+}
+
+/**
+ * @see FreeformFigure#fireExtentChanged()
+ */
+public void fireExtentChanged() {
+	Iterator iter = getListeners(FreeformListener.class);
+	while (iter.hasNext())
+		((FreeformListener)iter.next())
+			.notifyFreeformExtentChanged();
+}
+
+/**
+ * Overrides to do nothing.
+ * @see Figure#fireMoved()
+ */
+protected void fireMoved() { }
+
+/**
+ * @see FreeformFigure#getFreeformExtent()
+ */
+public Rectangle getFreeformExtent() {
+	return helper.getFreeformExtent();
+}
+
+/**
+ * @see Figure#primTranslate(int, int)
+ */
+public void primTranslate(int dx, int dy) {
+	bounds.x += dx;
+	bounds.y += dy;
+}
+
+/**
+ * @see IFigure#remove(IFigure)
+ */
+public void remove(IFigure child) {
+	helper.unhookChild(child);
+	super.remove(child);
+}
+
+/**
+ * @see FreeformFigure#removeFreeformListener(FreeformListener)
+ */
+public void removeFreeformListener(FreeformListener listener) {
+	removeListener(FreeformListener.class, listener);
+}
+
+/**
+ * @see FreeformFigure#setFreeformBounds(Rectangle)
+ */
+public void setFreeformBounds(Rectangle bounds) {
+	helper.setFreeformBounds(bounds);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayeredPane.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayeredPane.java
new file mode 100644
index 0000000..592f856
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayeredPane.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.Iterator;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A LayeredPane that contains {@link org.eclipse.draw2d.FreeformLayer FreeformLayers}.
+ */
+public class FreeformLayeredPane
+	extends LayeredPane
+	implements FreeformFigure
+{
+private FreeformHelper helper = new FreeformHelper(this);
+
+/**
+ * Constructs a new FreeformLayeredPane.
+ */
+public FreeformLayeredPane() {
+	setLayoutManager(null);
+}
+
+/**
+ * @see IFigure#add(IFigure, Object, int)
+ */
+public void add(IFigure child, Object constraint, int index) {
+	super.add(child, constraint, index);
+	helper.hookChild(child);
+}
+
+/**
+ * @see FreeformFigure#addFreeformListener(FreeformListener)
+ */
+public void addFreeformListener(FreeformListener listener) {
+	addListener(FreeformListener.class, listener);
+}
+
+/**
+ * @see FreeformFigure#fireExtentChanged()
+ */
+public void fireExtentChanged() {
+	Iterator iter = getListeners(FreeformListener.class);
+	while (iter.hasNext())
+		((FreeformListener)iter.next())
+			.notifyFreeformExtentChanged();
+}
+
+/**
+ * Overrides to do nothing.
+ * @see Figure#fireMoved()
+ */
+protected void fireMoved() { }
+
+/**
+ * Returns the FreeformHelper.
+ * @return the FreeformHelper
+ */
+protected FreeformHelper getFreeformHelper() {
+	return helper;
+}	
+
+/**
+ * @see FreeformFigure#getFreeformExtent()
+ */
+public Rectangle getFreeformExtent() {
+	return helper.getFreeformExtent();
+}
+
+/**
+ * @see Figure#primTranslate(int, int)
+ */
+protected void primTranslate(int dx, int dy) {
+	bounds.x += dx;
+	bounds.y += dy;
+}
+
+/**
+ * @see IFigure#remove(IFigure)
+ */
+public void remove(IFigure child) {
+	helper.unhookChild(child);
+	super.remove(child);
+}
+
+/**
+ * @see FreeformFigure#removeFreeformListener(FreeformListener)
+ */
+public void removeFreeformListener(FreeformListener listener) {
+	removeListener(FreeformListener.class, listener);
+}
+
+/**
+ * @see FreeformFigure#setFreeformBounds(Rectangle)
+ */
+public void setFreeformBounds(Rectangle bounds) {
+	helper.setFreeformBounds(bounds);
+}
+
+/**
+ * Calls {@link Figure#fireMoved() super.fireMoved()}.
+ */
+protected void superFireMoved() {
+	super.fireMoved();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayout.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayout.java
new file mode 100644
index 0000000..984bd34
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformLayout.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+/**
+ * A layout for {@link org.eclipse.draw2d.FreeformFigure FreeformFigures}.
+ */
+public class FreeformLayout
+	extends XYLayout
+{
+
+/**
+ * Returns the point (0,0) as the origin.
+ * @see XYLayout#getOrigin(IFigure)
+ */
+public Point getOrigin(IFigure figure) {
+	return new Point();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformListener.java
new file mode 100644
index 0000000..fb74554
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformListener.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * Listens for extent changes in {@link org.eclipse.draw2d.FreeformFigure FreeformFigures}.
+ * Created on :Oct 4, 2002
+ * @author hudsonr
+ * @since 2.0
+ */
+public interface FreeformListener {
+
+/**
+ * Called when the extent of the FreeformFigure has changed.
+ */
+void notifyFreeformExtentChanged();
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformViewport.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformViewport.java
new file mode 100644
index 0000000..feb0db9
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FreeformViewport.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A viewport for {@link org.eclipse.draw2d.FreeformFigure FreeformFigures}.  
+ * FreeformFigures can only reside in this type of viewport.
+ */
+public class FreeformViewport
+	extends Viewport
+{
+
+class FreeformViewportLayout
+	extends ViewportLayout
+{
+	protected Dimension calculatePreferredSize(IFigure parent, int wHint, int hHint) {
+		getContents().validate();
+		wHint = Math.max(0, wHint);
+		hHint = Math.max(0, hHint);
+		return ((FreeformFigure)getContents())
+			.getFreeformExtent()
+			.getExpanded(getInsets())
+			.union(0, 0)
+			.union(wHint - 1, hHint - 1)
+			.getSize();
+	}
+
+	protected boolean isSensitiveHorizontally(IFigure parent) {
+		return true;
+	}
+
+	protected boolean isSensitiveVertically(IFigure parent) {
+		return true;
+	}
+
+
+	public void layout(IFigure figure) {
+		//Do nothing, contents updates itself.
+	}
+}
+
+/**
+ * Constructs a new FreeformViewport.  This viewport must use graphics translation to 
+ * scroll the FreeformFigures inside of it.
+ */
+public FreeformViewport() {
+	super(true); //Must use graphics translate to scroll freeforms.
+	setLayoutManager(new FreeformViewportLayout());
+}
+
+/**
+ * Readjusts the scrollbars.  In doing so, it gets the freeform extent of the contents and
+ * unions this rectangle with this viewport's client area, then sets the contents freeform
+ * bounds to be this unioned rectangle.  Then proceeds to set the scrollbar values based
+ * on this new information.
+ * @see Viewport#readjustScrollBars()
+ */
+protected void readjustScrollBars() {
+	if (getContents() == null)
+		return;
+	if (!(getContents() instanceof FreeformFigure))
+		return;
+	FreeformFigure ff = (FreeformFigure)getContents();
+	Rectangle clientArea = getClientArea();
+	Rectangle bounds = ff.getFreeformExtent().getCopy();
+	bounds.union(0, 0, clientArea.width, clientArea.height);
+	ff.setFreeformBounds(bounds);
+
+	getVerticalRangeModel().setAll(bounds.y, clientArea.height, bounds.bottom());
+	getHorizontalRangeModel().setAll(bounds.x, clientArea.width, bounds.right());
+}
+
+/**
+ * Returns <code>true</code>.
+ * @see Figure#useLocalCoordinates()
+ */
+protected boolean useLocalCoordinates() {
+	return true;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Graphics.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Graphics.java
new file mode 100644
index 0000000..843b044
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Graphics.java
@@ -0,0 +1,929 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Path;
+import org.eclipse.swt.graphics.Pattern;
+import org.eclipse.swt.graphics.TextLayout;
+
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * The Graphics class allows you to draw to a surface.  The drawXxx() methods that pertain 
+ * to shapes draw an outline of the shape, whereas the fillXxx() methods fill in the shape.
+ * Also provides for drawing text, lines and images.
+ */
+public abstract class Graphics {
+
+/**
+ * @see SWT#LINE_CUSTOM
+ */
+public static final int LINE_CUSTOM = SWT.LINE_CUSTOM;
+
+/**
+ * @see SWT#LINE_DASH
+ */
+public static final int LINE_DASH = SWT.LINE_DASH;
+
+/**
+ * @see SWT#LINE_DASHDOT
+ */
+public static final int LINE_DASHDOT = SWT.LINE_DASHDOT;
+
+/**
+ * @see SWT#LINE_DASHDOTDOT
+ */
+public static final int LINE_DASHDOTDOT = SWT.LINE_DASHDOTDOT;
+
+/**
+ * @see SWT#LINE_DOT
+ */
+public static final int LINE_DOT = SWT.LINE_DOT;
+
+/**
+ * @see SWT#LINE_SOLID
+ */
+public static final int LINE_SOLID = SWT.LINE_SOLID;
+
+/**
+ * Sets the clip region to the given rectangle.  Anything outside this rectangle will not
+ * be drawn.
+ * @param r the clip rectangle
+ */
+public abstract void clipRect(Rectangle r);
+
+/**
+ * Disposes this object, releasing any resources.
+ */
+public abstract void dispose();
+
+/**
+ * Draws the outline of an arc located at (x,y) with width <i>w</i> and height <i>h</i>. 
+ * The starting angle of the arc (specified in degrees) is <i>offset</i> and <i>length</i>
+ * is the arc's angle (specified in degrees).
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param offset the start angle
+ * @param length the length of the arc
+ */
+public abstract void drawArc(int x, int y, int w, int h, int offset, int length);
+
+/**
+ * @see #drawArc(int, int, int, int, int, int)
+ */
+public final void drawArc(Rectangle r, int offset, int length) {
+	drawArc(r.x, r.y, r.width, r.height, offset, length);
+}
+
+/**
+ * Draws a focus rectangle.
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+public abstract void drawFocus(int x, int y, int w, int h);
+
+/**
+ * @see #drawFocus(int, int, int, int)
+ */
+public final void drawFocus(Rectangle r) {
+	drawFocus(r.x, r.y, r.width, r.height);
+}
+
+/**
+ * Draws the given Image at the location (x,y).
+ * @param srcImage the Image
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+public abstract void drawImage(Image srcImage, int x, int y);
+
+/**
+ * Draws a rectangular section of the given Image to the specified rectangular reagion on
+ * the canvas.  The section of the image bounded by the rectangle (x1,y1,w1,h1) is copied
+ * to the section of the canvas bounded by the rectangle (x2,y2,w2,h2).  If these two 
+ * sizes are different, scaling will occur.
+ * 
+ * @param srcImage the image
+ * @param x1 the x coordinate of the source
+ * @param y1 the y coordinate of the source
+ * @param w1 the width of the source
+ * @param h1 the height of the source
+ * @param x2 the x coordinate of the destination
+ * @param y2 the y coordinate of the destination
+ * @param w2 the width of the destination
+ * @param h2 the height of the destination
+ */
+public abstract void drawImage(Image srcImage, int x1, int y1, int w1, int h1, 
+													int x2, int y2, int w2, int h2);
+
+/**
+ * Draws the given image at a point.
+ * @param image the image to draw
+ * @param p where to draw the image
+ * @see #drawImage(Image, int, int)
+ */
+public final void drawImage(Image image, Point p) {
+	drawImage(image, p.x, p.y);
+}
+
+/**
+ * @see #drawImage(Image, int, int, int, int, int, int, int, int)
+ */
+public final void drawImage(Image srcImage, Rectangle src, Rectangle dest) {
+	drawImage(srcImage, src.x, src.y, src.width, src.height, 
+						dest.x, dest.y, dest.width, dest.height);
+}
+
+/**
+ * Draws a line between the points <code>(x1,y1)</code> and <code>(x2,y2)</code> using the
+ * foreground color.
+ * @param x1 the x coordinate for the first point
+ * @param y1 the y coordinate for the first point
+ * @param x2 the x coordinate for the second point
+ * @param y2 the y coordinate for the second point
+ */
+public abstract void drawLine(int x1, int y1, int x2, int y2);
+
+/**
+ * @see #drawLine(int, int, int, int)
+ */
+public final void drawLine(Point p1, Point p2) {
+	drawLine(p1.x, p1.y, p2.x, p2.y);
+}
+
+/**
+ * Draws the outline of an ellipse that fits inside the rectangle with the given
+ * properties using the foreground color.
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+public abstract void drawOval(int x, int y, int w, int h);
+
+/**
+ * Draws an oval inside the given rectangle using the current foreground color.
+ * @param r the rectangle circumscribing the oval to be drawn
+ * @see #drawOval(int, int, int, int)
+ */
+public final void drawOval(Rectangle r) {
+	drawOval(r.x, r.y, r.width, r.height);
+}
+
+/**
+ * Draws the given path.
+ * @param path the path to draw
+ * @since 3.1
+ */
+public void drawPath(Path path) {
+	subclassFunctionMission();
+}
+
+/** 
+ * Draws a pixel, using the foreground color, at the specified point (<code>x</code>,
+ * <code>y</code>).
+ * <p>
+ * Note that the current line attributes do not affect this
+ * operation.
+ * </p>
+ *
+ * @param x the point's x coordinate
+ * @param y the point's y coordinate 
+ * 
+ */
+public void drawPoint(int x, int y) {
+	drawLine(x, y, x, y);
+}
+
+/**
+ * Draws a closed polygon defined by the given Integer array containing the vertices in
+ * x,y order.  The first and last points in the list will be connected.
+ * @param points the vertices
+ */
+public void drawPolygon(int[] points) {
+	drawPolygon(getPointList(points));
+}
+
+/**
+ * Draws a closed polygon defined by the given <code>PointList</code> containing the 
+ * vertices.  The first and last points in the list will be connected.
+ * @param points the vertices
+ */
+public abstract void drawPolygon(PointList points);
+
+/**
+ * Draws a polyline defined by the given Integer array containing the vertices in x,y
+ * order. The first and last points in the list will <b>not</b> be connected.
+ * @param points the vertices
+ */
+public void drawPolyline(int[] points) {
+	drawPolyline(getPointList(points));
+}
+
+/**
+ * Draws a polyline defined by the given <code>PointList</code> containing the vertices.
+ * The first and last points in the list will <b>not</b> be connected.
+ * @param points the vertices
+ */
+public abstract void drawPolyline(PointList points);
+
+/**
+ * Draws a rectangle whose top-left corner is located at the point (x,y) with the given 
+ * width and height.
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param width the width
+ * @param height the height
+ */
+public abstract void drawRectangle(int x, int y, int width, int height);
+
+/**
+ * Draws the given rectangle using the current foreground color.
+ * @param r the rectangle to draw
+ * @see #drawRectangle(int, int, int, int)
+ */
+public final void drawRectangle(Rectangle r) {
+	drawRectangle(r.x, r.y, r.width, r.height);
+}
+
+/**
+ * Draws a rectangle with rounded corners using the foreground color.  <i>arcWidth</i> and
+ * <i>arcHeight</i> represent the horizontal and vertical diameter of the corners.
+ * 
+ * @param r the rectangle
+ * @param arcWidth the arc width
+ * @param arcHeight the arc height
+ */
+public abstract void drawRoundRectangle(Rectangle r, int arcWidth, int arcHeight);
+
+/**
+ * Draws the given string using the current font and foreground color. No tab expansion or 
+ * carriage return processing will be performed. The background of the string will be
+ * transparent.
+ * 
+ * @param s the string
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+public abstract void drawString(String s, int x, int y);
+
+/**
+ * @see #drawString(String, int, int)
+ */
+public final void drawString(String s, Point p) {
+	drawString(s, p.x, p.y);
+}
+
+
+/**
+ * Draws the given string using the current font and foreground color. Tab expansion and 
+ * carriage return processing are performed. The background of the text will be
+ * transparent.
+ * 
+ * @param s the text
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+public abstract void drawText(String s, int x, int y);
+
+/**
+ * Draws a string using the specified styles. The styles are defined by {@link
+ * GC#drawText(String, int, int, int)}.
+ * @param s the String to draw
+ * @param x the x location
+ * @param y the y location
+ * @param style the styles used to render the string
+ * @since 3.0
+ */
+public void drawText(String s, int x, int y, int style) {
+	subclassFunctionMission();
+}
+
+/**
+ * @see #drawText(String, int, int)
+ */
+public final void drawText(String s, Point p) {
+	drawText(s, p.x, p.y);
+}
+
+/**
+ * Draws a string using the specified styles. The styles are defined by {@link
+ * GC#drawText(String, int, int, int)}.
+ * @param s the String to draw
+ * @param p the point at which to draw the string
+ * @param style the styles used to render the string
+ * @since 3.0
+ */
+public final void drawText(String s, Point p, int style) {
+	drawText(s, p.x, p.y, style);
+}
+
+/**
+ * Renders the specified TextLayout to this Graphics.
+ * @since 3.0
+ * @param layout the TextLayout
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+public final void drawTextLayout(TextLayout layout, int x, int y) {
+	drawTextLayout(layout, x, y, -1, -1, null, null);
+}
+
+/**
+ * @param x the x location
+ * @param y the y location
+ * @param layout the TextLayout being rendered
+ * @param selectionStart the start of selection
+ * @param selectionEnd the end of selection
+ * @param selectionForeground the foreground selection color
+ * @param selectionBackground the background selection color
+ * @see Graphics#drawTextLayout(TextLayout, int, int)
+ */
+public void drawTextLayout(TextLayout layout, int x, int y, int selectionStart,
+		int selectionEnd, Color selectionForeground, Color selectionBackground) {
+	subclassFunctionMission();
+}
+
+/**
+ * Fills the interior of an arc located at (<i>x</i>,<i>y</i>) with width <i>w</i> and 
+ * height <i>h</i>. The starting angle of the arc (specified in degrees) is <i>offset</i>
+ * and <i>length</i> is the arc's angle (specified in degrees).
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param offset the start angle
+ * @param length the length of the arc
+ */
+public abstract void fillArc(int x, int y, int w, int h, int offset, int length);
+
+/**
+ * @see #fillArc(int, int, int, int, int, int)
+ */
+public final void fillArc(Rectangle r, int offset, int length) {
+	fillArc(r.x, r.y, r.width, r.height, offset, length);
+}
+
+/**
+ * Fills the the given rectangle with a gradient from the foreground color to the 
+ * background color. If <i>vertical</i> is <code>true</code>, the gradient will go from 
+ * top to bottom.  Otherwise, it will go from left to right.
+ * background color.
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ * @param vertical whether the gradient should be vertical
+ */
+public abstract void fillGradient(int x, int y, int w, int h, boolean vertical);
+
+/**
+ * @see #fillGradient(int, int, int, int, boolean)
+ */
+public final void fillGradient(Rectangle r, boolean vertical) {
+	fillGradient(r.x, r.y, r.width, r.height, vertical);
+}
+
+/**
+ * Fills an ellipse that fits inside the rectangle with the given properties using the 
+ * background color.
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param w the width
+ * @param h the height
+ */
+public abstract void fillOval(int x, int y, int w, int h);
+
+/**
+ * @see #fillOval(int, int, int, int)
+ */
+public final void fillOval(Rectangle r) {
+	fillOval(r.x, r.y, r.width, r.height);
+}
+
+/**
+ * Fills the given path.
+ * @param path the path to fill
+ * @since 3.1
+ */
+public void fillPath(Path path) {
+	subclassFunctionMission();
+}
+
+/**
+ * Fills a closed polygon defined by the given Integer array containing the 
+ * vertices in x,y order.  The first and last points in the list will be connected.
+ * @param points the vertices
+ */
+public void fillPolygon(int[] points) {
+	fillPolygon(getPointList(points));
+}
+
+/**
+ * Fills a closed polygon defined by the given <code>PointList</code> containing the 
+ * vertices.  The first and last points in the list will be connected.
+ * @param points the vertices
+ */
+public abstract void fillPolygon(PointList points);
+
+/**
+ * Fills a rectangle whose top-left corner is located at the point (x,y) with the given
+ * width and height.
+ * 
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param width the width
+ * @param height the height
+ */
+public abstract void fillRectangle(int x, int y, int width, int height);
+
+/**
+ * Fills the given rectangle using the current background color.
+ * @param r the rectangle to fill
+ * @see #fillRectangle(int, int, int, int)
+ */
+public final void fillRectangle(Rectangle r) {
+	fillRectangle(r.x, r.y, r.width, r.height);
+}
+
+/**
+ * Fills a rectangle with rounded corners using the background color.  <i>arcWidth</i> and
+ * <i>arcHeight</i> represent the horizontal and vertical diameter of the corners.
+ * 
+ * @param r the rectangle
+ * @param arcWidth the arc width
+ * @param arcHeight the arc height
+ */
+public abstract void fillRoundRectangle(Rectangle r, int arcWidth, int arcHeight);
+
+/**
+ * Draws the given string using the current font and foreground color. No tab expansion or 
+ * carriage return processing will be performed. The background of the string will be
+ * filled with the current background color.
+ * 
+ * @param s the string
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+public abstract void fillString(String s, int x, int y);
+
+/**
+ * @see #fillString(String, int, int)
+ */
+public final void fillString(String s, Point p) {
+	fillString(s, p.x, p.y);
+}
+
+/**
+ * Draws the given string using the current font and foreground color. Tab expansion and 
+ * carriage return processing are performed. The background of the text will be filled
+ * with the current background color.
+ * 
+ * @param s the text
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+public abstract void fillText(String s, int x, int y);
+
+/**
+ * @see #fillText(String, int, int)
+ */
+public final void fillText(String s, Point p) {
+	fillText(s, p.x, p.y);
+}
+
+/**
+ * Returns the current absolute scaling which will be applied to the underlying Device
+ * when painting to this Graphics.  The default value is 1.0.
+ * @since 3.0
+ * @return the effective absolute scaling factor
+ */
+public double getAbsoluteScale() {
+	return 1.0;
+}
+
+/**
+ * Returns the current alpha value of the graphics.
+ * @return the alpha value
+ * @since 3.1
+ */
+public int getAlpha() {
+	subclassFunctionMission();
+	return 255;
+}
+
+/**
+ * Returns the anti-aliasing setting value, which will be one of <code>SWT.DEFAULT</code>,
+ * <code>SWT.OFF</code> or <code>SWT.ON</code>. Note that this controls anti-aliasing for
+ * all <em>non-text</em> drawing operations.
+ * @see #getTextAntialias()
+ * @return the anti-alias setting
+ * @since 3.1
+ */
+public int getAntialias() {
+	subclassFunctionMission();
+	return SWT.DEFAULT;
+}
+
+/**
+ * Returns the background color used for filling.
+ * @return the background color
+ */
+public abstract Color getBackgroundColor();
+
+/**
+ * Modifies the given rectangle to match the clip region and returns that rectangle.
+ * @param rect the rectangle to hold the clip region
+ * @return the clip rectangle
+ */
+public abstract Rectangle getClip(Rectangle rect);
+
+/**
+ * Returns the fill rule, which will be one of <code>SWT.FILL_EVEN_ODD</code> or
+ * <code>SWT.FILL_WINDING</code>.
+ * @return the fill rule
+ * @since 3.1
+ */
+public int getFillRule() {
+	subclassFunctionMission();
+	return 0;
+}
+
+/**
+ * Returns the font used to draw and fill text.
+ * @return the font
+ */
+public abstract Font getFont();
+
+/**
+ * Returns the font metrics for the current font.
+ * @return the font metrics
+ */
+public abstract FontMetrics getFontMetrics();
+
+/**
+ * Returns the foreground color used to draw lines and text.
+ * @return the foreground color
+ */
+public abstract Color getForegroundColor();
+
+/**
+ * Returns the interpolation setting, which will be one of <code>SWT.DEFAULT</code>,
+ * <code>SWT.NONE</code>, <code>SWT.LOW</code> or <code>SWT.HIGH</code>.
+ * @return the interpolation setting
+ * @since 3.1
+ */
+public int getInterpolation() {
+	subclassFunctionMission();
+	return 0;
+}
+
+/**
+ * Returns the current line cap style, which will be one of the constants
+ * <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>, or <code>SWT.CAP_SQUARE</code>.
+ * 
+ * @return the cap style used for drawing lines
+ * @since 3.1
+ */
+public int getLineCap() {
+	subclassFunctionMission();
+	return SWT.CAP_FLAT;
+}
+
+
+/** 
+ * Returns the line join style, which will be one of the constants
+ * <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>, or
+ * <code>SWT.JOIN_BEVEL</code>.
+ * 
+ * @since 3.1
+ * @return the join style used for drawing lines
+ */
+public int getLineJoin() {
+	subclassFunctionMission();
+	return SWT.JOIN_MITER;
+}
+
+/**
+ * Returns the line style.
+ * @return the line style
+ */
+public abstract int getLineStyle();
+/**
+ * Returns the current line width.
+ * @return the line width
+ */
+public abstract int getLineWidth();
+
+/**
+ * Returns a pointlist containing all the points from the integer array.
+ * @param points an integer array of x,y points
+ * @return the corresponding pointlist
+ */
+private PointList getPointList(int[] points) {
+	PointList pointList = new PointList(points.length / 2);
+	for (int i = 0; (i + 1) < points.length; i += 2)
+		pointList.addPoint(points[i], points[i + 1]);
+	return pointList;
+}
+
+/**
+ * Returns the textual anti-aliasing setting value, which will be one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or <code>SWT.ON</code>. Note that this
+ * controls anti-aliasing <em>only</em> for text drawing operations.
+ *
+ * @see #getAntialias()
+ * @return the anti-aliasing setting
+ * @since 3.1
+ */
+public int getTextAntialias() {
+	subclassFunctionMission();
+	return SWT.DEFAULT;
+}
+
+/**
+ * Returns <code>true</code> if this graphics object should use XOR mode with painting.
+ * @return whether XOR mode is turned on
+ */
+public abstract boolean getXORMode();
+
+/**
+ * Pops the previous state of this graphics object off the stack (if {@link #pushState()} 
+ * has previously been called) and restores the current state to that popped state.
+ */
+public abstract void popState();
+
+/**
+ * Pushes the current state of this graphics object onto a stack.
+ */
+public abstract void pushState();
+
+/**
+ * Restores the previous state of this graphics object.
+ */
+public abstract void restoreState();
+
+/**
+ * Rotates the coordinates by the given counter-clockwise angle. All subsequent painting
+ * will be performed in the resulting coordinates. Some functions are illegal when a
+ * rotated coordinates system is in use.  To restore access to those functions, it is
+ * necessary to call restore or pop to return to a non rotated state.
+ * @param degrees the degrees to rotate
+ * @since 3.1
+ */
+public void rotate(float degrees) {
+	subclassFunctionMission();
+}
+
+/**
+ * Scales this graphics object by the given amount.
+ * @param amount the scale factor
+ */
+public abstract void scale(double amount);
+
+/**
+ * Scales the graphics by the given horizontal and vertical components.
+ * @param horizontal the horizontal scaling factor
+ * @param vertical the vertical scaling factor
+ * @since 3.1
+ */
+public void scale(float horizontal, float vertical) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the alpha to the given value.  Values may range from 0 to 255.  A value
+ * of 0 is completely transparent.
+ * 
+ * @param alpha an alpha value (0-255)
+ * @since 3.1
+ */
+public void setAlpha(int alpha) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the anti-aliasing value to the parameter, which must be one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or <code>SWT.ON</code>. Note that this
+ * controls anti-aliasing for all <em>non-text drawing</em> operations.
+ * 
+ * @param value the anti-alias value
+ */
+public void setAntialias(int value) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the background color.
+ * @param rgb the new background color
+ */
+public abstract void setBackgroundColor(Color rgb);
+
+/**
+ * Sets the pattern used for fill-type graphics operations. The pattern must not be
+ * disposed while it is being used by the graphics.
+ * @param pattern the background pattern
+ * @since 3.1
+ */
+public void setBackgroundPattern(Pattern pattern) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the area which can be affected by drawing operations to the specified
+ * <code>Path</code>.
+
+ * @param path the clipping path
+ * @since 3.1
+ */
+public void setClip(Path path) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the clip rectangle. Painting will <b>not</b> occur outside this area.
+ * @param r the new clip rectangle
+ */
+public abstract void setClip(Rectangle r);
+
+/**
+ * Sets the fill rule to the given value, which must be one of
+ * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>.
+ * @param rule the fill rule
+ * @since 3.1
+ */
+public void setFillRule(int rule) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the font.
+ * @param f the new font
+ */
+public abstract void setFont(Font f);
+
+/**
+ * Sets the foreground color.
+ * @param rgb the new foreground color
+ */
+public abstract void setForegroundColor(Color rgb);
+
+/**
+ * Sets the foreground pattern for draw and text operations. The pattern must not be
+ * disposed while it is being referenced by the graphics.
+ * @param pattern the foreground pattern
+ * @since 3.1
+ */
+public void setForegroundPattern(Pattern pattern) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the interpolation setting to the given value, which must be one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>,  <code>SWT.LOW</code> or
+ * <code>SWT.HIGH</code>. This setting is relevant when working with Images.
+ * @param interpolation the interpolation
+ * @since 3.1
+ */
+public void setInterpolation(int interpolation) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the line cap style to the argument, which must be one of the constants
+ * <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>, or <code>SWT.CAP_SQUARE</code>.
+ * @param cap the line cap
+ * @since 3.1
+ */
+public void setLineCap(int cap) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the dash pattern when the custom line style is in use. Because this
+ * feature is rarely used, the dash pattern may not be preserved when calling
+ * {@link #pushState()} and {@link #popState()}.
+ * @param dash the pixel pattern
+ * @since 3.1
+ */
+public void setLineDash(int dash[]) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the line join style to the argument, which must be one of the constants
+ * <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>, or
+ * <code>SWT.JOIN_BEVEL</code>.
+ * @param join the join type
+ * @since 3.1
+ */
+public void setLineJoin(int join) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the line style to the argument, which must be one of the constants
+ * <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>, <code>SWT.LINE_DOT</code>,
+ * <code>SWT.LINE_DASHDOT</code> or <code>SWT.LINE_DASHDOTDOT</code>.
+ * @param style the new style
+ */
+public abstract void setLineStyle(int style);
+
+/**
+ * Sets the line width.
+ * 
+ * @param width the new width
+ */
+public abstract void setLineWidth(int width);
+
+/**
+ * Sets the textual anti-aliasing value to the parameter, which must be one of
+ * <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or <code>SWT.ON</code>. Note that this
+ * controls anti-aliasing only for all <em>text drawing</em> operations.
+ * 
+ * @param value the textual anti-alias setting
+ * @since 3.1
+ */
+public void setTextAntialias(int value) {
+	subclassFunctionMission();
+}
+
+/**
+ * Modifies the current transformation by shearing the graphics in the specified
+ * horizontal and vertical amounts. Shearing can be used to produce effects like Italic
+ * fonts.
+ * @param horz the horizontal shearing amount
+ * @param vert the vertical shearming amount
+ * @since 3.1
+ */
+public void shear(float horz, float vert) {
+	subclassFunctionMission();
+}
+
+/**
+ * Sets the XOR mode.
+ * @param b the new XOR mode
+ */
+public abstract void setXORMode(boolean b);
+
+private void subclassFunctionMission() {
+	throw new RuntimeException("The class: " + getClass() //$NON-NLS-1$
+			+ " has not implemented this new graphics function"); //$NON-NLS-1$
+}
+
+/**
+ * Translates the receiver's coordinates by the specified x and y amounts. All
+ * subsequent painting will be performed in the resulting coordinate system. Integer
+ * translation used by itself does not require or start the use of the advanced
+ * graphics system in SWT. It is emulated until advanced graphics are triggered.
+ * @param dx the horizontal offset
+ * @param dy the vertical offset
+ */
+public abstract void translate(int dx, int dy);
+
+
+/**
+ * Modifies the current transform by translating the given x and y amounts. All
+ * subsequent painting will be performed in the resulting coordinate system.
+ * @param dx the horizontal offset
+ * @param dy the vertical offset
+ */
+public void translate(float dx, float dy) {
+	subclassFunctionMission();
+}
+
+/**
+ * @see #translate(int, int)
+ */
+public final void translate(Point pt) {
+	translate(pt.x, pt.y);
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/GraphicsSource.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/GraphicsSource.java
new file mode 100644
index 0000000..6f8b6f8
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/GraphicsSource.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * Provides a {@link org.eclipse.draw2d.Graphics} object for painting.
+ */
+public interface GraphicsSource {
+
+/**
+ * Returns a Graphics for the rectangular region requested. May return <code>null</code>.
+ * @param region The rectangular region
+ * @return A new Graphics object for the given region
+ */
+Graphics getGraphics(Rectangle region);
+
+/**
+ * Tells the GraphicsSource that you have finished using that region.
+ * @param region The rectangular region that that no longer needs the Graphics
+ */
+void flushGraphics(Rectangle region);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/GroupBoxBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/GroupBoxBorder.java
new file mode 100644
index 0000000..b919bb4
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/GroupBoxBorder.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A labeled border intended to house a Figure with a group of children. The label should 
+ * serve as a description of the group.
+ */
+public class GroupBoxBorder
+	extends AbstractLabeledBorder
+{
+
+/**
+ * Constructs a GroupBoxBorder with the name of this class as its label.
+ * 
+ * @since 2.0
+ */
+public GroupBoxBorder() { }
+
+/**
+ * Constructs a GroupBoxBorder with label s.
+ * 
+ * @param s the label
+ * @since 2.0
+ */
+public GroupBoxBorder(String s) {
+	super(s);
+}
+
+/**
+ * Calculates and returns the Insets for this GroupBoxBorder.
+ *
+ * @param figure   IFigure on which the calculations should be made. Generally this is 
+ * 					the IFigure of which this GroupBoxBorder is surrounding.
+ * @return  the Insets for this GroupBoxBorder. 
+ * @since 2.0
+ */
+protected Insets calculateInsets(IFigure figure) {
+	int height = getTextExtents(figure).height;
+	return new Insets(height);
+}
+
+/**
+ * @see org.eclipse.draw2d.Border#getPreferredSize(IFigure)
+ */
+public Dimension getPreferredSize(IFigure fig) {
+	Dimension textSize = getTextExtents(fig);
+	return textSize.getCopy().expand(textSize.height * 2, 0);
+}
+
+/**
+ * @see Border#paint(IFigure, Graphics, Insets)
+ */
+public void paint(IFigure figure, Graphics g, Insets insets) {
+	tempRect.setBounds(getPaintRectangle(figure, insets));
+	Rectangle r = tempRect;
+	if (r.isEmpty())
+		return;
+
+	Rectangle textLoc = new Rectangle(r.getTopLeft(), getTextExtents(figure));
+	r.crop(new Insets(getTextExtents(figure).height / 2));
+	FigureUtilities.paintEtchedBorder(g, r);
+
+	textLoc.x += getInsets(figure).left;
+	g.setFont(getFont(figure));
+	g.setForegroundColor(getTextColor());
+	g.clipRect(textLoc);
+	g.fillText(getLabel(), textLoc.getTopLeft());
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/IFigure.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/IFigure.java
new file mode 100644
index 0000000..7c6dc75
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/IFigure.java
@@ -0,0 +1,885 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.beans.PropertyChangeListener;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.draw2d.geometry.Translatable;
+
+/**
+ * A lightweight graphical object.  Figures are rendered to a {@link Graphics}  object.
+ * Figures can be composed to create complex graphics.
+ * 
+ * <P>
+ * WARNING: This interface is not intended to be implemented by clients.
+ */
+public interface IFigure {
+
+/**
+ * Insets that are all 0.  Always returns <code>true<code> for {@link #isEmpty()}.
+ */
+class NoInsets
+	extends Insets
+{
+	NoInsets() {
+		super(0, 0, 0, 0);
+	}
+	public boolean isEmpty() {
+		return true;
+	}
+}
+
+/**
+ * The maximum allowable dimension. ({@link Integer#MAX_VALUE},{@link Integer#MAX_VALUE})
+ */
+Dimension MAX_DIMENSION = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+/**
+ * The minimum allowable dimension. (5,5)
+ */
+Dimension MIN_DIMENSION = new Dimension(5, 5);
+
+/**
+ * Empty Insets.
+ */
+Insets NO_INSETS = new NoInsets();
+
+/**
+ * Adds the given IFigure as a child of this IFigure.  The same as calling {@link
+ * #add(IFigure, Object, int) add(figure, null, -1)}.
+ * @param figure The IFigure to add
+ */
+void add(IFigure figure);
+
+/**
+ * Adds the given IFigure as a child of this IFigure at the given index.  The same as
+ * calling {@link #add(IFigure, Object, int) add(figure, null, index)}.
+ * @param figure The IFigure to add
+ * @param index The index where the IFigure should be added
+ */
+void add(IFigure figure, int index);
+
+/**
+ * Adds the given IFigure as a child of this IFigure with the given constraint.  The same
+ * as calling {@link #add(IFigure, Object, int) add(figure, constraint, -1)}.
+ * @param figure The IFigure to add
+ * @param constraint The newly added IFigure's constraint
+ */
+void add(IFigure figure, Object constraint);
+
+/**
+ * Adds the child with the specified index and constraint. The child's parent is currently
+ * not null, it is removed from that parent.  If this figure has a LayoutManager, then
+ * {@link LayoutManager#setConstraint(IFigure, Object)} shall be called on the layout.
+ * @param figure The IFigure to add
+ * @param constraint The newly added IFigure's constraint
+ * @param index The index where the IFigure should be added
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws IllegalArgumentException if adding the child creates a cycle
+ */
+void add(IFigure figure, Object constraint, int index);
+
+/**
+ * Registers the given listener as an AncestorListener of this figure.
+ * @param listener The listener to add
+ */
+void addAncestorListener(AncestorListener listener);
+
+/**
+ * Registers the given listener as a CoordinateListener of this figure.
+ * @param listener the listener to add
+ * @since 3.1
+ */
+void addCoordinateListener(CoordinateListener listener);
+
+/**
+ * Registers the given listener as a FigureListener of this figure.
+ * @param listener The listener to add
+ */
+void addFigureListener(FigureListener listener);
+
+/**
+ * Registers the given listener as a FocusListener of this figure.
+ * @param listener The listener to add
+ */
+void addFocusListener(FocusListener listener);
+
+/**
+ * Registers the given listener as a KeyListener of this figure.
+ * @param listener The listener to add
+ */
+void addKeyListener(KeyListener listener);
+
+/**
+ * Registers the given listener on this figure. 
+ * @param listener The listener to add
+ * @since 3.1
+ */
+void addLayoutListener(LayoutListener listener);
+
+/**
+ * Registers the given listener as a MouseListener of this IFigure.
+ * @param listener The listener to add
+ */
+void addMouseListener(MouseListener listener);
+
+/**
+ * Registers the given listener as a MouseMotionListener of this IFigure.
+ * @param listener The listener to add
+ */
+void addMouseMotionListener(MouseMotionListener listener);
+
+/**
+ * Called after this IFigure is added to its parent.
+ */
+void addNotify();
+
+/**
+ * Registers the given listener as a PropertyChangeListener of this IFigure.
+ * @param listener The listener to add
+ */
+void addPropertyChangeListener(PropertyChangeListener listener);
+
+/**
+ * Registers the given listener as a PropertyChangeListener of this IFigure, interested
+ * only in the given property.
+ * @param property The property the listener is interested in
+ * @param listener The listener to add
+ */
+void addPropertyChangeListener(String property, PropertyChangeListener listener);
+
+/**
+ * Returns <code>true</code> if the point <code>(x, y)</code> is contained within this
+ * IFigure's bounds.
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return <code>true</code> if the point (x,y) is contained in this IFigure's bounds
+ */
+boolean containsPoint(int x, int y);
+
+/**
+ * Returns <code>true</code> if the Point p is contained within this IFigure's bounds.
+ * @param p The point
+ * @return <code>true</code> if the Point p is contained within this IFigure's bounds
+ */
+boolean containsPoint(Point p);
+
+/**
+ * Erases this IFigure.  
+ */
+void erase();
+
+/**
+ * Returns the IFigure at the specified location. May return <code>this</code> or
+ * <code>null</code>.
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return The IFigure at the specified location
+ */
+IFigure findFigureAt(int x, int y);
+
+/**
+ * Returns the IFigure at the specified location based on the conditional TreeSearch.  May
+ * return <code>this</code> or <code>null</code>
+ * @param x the X coordinate
+ * @param y the Y coordinate
+ * @param search the conditional TreeSearch
+ * @return the IFigure at the specified location
+ */
+IFigure findFigureAt(int x, int y, TreeSearch search);
+
+/**
+ * Returns the IFigure at the specified location. May return <code>this</code> or
+ * <code>null</code>.
+ * @param p The point
+ * @return The IFigure at the specified location
+ */
+IFigure findFigureAt(Point p);
+
+/**
+ * Returns the IFigure at the specified location, excluding any IFigures in
+ * <code>collection</code>. May return <code>this</code> or <code>null</code>.
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @param collection A collection of IFigures to be excluded
+ * @return The IFigure at the specified location, excluding any IFigures in collection
+ */
+IFigure findFigureAtExcluding(int x, int y, Collection collection);
+
+/**
+ * Returns the IFigure located at the given location which will accept mouse events.
+ * @param x The X coordinate
+ * @param y The Y coordinate
+ * @return The IFigure located at the given location which will accept mouse events
+ */
+IFigure findMouseEventTargetAt(int x, int y);
+
+/**
+ * Returns the background color. Background color can be inherited from the parent.
+ * @return The background color
+ */
+Color getBackgroundColor();
+
+/**
+ * Returns the current border by reference.
+ * @return The current border
+ */
+Border getBorder();
+
+/**
+ * Returns the smallest rectangle completely enclosing the IFigure. Implementation may
+ * return the Rectangle by reference. For this reason, callers of this method must not
+ * modify the returned Rectangle. The Rectangle's values may change in the future.
+ * @return This IFigure's bounds
+ */
+Rectangle getBounds();
+
+/**
+ * Returns an unmodifiable list of children by reference.
+ * @return An unmodifiable list of children by reference
+ */
+List getChildren();
+
+/**
+ * Returns the rectangular area within this Figure's bounds in which children will be
+ * placed (via {@link LayoutManager LayoutManagers}) and the painting of children will be
+ * clipped.
+ * @return The client area
+ */
+Rectangle getClientArea();
+
+/**
+ * Copies the client area into the specificied Recangle, and returns that rectangle for 
+ * convenience.
+ * @param rect The destination rectangle for the client area
+ * @return The same instance that was passed in, modified to contain the client area
+ */
+Rectangle getClientArea(Rectangle rect);
+
+/**
+ * Returns the Cursor used when the mouse is over this IFigure.
+ * @return The Cursor used when the mouse is over this IFigure
+ */
+Cursor getCursor();
+
+/**
+ * Returns the current Font by reference.
+ * @return The current Font
+ */
+Font getFont();
+
+/**
+ * Returns the foreground color.
+ * @return The foreground color
+ */
+Color getForegroundColor();
+
+/**
+ * Returns the current Insets.  May be returned by reference.  The returned value should
+ * not be modified.
+ * @return The current Insets.
+ */
+Insets getInsets();
+
+/**
+ * Returns the current LayoutManager by reference.
+ * @return The current LayoutManager by reference
+ */
+LayoutManager getLayoutManager();
+
+/**
+ * Returns the background Color of this Figure. Does not inherit this Color from the
+ * parent, may return null.
+ * @return The local background Color
+ */
+Color getLocalBackgroundColor();
+
+/**
+ * Returns the local foreground Color of this Figure. Does not inherit this Color from the
+ * parent, may return null.
+ * @return The local foreground Color
+ */
+Color getLocalForegroundColor();
+
+/**
+ * Returns a hint indicating the largest desireable size for the IFigure. Returned
+ * Dimension is by value.
+ * @return The maximum size
+ */
+Dimension getMaximumSize();
+
+/**
+ * Returns a hint indicating the smallest desireable size for the IFigure. 
+ * The returned dimension may be by <i>reference</i>, and it must not be modified by the
+ * caller.
+ * @return The minimum size
+ */
+Dimension getMinimumSize();
+
+/**
+ * Returns a hint indicating the smallest desireable size for the IFigure.
+ * The returned dimension may be by <i>reference</i>, and it must not be modified by the
+ * caller.
+ * @param wHint the width hint
+ * @param hHint the height hint
+ * @return The minimum size
+ */
+Dimension getMinimumSize(int wHint, int hHint);
+
+/**
+ * Returns the IFigure that is the current parent of this IFigure or <code>null</code> if
+ * there is no parent.
+ * @return <code>null</code> or the parent figure
+ */
+IFigure getParent();
+
+/**
+ * Returns the preferred size for this IFigure. The returned value must not be modified
+ * by the caller.  If the figure has no preference, it returns its current size.  The same
+ * as calling {@link #getPreferredSize(int, int) getPreferredSize(-1, -1)}.
+ * @return The preferred size
+ */
+Dimension getPreferredSize();
+
+/**
+ * Returns the preferred size for this IFigure using the provided width and height hints.
+ * The returned dimension may be by <i>reference</i>, and it must not be modified by the
+ * caller.  A value of <code>-1</code> indicates that there is no constraint in that
+ * direction.
+ * 
+ * @param wHint a width hint
+ * @param hHint a height hint
+ * @return The preferred size
+ */ 
+Dimension getPreferredSize(int wHint, int hHint);
+
+/**
+ * Returns the current size. Returned Dimension is by value.
+ * @return The current size
+ */
+Dimension getSize();
+
+/**
+ * Returns a IFigure that is the tooltip for this IFigure.
+ * @return This IFigure's tooltip
+ */
+IFigure getToolTip();
+
+/**
+ * Returns the UpdateManager for this IFigure by reference.
+ * @return The update manager
+ */
+UpdateManager getUpdateManager();
+
+/**
+ * Called when this IFigure has gained focus.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link FocusListener} with
+ * this IFigure.
+ * @param event The focus event
+ */
+void handleFocusGained(FocusEvent event);
+
+/**
+ * Called when this IFigure has lost focus.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link FocusListener} with
+ * this IFigure.
+ * @param event The focus event
+ */
+void handleFocusLost(FocusEvent event);
+
+/**
+ * Called when a key is pressed while this IFigure has focus.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link KeyListener} with
+ * this IFigure.
+ * @param event The key event
+ */
+void handleKeyPressed(KeyEvent event);
+
+/**
+ * Called when a key is released while this IFigure has focus.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link KeyListener} with
+ * this IFigure.
+ * @param event The key event
+ */
+void handleKeyReleased(KeyEvent event);
+
+/**
+ * Called when a mouse button has been double-clicked while within this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseListener} with
+ * this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseDoubleClicked(MouseEvent event);
+
+/**
+ * Called when the mouse has been dragged within this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseMotionListener}
+ * with this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseDragged(MouseEvent event);
+
+/**
+ * Called when the mouse has entered this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseMotionListener}
+ * with this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseEntered(MouseEvent event);
+
+/**
+ * Called when the mouse has exited this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseMotionListener}
+ * with this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseExited(MouseEvent event);
+
+/**
+ * Called when the mouse has hovered over this IFigure.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseMotionListener}
+ * with this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseHover(MouseEvent event);
+
+/**
+ * Called when the mouse has moved within this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseMotionListener}
+ * with this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseMoved(MouseEvent event);
+
+/**
+ * Called when a mouse button has been pressed while within this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseListener} with
+ * this IFigure.
+ * @param event The mouse event
+ */
+void handleMousePressed(MouseEvent event);
+
+/**
+ * Called when a mouse button has been released while within this IFigure's bounds.
+ * <p><b>NOTE</b>: You should not override this method. If you are interested in receiving
+ * notification of this type of event, you should register a {@link MouseListener} with
+ * this IFigure.
+ * @param event The mouse event
+ */
+void handleMouseReleased(MouseEvent event);
+
+/**
+ * Returns <code>true</code> if this IFigure has focus.
+ * @return <code>true</code> if this IFigure has focus
+ */
+boolean hasFocus();
+
+/**
+ * This method is <b>for internal purposes only</b> and should not be called.
+ * @return The event dispatcher
+ */
+EventDispatcher internalGetEventDispatcher();
+
+/**
+ * Returns <code>true</code> if this IFigure's bounds intersect with the given Rectangle.
+ * Figure is asked so that non-rectangular IFigures can reduce the frequency of paints.
+ * @param rect The rectangle to check for intersection
+ * @return <code>true</code> if this IFigure's bounds intersect with the given Rectangle
+ */
+boolean intersects(Rectangle rect);
+
+/**
+ * Invalidates this IFigure.  If this figure has a LayoutManager, then
+ * {@link LayoutManager#invalidate()} should be called on that layout.
+ */
+void invalidate();
+
+/**
+ * Invalidates this figure as well as all contained within.
+ */
+void invalidateTree();
+
+/**
+ * Returns <code>true</code> if this figure is capable of applying a local coordinate
+ * system which affects its children.
+ * @since 3.1
+ * @return <code>true</code> if this figure provides local coordinates to children
+ */
+boolean isCoordinateSystem();
+
+/**
+ * Returns <code>true</code> if this IFigure is enabled.
+ * @return <code>true</code> if this IFigure is enabled
+ */
+boolean isEnabled();
+
+/**
+ * Returns <code>true</code> if this IFigure can gain focus on a 
+ * {@link org.eclipse.swt.events.TraverseEvent}.
+ * @return <code>true</code> if this IFigure can gain focus on a TraverseEvent
+ */
+boolean isFocusTraversable();
+
+/**
+ * @return <code>true</code> if this figure is hosted in a Control that is mirrored
+ * @since 3.1
+ */
+boolean isMirrored();
+
+/**
+ * Returns <code>true</code> if this IFigure is opaque.
+ * @return <code>true</code> if this IFigure is opaque
+ */
+boolean isOpaque();
+
+/**
+ * Returns <code>true</code> if this IFigure can receive focus on a call to
+ * {@link #requestFocus()}.
+ * @return <code>true</code> if this IFigure can receive focus on a call to requestFocus()
+ */
+boolean isRequestFocusEnabled();
+
+/**
+ * Returns <code>true</code> if this IFigure is showing. This figure is only showing if
+ * it is visible and its parent is showing, or it has no parent.
+ * @return <code>true</code> if this IFigure is showing
+ */
+boolean isShowing();
+
+/**
+ * returns <code>true</code> if this figure's visibility flag is set to true. Does not
+ * walk up the parent chain.
+ * @return <code>true</code> if the figure's visibility flag is set
+ */
+boolean isVisible();
+
+/**
+ * Paints this IFigure and its children.
+ * @param graphics The Graphics object used for painting
+ */
+void paint(Graphics graphics);
+
+/**
+ * Removes the given child from this figure's children.  If this figure has a
+ * LayoutManager, then {@link LayoutManager#remove(IFigure)} shall be called on that
+ * layout with the child.
+ * @param figure The IFigure to remove
+ */
+void remove(IFigure figure);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of
+ * ancestor events.
+ * @param listener The listener to remove
+ */
+void removeAncestorListener(AncestorListener listener);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of
+ * coordinate changes.
+ * @param listener the listener to remove
+ * @since 3.1
+ */
+void removeCoordinateListener(CoordinateListener listener);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of
+ * IFigure events.
+ * @param listener The listener to remove
+ */
+void removeFigureListener(FigureListener listener);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of focus
+ * events.
+ * @param listener The listener to remove
+ */
+void removeFocusListener(FocusListener listener);
+
+/**
+ * Removes the first occurence of the given listener.
+ * @param listener The listener to remove
+ */
+void removeKeyListener(KeyListener listener);
+
+/**
+ * Removes the most recent occurence of the given listener.
+ * @since 3.1
+ * @param listener the listener to remove
+ */
+void removeLayoutListener(LayoutListener listener);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of mouse
+ * events.
+ * @param listener The listener to remove
+ */
+void removeMouseListener(MouseListener listener);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of mouse
+ * motion events.
+ * @param listener The listener to remove
+ */
+void removeMouseMotionListener(MouseMotionListener listener);
+
+/**
+ * Called before this IFigure is removed from its parent.
+ */
+void removeNotify();
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of any
+ * property changes.
+ * @param listener The listener to remove
+ */
+void removePropertyChangeListener(PropertyChangeListener listener);
+
+/**
+ * Unregisters the given listener, so that it will no longer receive notification of
+ * changes in the given property. This will only unregister the listener for the given
+ * property. If the listener is registered to listen to other properties, this will not
+ * affect the notification of the listener regarding those properties.
+ * @param property The property that the listener is no longer interested in
+ * @param listener The listener no longer interested in the property
+ */
+void removePropertyChangeListener(String property, PropertyChangeListener listener);
+
+/**
+ * Repaints this IFigure.
+ */
+void repaint();
+
+/**
+ * Repaints the rectangular area within this IFigure whose upper-left corner is located at
+ * the point <code>(x,y)</code> and whose width and height are <code>w</code> and
+ * <code>h</code>, respectively.
+ * @param x The X coordinate of the area to repaint
+ * @param y The Y coordinate of the area to repaint
+ * @param w The width of the area to repaint
+ * @param h The height of the area to repaint
+ */
+void repaint(int x, int y, int w, int h);
+
+/**
+ * Repaints the rectangular area within this IFigure represented by <code>rect</code>.
+ * @param rect The rectangular area to be repainted
+ */
+void repaint(Rectangle rect);
+
+/**
+ * Requests focus from the {@link EventDispatcher}.
+ */
+void requestFocus();
+
+/**
+ * Invalidates this figure and revalidates() its parent.  If a figure does not have a
+ * parent, it will request a validation from it UpdateManager. Calling this method does
+ * not guarantee that a repaint will occur.
+ */
+void revalidate();
+
+/**
+ * Sets the background color.
+ * @param c The new background color
+ */
+void setBackgroundColor(Color c);
+
+/**
+ * Sets the border.
+ * @param b The new border
+ */
+void setBorder(Border b);
+
+/**
+ * Sets the bounds to the bounds of the specified <code>Rectangle</code>.
+ * @param rect The new bounds
+ */
+void setBounds(Rectangle rect);
+
+/**
+ * Convenience method to set the constraint of the specified child in the current
+ * LayoutManager.
+ * @param child The figure whose constraint is being set
+ * @param constraint the constraint
+ * @throws IllegalArgumentException if the child is not contained by this Figure
+ */
+void setConstraint(IFigure child, Object constraint);
+
+/**
+ * Sets the cursor.
+ * @param cursor The new cursor
+ */
+void setCursor(Cursor cursor);
+
+/**
+ * Sets this IFigure to be enabled.
+ * @param value <code>true</code> if this IFigure should be enabled
+ */
+void setEnabled(boolean value);
+
+/**
+ * Sets the ability for this IFigure to gain focus on a 
+ * {@link org.eclipse.swt.events.TraverseEvent}.
+ * @param value <code>true</code> if this IFigure should gain focus on a TraverseEvent
+ */
+void setFocusTraversable(boolean value);
+
+/**
+ * Sets the font.
+ * @param f The new font
+ */
+void setFont(Font f);
+
+/**
+ * Sets the foreground color.
+ * @param c The new foreground color
+ */
+void setForegroundColor(Color c);
+
+/**
+ * Sets the LayoutManager.
+ * @param lm The new layout manager
+ */
+void setLayoutManager(LayoutManager lm);
+
+/**
+ * Sets the location of this IFigure.
+ * @param p The new location
+ */
+void setLocation(Point p);
+
+/**
+ * Sets the maximum size this IFigure can be.
+ * @param size The new maximum size
+ */
+void setMaximumSize(Dimension size);
+
+/**
+ * Sets the minimum size this IFigure can be.
+ * @param size The new minimum size
+ */
+void setMinimumSize(Dimension size);
+
+/**
+ * Sets this IFigure to be opaque if <i>isOpaque</i> is <code>true</code> and transparent
+ * if <i>isOpaque</i> is <code>false</code>.
+ * @param isOpaque <code>true</code> is this IFigure should be opaque
+ */
+void setOpaque(boolean isOpaque);
+
+/**
+ * Sets this IFigure's parent.
+ * @param parent The new parent IFigure
+ */
+void setParent(IFigure parent);
+
+/**
+ * Sets this IFigure's preferred size.
+ * @param size The new preferred size
+ */
+void setPreferredSize(Dimension size);
+
+/**
+ * Sets the ability for this Figure to gain focus on a call to {@link #requestFocus()}.
+ * @param requestFocusEnabled <code>true</code> if this IFigure should gain focus on a call
+ * to requestFocus()
+ */
+void setRequestFocusEnabled(boolean requestFocusEnabled);
+
+/**
+ * Sets this IFigure's size.
+ * @param d The new size
+ */
+void setSize(Dimension d);
+
+/**
+ * Sets this IFigure's size.
+ * @param w The new width
+ * @param h The new height
+ */
+void setSize(int w, int h);
+
+/**
+ * Sets a tooltip that is displayed when the mouse hovers over this IFigure.
+ * @param figure The tooltip IFigure
+ */
+void setToolTip(IFigure figure);
+
+/**
+ * Sets this IFigure's visibility.
+ * @param visible <code>true</code> if this IFigure should be visible
+ */
+void setVisible(boolean visible);
+
+/**
+ * Moves this IFigure <code>x</code> pixels horizontally and <code>y</code> pixels
+ * vertically.
+ * @param x The amount to move this IFigure horizontally
+ * @param y The amount to move this IFigure vertically
+ */
+void translate(int x, int y);
+
+/**
+ * Translates a Translatable from this IFigure's parent's coordinates to this IFigure's
+ * local coordinates.
+ * @param t The object to translate
+ */
+void translateFromParent(Translatable t);
+
+/**
+ * Translates a Translatable that is relative to this figure's bounds to absolute.
+ * @param t The object to translate
+ */
+void translateToAbsolute(Translatable t);
+
+/**
+ * Translates a Translatable from this IFigure's coordinates to its parent's coordinates.
+ * @param t The object to translate
+ */
+void translateToParent(Translatable t);
+
+/**
+ * Translates a Translatable in absolute coordinates to be relative to this figure's
+ * bounds.
+ * @param t The object to translate
+ */
+void translateToRelative(Translatable t);
+
+/**
+ * Indicates that this figure should make itself valid.  Validation includes invoking
+ * layout on a LayoutManager if present, and then validating all children figures. 
+ * Default validation uses pre-order, depth-first ordering.
+ */
+void validate();
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ImageFigure.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ImageFigure.java
new file mode 100644
index 0000000..8421596
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ImageFigure.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A Figure that simply contains an Image.  Use this Figure, instead of a Label, when
+ * displaying Images without any accompanying text.  This figure is not intended to have a
+ * layout mananger or children.
+ * <P>
+ * Note that it is the client's responsibility to dispose the given image.  There is no
+ * "free" resource management in draw2d.
+ *  
+ * @author Pratik Shah
+ */
+public class ImageFigure 
+	extends Figure 
+{
+
+private Image img;
+private Dimension size = new Dimension();
+private int alignment;
+
+/**
+ * Constructor<br>
+ * The default alignment is <code>PositionConstants.CENTER</code>.
+ */
+public ImageFigure() {
+	this(null, PositionConstants.CENTER);
+}
+
+/**
+ * Constructor<br>
+ * The default alignment is <code>PositionConstants.CENTER</code>.
+ * 
+ * @param	image	The Image to be displayed
+ */
+public ImageFigure(Image image) {
+	this(image, PositionConstants.CENTER);
+}
+
+/**
+ * Constructor
+ * 
+ * @param	image		The Image to be displayed
+ * @param	alignment	A PositionConstant indicating the alignment
+ * 
+ * @see ImageFigure#setImage(Image)
+ * @see ImageFigure#setAlignment(int)
+ */
+public ImageFigure(Image image, int alignment) {
+	setImage(image);
+	setAlignment(alignment);
+}
+
+/**
+ * @return The Image that this Figure displays
+ */
+public Image getImage() {
+	return img;
+}
+
+/**
+ * Calculates the necessary size to display the Image within the figure's client area.
+ * 
+ * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
+ */
+public Dimension getPreferredSize(int wHint, int hHint) {
+	if (getInsets() == NO_INSETS)
+		return size;
+	Insets i = getInsets();
+	return size.getExpanded(i.getWidth(), i.getHeight());
+}
+
+/**
+ * @see org.eclipse.draw2d.Figure#paintFigure(Graphics)
+ */
+protected void paintFigure(Graphics graphics) {
+	super.paintFigure(graphics);
+	
+	if (getImage() == null)
+		return;
+
+	int x, y;
+	Rectangle area = getClientArea();
+	switch (alignment & PositionConstants.NORTH_SOUTH) {
+		case PositionConstants.NORTH:
+			y = area.y;
+			break;
+		case PositionConstants.SOUTH:
+			y = area.y + area.height - size.height;
+			break;
+		default:
+			y = (area.height - size.height) / 2 + area.y;
+			break;
+	}
+	switch (alignment & PositionConstants.EAST_WEST) {
+		case PositionConstants.EAST:
+			x = area.x + area.width - size.width;
+			break;
+		case PositionConstants.WEST:
+			x = area.x;
+			break;
+		default:
+			x = (area.width - size.width) / 2 + area.x;
+			break;
+	}
+	graphics.drawImage(getImage(), x, y);
+}
+
+/**
+ * Sets the alignment of the Image within this Figure.  The alignment comes into play
+ * when the ImageFigure is larger than the Image.  The alignment could be any valid
+ * combination of the following:
+ * 
+ * <UL>
+ * 		<LI>PositionConstants.NORTH</LI>
+ * 		<LI>PositionConstants.SOUTH</LI>
+ * 		<LI>PositionConstants.EAST</LI>
+ * 		<LI>PositionConstants.WEST</LI>
+ * 		<LI>PositionConstants.CENTER or PositionConstants.NONE</LI>
+ * </UL>
+ * 
+ * @param flag A constant indicating the alignment
+ */
+public void setAlignment(int flag) {
+	alignment = flag;
+}
+
+/**
+ * Sets the Image that this ImageFigure displays.
+ * <p>
+ * IMPORTANT: Note that it is the client's responsibility to dispose the given image.
+ * 
+ * @param image	The Image to be displayed.  It can be <code>null</code>.
+ */
+public void setImage(Image image) {
+	if (img == image)
+		return;
+	img = image;
+	if (img != null)
+		size = new Rectangle(image.getBounds()).getSize();
+	else
+		size = new Dimension();
+	revalidate();
+	repaint();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ImageUtilities.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ImageUtilities.java
new file mode 100644
index 0000000..4db4cd6
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/ImageUtilities.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.draw2d.geometry.Dimension;
+
+/**
+ * @author Pratik Shah
+ * @since 3.0
+ */
+public class ImageUtilities {
+
+/**
+ * Returns a new Image with the given String rotated left (by 90 degrees).  The String
+ * will be rendered using the provided colors and fonts.  The client is responsible for
+ * disposing the returned Image.  Strings cannot contain newline or tab characters.  This
+ * method MUST be invoked from the user-interface (Display) thread.
+ * 
+ * @param string the String to be rendered
+ * @param font the font
+ * @param foreground the text's color
+ * @param background the background color
+ * @return an Image which must be disposed
+ */
+public static Image createRotatedImageOfString(String string, Font font, 
+                                               Color foreground, Color background) {
+	Display display = Display.getCurrent();
+	if (display == null)
+		SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);
+	
+	FontMetrics metrics = FigureUtilities.getFontMetrics(font);
+	Dimension strSize = FigureUtilities.getStringExtents(string, font);
+	Image srcImage = new Image(display, strSize.width, metrics.getAscent());
+	GC gc = new GC(srcImage);
+	gc.setFont(font);
+	gc.setForeground(foreground);
+	gc.setBackground(background);
+	gc.fillRectangle(srcImage.getBounds());
+	gc.drawString(string, 0, 0 - metrics.getLeading());
+	Image result = createRotatedImage(srcImage);
+	gc.dispose();
+	srcImage.dispose();
+	return result;
+}
+
+/**
+ * Returns a new Image that is the given Image rotated left by 90 degrees.  The client is
+ * responsible for disposing the returned Image.  This method MUST be invoked from the
+ * user-interface (Display) thread.
+ * 
+ * @param	srcImage	the Image that is to be rotated left
+ * @return	the rotated Image (the client is responsible for disposing it)
+ */
+public static Image createRotatedImage(Image srcImage) {
+	Display display = Display.getCurrent();
+	if (display == null)
+		SWT.error(SWT.ERROR_THREAD_INVALID_ACCESS);
+
+	ImageData srcData = srcImage.getImageData();
+	ImageData destData;
+	if (srcData.depth < 8)
+		destData = rotatePixelByPixel(srcData);
+	else
+		destData = rotateOptimized(srcData);
+	
+	return new Image(display, destData);
+}
+
+/**
+ * Creates an ImageData representing the given <code>Image</code> shaded with the given
+ * <code>Color</code>.
+ * 
+ * @param fromImage	Image that has to be shaded
+ * @param shade		The Color to be used for shading
+ * @return A new ImageData that can be used to create an Image.
+ */	
+public static ImageData createShadedImage(Image fromImage, Color shade) {
+	org.eclipse.swt.graphics.Rectangle r = fromImage.getBounds();
+	ImageData data = fromImage.getImageData();
+	PaletteData palette = data.palette;
+	if (!palette.isDirect) {
+		/* Convert the palette entries */
+		RGB [] rgbs = palette.getRGBs();
+		for (int i = 0; i < rgbs.length; i++) {
+			if (data.transparentPixel != i) {
+				RGB color = rgbs [i];
+				color.red = determineShading(color.red, shade.getRed());
+				color.blue = determineShading(color.blue, shade.getBlue());
+				color.green = determineShading(color.green, shade.getGreen());
+			}
+		}
+		data.palette = new PaletteData(rgbs);
+	} else {
+		/* Convert the pixels. */
+		int[] scanline = new int[r.width];
+		int redMask = palette.redMask;
+		int greenMask = palette.greenMask;
+		int blueMask = palette.blueMask;
+		int redShift = palette.redShift;
+		int greenShift = palette.greenShift;
+		int blueShift = palette.blueShift;
+		for (int y = 0; y < r.height; y++) {
+			data.getPixels(0, y, r.width, scanline, 0);
+			for (int x = 0; x < r.width; x++) {
+				int pixel = scanline[x];
+				int red = pixel & redMask;
+				red = (redShift < 0) ? red >>> -redShift : red << redShift;
+				int green = pixel & greenMask;
+				green = (greenShift < 0) ? green >>> -greenShift : green << greenShift;
+				int blue = pixel & blueMask;
+				blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift;
+				red = determineShading(red, shade.getRed());
+				blue = determineShading(blue, shade.getBlue());
+				green = determineShading(green, shade.getGreen());
+				red = (redShift < 0) ? red << -redShift : red >> redShift;
+				red &= redMask;
+				green = (greenShift < 0) ? green << -greenShift : green >> greenShift;
+				green &= greenMask;
+				blue = (blueShift < 0) ? blue << -blueShift : blue >> blueShift;
+				blue &= blueMask;
+				scanline[x] = red | blue | green;
+			}
+			data.setPixels(0, y, r.width, scanline, 0);
+		}
+	}
+	return data;
+}
+
+private static int determineShading(int origColor, int shadeColor) {
+	return (origColor + shadeColor) / 2;
+}
+
+private static ImageData rotateOptimized(ImageData srcData) {
+	int bytesPerPixel = Math.max(1, srcData.depth / 8);
+	int destBytesPerLine = ((srcData.height * bytesPerPixel - 1) / srcData.scanlinePad + 1) 
+			* srcData.scanlinePad;
+	byte[] newData = new byte[destBytesPerLine * srcData.width];
+	for (int srcY = 0; srcY < srcData.height; srcY++) {
+		for (int srcX = 0; srcX < srcData.width; srcX++) {
+			int destX = srcY;
+			int destY = srcData.width - srcX - 1;
+			int destIndex = (destY * destBytesPerLine) + (destX * bytesPerPixel);
+			int srcIndex = (srcY * srcData.bytesPerLine) + (srcX * bytesPerPixel);
+			System.arraycopy(srcData.data, srcIndex, newData, destIndex, bytesPerPixel);
+		}
+	}
+	return new ImageData(srcData.height, srcData.width, srcData.depth, srcData.palette, 
+			srcData.scanlinePad, newData);
+}
+
+private static ImageData rotatePixelByPixel(ImageData srcData) {
+	ImageData destData = new ImageData(srcData.height, srcData.width, srcData.depth, 
+			srcData.palette); 
+	for (int y = 0; y < srcData.height; y++) {
+		for (int x = 0; x < srcData.width; x++) {
+			destData.setPixel(y, srcData.width - x - 1,	srcData.getPixel(x, y));
+		}
+	}
+	return destData;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/InputEvent.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/InputEvent.java
new file mode 100644
index 0000000..50bfba5
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/InputEvent.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+
+/**
+ * The base class for Draw2d events.
+ */
+public abstract class InputEvent
+	extends java.util.EventObject
+{
+
+private int state;
+
+private boolean consumed = false;
+
+/** @see SWT#ALT */
+public static final int ALT = SWT.ALT;
+/** @see SWT#CONTROL */
+public static final int CONTROL = SWT.CONTROL;
+/** @see SWT#SHIFT */
+public static final int SHIFT = SWT.SHIFT;
+/** @see SWT#BUTTON1 */
+public static final int BUTTON1 = SWT.BUTTON1;
+/** @see SWT#BUTTON2 */
+public static final int BUTTON2 = SWT.BUTTON2;
+/** @see SWT#BUTTON3 */
+public static final int BUTTON3 = SWT.BUTTON3;
+/** @see SWT#BUTTON4 */
+public static final int BUTTON4 = SWT.BUTTON4;
+/** @see SWT#BUTTON5 */
+public static final int BUTTON5 = SWT.BUTTON5;
+/** A bitwise OR'ing of {@link #BUTTON1}, {@link #BUTTON2}, {@link #BUTTON3},
+ * {@link #BUTTON4} and {@link #BUTTON5} */
+public static final int ANY_BUTTON = SWT.BUTTON_MASK;
+
+/**
+ * Constructs a new InputEvent.
+ * @param dispatcher the event dispatcher
+ * @param source the source of the event
+ * @param state the state
+ */
+public InputEvent(EventDispatcher dispatcher, IFigure source, int state) {
+	super(source);
+	this.state = state;
+}
+
+/**
+ * Marks this event as consumed so that it doesn't get passed on to other listeners.
+ */
+public void consume() {
+	consumed = true;
+}
+
+/**
+ * Returns the event statemask, which is a bitwise OR'ing of any of the following: 
+ * {@link #ALT}, {@link #CONTROL}, {@link #SHIFT}, {@link #BUTTON1}, {@link #BUTTON2}, 
+ * {@link #BUTTON3}, {@link #BUTTON4} and {@link #BUTTON5}.
+ * @return the state
+ */
+public int getState() {
+	return state;
+}
+
+/**
+ * @return whether this event has been consumed.
+ */
+public boolean isConsumed() {
+	return consumed;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/KeyEvent.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/KeyEvent.java
new file mode 100644
index 0000000..c053e7e
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/KeyEvent.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * An event caused by the user interacting with the keyboard.
+ */
+public class KeyEvent
+	extends InputEvent
+{
+
+/** 
+ * The character that was pressed.
+ * @see org.eclipse.swt.events.KeyEvent#character 
+ */
+public char character;
+
+/** 
+ * The keycode.
+ * @see org.eclipse.swt.events.KeyEvent#keyCode 
+ */
+public int keycode;
+
+/**
+ * Constructs a new KeyEvent.
+ * @param dispatcher the event dispatcher
+ * @param source the source of the event
+ * @param ke an SWT key event used to supply the statemask, keycode and character
+ */
+public KeyEvent(EventDispatcher dispatcher, IFigure source,
+					org.eclipse.swt.events.KeyEvent ke) {
+	super(dispatcher, source, ke.stateMask);
+	character = ke.character;
+	keycode = ke.keyCode;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/KeyListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/KeyListener.java
new file mode 100644
index 0000000..3af90f0
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/KeyListener.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+/**
+ * A listener interface for receiving {@link KeyEvent KeyEvents} from the keyboard.
+ */
+public interface KeyListener {
+
+/**
+ * Called when a key is pressed.
+ * @param ke The KeyEvent object
+ */
+void keyPressed(KeyEvent ke);
+
+/**
+ * Called when a key is released.
+ * @param ke The KeyEvent object
+ */
+void keyReleased(KeyEvent ke);
+
+/**
+ * An empty implementation of KeyListener for convenience.
+ */
+class Stub
+	implements KeyListener
+{
+	/**
+	 * @see org.eclipse.draw2d.KeyListener#keyPressed(KeyEvent)
+	 */
+	public void keyPressed(KeyEvent ke) { }
+	/**
+	 * @see org.eclipse.draw2d.KeyListener#keyReleased(KeyEvent)
+	 */
+	public void keyReleased(KeyEvent ke) { }
+
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Label.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Label.java
new file mode 100644
index 0000000..3d9b0e9
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Label.java
@@ -0,0 +1,656 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.draw2d.geometry.Dimension;
+import org.eclipse.draw2d.geometry.Insets;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * A figure that can display text and/or an image.
+ */
+public class Label
+	extends Figure
+	implements PositionConstants
+{
+
+private static String ELLIPSIS = "..."; //$NON-NLS-1$
+
+
+private Image icon;
+private String text = "";//$NON-NLS-1$
+private String subStringText;
+private Dimension textSize;
+private Dimension subStringTextSize;
+private Dimension iconSize = new Dimension(0, 0);
+private Point iconLocation;
+private Point textLocation;
+private int textAlignment = CENTER;
+private int iconAlignment = CENTER;
+private int labelAlignment = CENTER;
+private int textPlacement = EAST;
+private int iconTextGap = 3;
+
+/**
+ * Construct an empty Label.
+ * 
+ * @since 2.0
+ */
+public Label() { }
+
+/**
+ * Construct a Label with passed String as its text.
+ * 
+ * @param s the label text
+ * @since 2.0
+ */
+public Label(String s) {
+	setText(s);
+}
+
+/**
+ * Construct a Label with passed Image as its icon.
+ * 
+ * @param i the label image
+ * @since 2.0
+ */
+public Label(Image i) {
+	setIcon(i);
+}
+
+/**
+ * Construct a Label with passed String as text and passed Image as its icon.
+ * 
+ * @param s the label text
+ * @param i the label image
+ * @since 2.0
+ */
+public Label(String s, Image i) {
+	setText(s);
+	setIcon(i);
+}
+
+private void alignOnHeight(Point loc, Dimension size, int alignment) {
+	Insets insets = getInsets();
+	switch(alignment) {
+		case TOP:
+			loc.y = insets.top;
+			break;
+		case BOTTOM:
+			loc.y = bounds.height - size.height - insets.bottom;
+			break;
+		default:
+			loc.y = (bounds.height - size.height) / 2;
+	}
+}
+
+private void alignOnWidth(Point loc, Dimension size, int alignment) {
+	Insets insets = getInsets();
+	switch(alignment) {
+		case LEFT:
+			loc.x = insets.left;
+			break;
+		case RIGHT:
+			loc.x = bounds.width - size.width - insets.right;
+			break;
+		default: 
+			loc.x = (bounds.width - size.width) / 2;
+	}
+}
+
+private void calculateAlignment() {
+	switch(textPlacement) {
+		case EAST:
+		case WEST:
+			alignOnHeight(textLocation, getTextSize(), textAlignment);
+			alignOnHeight(iconLocation, iconSize, iconAlignment);
+			break;
+		case NORTH:
+		case SOUTH:
+			alignOnWidth(textLocation, getSubStringTextSize(), textAlignment);
+			alignOnWidth(iconLocation, iconSize, iconAlignment);
+			break;
+	}
+}
+
+/**
+ * Calculates the size of the Label using the passed Dimension as the size of the Label's 
+ * text.
+ * 
+ * @param txtSize the precalculated size of the label's text
+ * @return the label's size
+ * @since 2.0
+ */ 
+protected Dimension calculateLabelSize(Dimension txtSize) {
+	int gap = iconTextGap;
+	if (getIcon() == null || getText().equals("")) //$NON-NLS-1$
+		gap = 0;
+	Dimension d = new Dimension(0, 0);
+	if (textPlacement == WEST || textPlacement == EAST) {
+		d.width = iconSize.width + gap + txtSize.width;
+		d.height = Math.max(iconSize.height, txtSize.height);
+	} else {
+		d.width = Math.max(iconSize.width, txtSize.width);
+		d.height = iconSize.height + gap + txtSize.height;
+	}
+	return d;
+}
+
+private void calculateLocations() {
+	textLocation = new Point();
+	iconLocation = new Point();
+	
+	calculatePlacement();
+	calculateAlignment();
+	Dimension offset = getSize().getDifference(getPreferredSize());
+	offset.width += getTextSize().width - getSubStringTextSize().width;
+	switch (labelAlignment) {
+		case CENTER: 
+			offset.scale(0.5f); 
+			break;
+		case LEFT: 
+			offset.scale(0.0f); 
+			break;
+		case RIGHT: 
+			offset.scale(1.0f); 
+			break;
+		case TOP: 
+			offset.height = 0; 
+			offset.scale(0.5f); 
+			break;
+		case BOTTOM: 
+			offset.height = offset.height * 2; 
+			offset.scale(0.5f); 
+			break;
+		default: 
+			offset.scale(0.5f); 
+			break;
+	}
+	
+	switch (textPlacement) {
+		case EAST:
+		case WEST: 
+			offset.height = 0; 
+			break;
+		case NORTH:
+		case SOUTH: 
+			offset.width = 0; 
+			break;
+	}
+
+	textLocation.translate(offset);
+	iconLocation.translate(offset);
+}
+
+private void calculatePlacement() {
+	int gap = iconTextGap;
+	if (icon == null || text.equals("")) //$NON-NLS-1$
+		gap = 0;
+	Insets insets = getInsets();
+	
+	switch(textPlacement) {
+	case EAST:
+		iconLocation.x = insets.left;
+		textLocation.x = iconSize.width + gap + insets.left;	
+		break;
+	case WEST:
+		textLocation.x = insets.left;
+		iconLocation.x = getSubStringTextSize().width + gap + insets.left;
+		break;
+	case NORTH:
+		textLocation.y = insets.top;
+		iconLocation.y = getTextSize().height + gap + insets.top;
+		break;
+	case SOUTH:
+		textLocation.y = iconSize.height + gap + insets.top;
+		iconLocation.y = insets.top;
+	}
+}
+
+/**
+ * Calculates the size of the Label's text size. The text size calculated takes into 
+ * consideration if the Label's text is currently truncated. If text size without 
+ * considering current truncation is desired, use {@link #calculateTextSize()}.
+ * 
+ * @return the size of the label's text, taking into account truncation
+ * @since 2.0
+ */
+protected Dimension calculateSubStringTextSize() {
+	return FigureUtilities.getTextExtents(getSubStringText(), getFont());
+}
+
+/**
+ * Calculates and returns the size of the Label's text. Note that this Dimension is 
+ * calculated using the Label's full text, regardless of whether or not its text is 
+ * currently truncated. If text size considering current truncation is desired, use 
+ * {@link #calculateSubStringTextSize()}.
+ * 
+ * @return the size of the label's text, ignoring truncation
+ * @since 2.0
+ */
+protected Dimension calculateTextSize() {
+	return FigureUtilities.getTextExtents(getText(), getFont());
+}
+
+private void clearLocations() {
+	iconLocation = textLocation = null;
+}
+
+/**
+ * Returns the Label's icon.
+ * 
+ * @return the label icon
+ * @since 2.0
+ */
+public Image getIcon() {
+	return icon;
+}
+
+/**
+ * Returns the current alignment of the Label's icon. The default is 
+ * {@link PositionConstants#CENTER}.
+ * 
+ * @return the icon alignment
+ * @since 2.0
+ */
+public int getIconAlignment() {
+	return iconAlignment;
+}
+
+/**
+ * Returns the bounds of the Label's icon.
+ * 
+ * @return the icon's bounds
+ * @since 2.0
+ */
+public Rectangle getIconBounds() {
+	Rectangle bounds = getBounds();
+	return new Rectangle(bounds.getLocation().translate(getIconLocation()), iconSize);
+}
+
+/**
+ * Returns the location of the Label's icon relative to the Label.
+ * 
+ * @return the icon's location
+ * @since 2.0
+ */
+protected Point getIconLocation() {
+	if (iconLocation == null)
+		calculateLocations();
+	return iconLocation;
+}
+
+/**
+ * Returns the gap in pixels between the Label's icon and its text.
+ * 
+ * @return the gap
+ * @since 2.0
+ */
+public int getIconTextGap() {
+	return iconTextGap;
+}
+
+/**
+ * @see IFigure#getMinimumSize(int, int)
+ */
+public Dimension getMinimumSize(int w, int h) {
+	if (minSize != null)
+		return minSize;
+	minSize = new Dimension();
+	if (getLayoutManager() != null)
+		minSize.setSize(getLayoutManager().getMinimumSize(this, w, h));
+	
+	Dimension labelSize = 
+		calculateLabelSize(FigureUtilities.getTextExtents(ELLIPSIS, getFont())
+				.intersect(FigureUtilities.getTextExtents(getText(), getFont())));
+	Insets insets = getInsets();
+	labelSize.expand(insets.getWidth(), insets.getHeight());
+	minSize.union(labelSize);
+	return minSize;	
+}
+
+/**
+ * @see IFigure#getPreferredSize(int, int)
+ */
+public Dimension getPreferredSize(int wHint, int hHint) {
+	if (prefSize == null) {
+		prefSize = calculateLabelSize(getTextSize());
+		Insets insets = getInsets();
+		prefSize.expand(insets.getWidth(), insets.getHeight());
+		if (getLayoutManager() != null)
+			prefSize.union(getLayoutManager().getPreferredSize(this, wHint, hHint));
+	}
+	if (wHint >= 0 && wHint < prefSize.width) {
+		Dimension minSize = getMinimumSize(wHint, hHint);
+		Dimension result = prefSize.getCopy();
+		result.width = Math.min(result.width, wHint);
+		result.width = Math.max(minSize.width, result.width);
+		return result;
+	}
+	return prefSize;
+}
+
+/**
+ * Calculates the amount of the Label's current text will fit in the Label, including an 
+ * elipsis "..." if truncation is required. 
+ * 
+ * @return the substring
+ * @since 2.0
+ */
+public String getSubStringText() {
+	if (subStringText != null)
+		return subStringText;
+	
+	subStringText = text;
+	int widthShrink = getPreferredSize().width - getSize().width;
+	if (widthShrink <= 0)
+		return subStringText;
+	
+	Dimension effectiveSize = getTextSize().getExpanded(-widthShrink, 0);
+	Font currentFont = getFont();
+	int dotsWidth = FigureUtilities.getTextWidth(ELLIPSIS, currentFont);
+	
+	if (effectiveSize.width < dotsWidth)
+		effectiveSize.width = dotsWidth;
+	
+	int subStringLength = FigureUtilities.getLargestSubstringConfinedTo(text,
+												  currentFont,
+												  effectiveSize.width - dotsWidth);
+	subStringText = new String(text.substring(0, subStringLength) + ELLIPSIS);
+	return subStringText;
+}
+
+/**
+ * Returns the size of the Label's current text. If the text is currently truncated, the 
+ * truncated text with its ellipsis is used to calculate the size.
+ * 
+ * @return the size of this label's text, taking into account truncation
+ * @since 2.0
+ */
+protected Dimension getSubStringTextSize() {
+	if (subStringTextSize == null)
+		subStringTextSize = calculateSubStringTextSize();
+	return subStringTextSize;	
+}
+
+/**
+ * Returns the text of the label. Note that this is the complete text of the label, 
+ * regardless of whether it is currently being truncated. Call {@link #getSubStringText()}
+ * to return the label's current text contents with truncation considered.
+ * 
+ * @return the complete text of this label
+ * @since 2.0
+ */
+public String getText() {
+	return text;
+}
+
+/**
+ * Returns the current alignment of the Label's text. The default text alignment is 
+ * {@link PositionConstants#CENTER}.
+ * 
+ * @return the text alignment
+ */
+public int getTextAlignment() {
+	return textAlignment;
+}
+
+/**
+ * Returns the bounds of the label's text. Note that the bounds are calculated using the 
+ * label's complete text regardless of whether the label's text is currently truncated.
+ * 
+ * @return the bounds of this label's complete text
+ * @since 2.0
+ */
+public Rectangle getTextBounds() {
+	Rectangle bounds = getBounds();
+	return new Rectangle(bounds.getLocation().translate(getTextLocation()), textSize);
+}
+
+/**
+ * Returns the location of the label's text relative to the label.
+ * 
+ * @return the text location
+ * @since 2.0
+ */
+protected Point getTextLocation() {
+	if (textLocation != null) 
+		return textLocation;
+	calculateLocations();
+	return textLocation;
+}
+
+/**
+ * Returns the current placement of the label's text relative to its icon. The default 
+ * text placement is {@link PositionConstants#EAST}.
+ * 
+ * @return the text placement
+ * @since 2.0
+ */ 
+public int getTextPlacement() {
+	return textPlacement;
+}
+
+/**
+ * Returns the size of the label's complete text. Note that the text used to make this 
+ * calculation is the label's full text, regardless of whether the label's text is 
+ * currently being truncated and is displaying an ellipsis. If the size considering 
+ * current truncation is desired, call {@link #getSubStringTextSize()}.
+ * 
+ * @return the size of this label's complete text
+ * @since 2.0
+ */
+protected Dimension getTextSize() {
+	if (textSize == null)
+		textSize = calculateTextSize();
+	return textSize;
+}
+
+/**
+ * @see IFigure#invalidate()
+ */
+public void invalidate() {
+	prefSize = null;
+	minSize = null;
+	clearLocations();
+	textSize = null;
+	subStringTextSize = null;
+	subStringText = null;
+	super.invalidate();
+}
+
+/**
+ * Returns <code>true</code> if the label's text is currently truncated and is displaying 
+ * an ellipsis, <code>false</code> otherwise.
+ * 
+ * @return <code>true</code> if the label's text is truncated
+ * @since 2.0
+ */
+public boolean isTextTruncated() {
+	return !getSubStringText().equals(getText());
+}
+
+/**
+ * @see Figure#paintFigure(Graphics)
+ */
+protected void paintFigure(Graphics graphics) {
+	if (isOpaque())
+		super.paintFigure(graphics);
+	Rectangle bounds = getBounds();
+	graphics.translate(bounds.x, bounds.y);
+	if (icon != null)
+		graphics.drawImage(icon, getIconLocation());
+	if (!isEnabled()) {
+		graphics.translate(1, 1);
+		graphics.setForegroundColor(ColorConstants.buttonLightest);
+		graphics.drawText(getSubStringText(), getTextLocation());
+		graphics.translate(-1, -1);
+		graphics.setForegroundColor(ColorConstants.buttonDarker);
+	}
+	graphics.drawText(getSubStringText(), getTextLocation());
+	graphics.translate(-bounds.x, -bounds.y);
+}
+
+/**
+ * Sets the label's icon to the passed image.
+ * 
+ * @param image the new label image
+ * @since 2.0
+ */
+public void setIcon(Image image) {
+	if (icon == image) 
+		return;
+	icon = image;
+	//Call repaint, in case the image dimensions are the same.
+	repaint();
+	if (icon == null)
+		setIconDimension(new Dimension());
+	else
+		setIconDimension(new Dimension(image));
+}
+
+/**
+ * This method sets the alignment of the icon within the bounds of the label. If the label
+ * is larger than the icon, then the icon will be aligned according to this alignment.
+ * Valid values are:
+ * <UL>
+ *   <LI><EM>{@link PositionConstants#CENTER}</EM>
+ *   <LI>{@link PositionConstants#TOP}
+ *   <LI>{@link PositionConstants#BOTTOM}
+ *   <LI>{@link PositionConstants#LEFT}
+ *   <LI>{@link PositionConstants#RIGHT}
+ * </UL>
+ * @param align the icon alignment 
+ * @since 2.0
+ */
+public void setIconAlignment (int align) {
+	if (iconAlignment == align)
+		return;
+	iconAlignment = align;
+	clearLocations();
+	repaint();
+}
+
+/**
+ * Sets the label's icon size to the passed Dimension.
+ * 
+ * @param d the new icon size
+ * @deprecated the icon is automatically displayed at 1:1
+ * @since 2.0
+ */
+public void setIconDimension(Dimension d) {
+	if (d.equals(iconSize)) 
+		return;
+	iconSize = d;
+	revalidate();
+}
+
+/**
+ * Sets the gap in pixels between the label's icon and text to the passed value. The 
+ * default is 4.
+ * 
+ * @param gap the gap
+ * @since 2.0
+ */
+public void setIconTextGap(int gap) {
+	if (iconTextGap == gap) 
+		return;
+	iconTextGap = gap;
+	repaint();
+	revalidate();
+}
+
+/**
+ * Sets the alignment of the entire label (icon and text). If this figure's bounds
+ * are larger than the size needed to display the label, the label will be aligned
+ * accordingly. Valid values are:
+ * <UL>
+ *   <LI><EM>{@link PositionConstants#CENTER}</EM>
+ *   <LI>{@link PositionConstants#TOP}
+ *   <LI>{@link PositionConstants#BOTTOM}
+ *   <LI>{@link PositionConstants#LEFT}
+ *   <LI>{@link PositionConstants#RIGHT}
+ * </UL>
+ * 
+ * @param align label alignment
+ */
+public void setLabelAlignment(int align) {
+	if (labelAlignment == align)
+		return;
+	labelAlignment = align;
+	clearLocations();
+	repaint();
+}
+
+/**
+ * Sets the label's text.
+ * @param s the new label text
+ * @since 2.0
+ */
+public void setText(String s) {
+	//"text" will never be null.
+	if (s == null)
+		s = "";//$NON-NLS-1$
+	if (text.equals(s)) 
+		return;
+	text = s;
+	revalidate();
+	repaint();
+}
+
+/**
+ * Sets the alignment of the Text relative to the icon. The text alignment must be
+ * orthogonal to the text placement. For example, if the placement is EAST, then the
+ * text can be aligned using TOP, CENTER, or BOTTOM. Valid values are:
+ * <UL>
+ *   <LI><EM>{@link PositionConstants#CENTER}</EM>
+ *   <LI>{@link PositionConstants#TOP}
+ *   <LI>{@link PositionConstants#BOTTOM}
+ *   <LI>{@link PositionConstants#LEFT}
+ *   <LI>{@link PositionConstants#RIGHT}
+ * </UL>
+ * @see #setLabelAlignment(int)
+ * @param align the text alignment
+ * @since 2.0
+ */
+public void setTextAlignment(int align) {
+	if (textAlignment == align) 
+		return;
+	textAlignment = align;
+	clearLocations();
+	repaint();
+}
+
+/**
+ * Sets the placement of text relative to the label's icon. Valid values are:
+ * <UL>
+ *   <LI><EM>{@link PositionConstants#EAST}</EM>
+ *   <LI>{@link PositionConstants#NORTH}
+ *   <LI>{@link PositionConstants#SOUTH}
+ *   <LI>{@link PositionConstants#WEST}
+ * </UL>
+ * 
+ * @param where the text placement
+ * @since 2.0
+ */
+public void setTextPlacement (int where) {
+	if (textPlacement == where)
+		return;
+	textPlacement = where;
+	revalidate();
+	repaint();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabelAnchor.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabelAnchor.java
new file mode 100644
index 0000000..731a41e
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabelAnchor.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * LabelAnchors must have an owner of type {@link Label}. The LabelAnchor behaves like
+ * {@link ChopboxAnchor} but {@link Connection Connections} will point to the center of
+ * its owner's icon as opposed to the center of the entire owning Label.
+ */
+public class LabelAnchor 
+	extends ChopboxAnchor
+{
+
+/**
+ * Constructs a LabelAnchor with no owner.
+ * 
+ * @since 2.0
+ */
+protected LabelAnchor() { }
+
+/**
+ * Constructs a LabelAnchor with owner <i>label</i>.
+ * @param label This LabelAnchor's owner
+ * @since 2.0
+ */
+public LabelAnchor(Label label) {
+	super(label);
+}
+
+/**
+ * Returns the bounds of this LabelAnchor's owning Label icon.
+ * @return The bounds of this LabelAnchor's owning Label icon
+ * @since 2.0
+ */
+protected Rectangle getBox() {
+	Label label = (Label)getOwner();
+	return label.getIconBounds();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabeledBorder.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabeledBorder.java
new file mode 100644
index 0000000..375186f
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabeledBorder.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * LabeledBorders have a text message somewhere on them. The Font for the text can be set.
+ * LabeledBorders should not change their Insets when the label changes, therefore,
+ * Figures using this Border should repaint() when updating the label, and revalidate()
+ * when changing the Font.
+ */
+public interface LabeledBorder 
+	extends Border
+{
+
+/**
+ * Returns the label for this Border.
+ * @return The label for this Border
+ */
+String getLabel();
+
+/**
+ * Sets the Font for the label.
+ * @param f The Font to be set
+ */
+void setFont(Font f);
+
+/**
+ * Sets the text to be displayed as the label for this Border.
+ * @param l The text
+ */
+void setLabel(String l);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabeledContainer.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabeledContainer.java
new file mode 100644
index 0000000..ecdcf30
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LabeledContainer.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.graphics.Font;
+
+/**
+ * A Container with a title bar describing the contents of the container. The frame is 
+ * generated by a {@link LabeledBorder}.
+ */
+public class LabeledContainer
+	extends Figure
+{
+
+/**
+ * Constructs a default container with a {@link GroupBoxBorder}.
+ * 
+ * @since 2.0
+ */
+public LabeledContainer() {
+	this(new GroupBoxBorder());
+}
+
+/**
+ * Constructs a labeled container with the border given as input.
+ *
+ * @param border the border
+ * @since 2.0
+ */
+public LabeledContainer(Border border) {
+	setBorder(border);
+	setOpaque(true);
+}
+
+private static LabeledBorder findLabeledBorder(Border border) {
+	if (border instanceof LabeledBorder)
+		return (LabeledBorder)border;
+	if (border instanceof CompoundBorder) {
+		CompoundBorder cb = (CompoundBorder)border;
+		LabeledBorder labeled = findLabeledBorder(cb.getInnerBorder());
+		if (labeled == null)
+			labeled = findLabeledBorder(cb.getOuterBorder());
+		return labeled;
+	}
+	return null;
+}
+
+/**
+ * Returns the text of the LabeledContainer's label.
+ *
+ * @return the label text
+ * @since 2.0
+ */
+public String getLabel() {
+	return getLabeledBorder().getLabel();
+}
+
+/**
+ * Returns the LabeledBorder of this container.
+ *
+ * @return the border
+ * @since 2.0
+ */
+protected LabeledBorder getLabeledBorder() {
+	return findLabeledBorder(getBorder());
+}
+
+/**
+ * Sets the title of the container.
+ *
+ * @param s the new title text
+ * @since 2.0
+ */
+public void setLabel(String s) {
+	getLabeledBorder().setLabel(s);
+	revalidate();
+	repaint();
+}
+
+/**
+ * Sets the font to be used for the container title.
+ *
+ * @param f the new font
+ * @since 2.0
+ */
+public void setLabelFont(Font f) {
+	getLabeledBorder().setFont(f);
+	revalidate();
+	repaint();
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Layer.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Layer.java
new file mode 100644
index 0000000..ef184e5
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/Layer.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Point;
+
+
+/**
+ * A transparent figure intended to be added exclusively to a {@link LayeredPane}, who has
+ * the responsibilty of managing its layers. 
+ */
+public class Layer
+	extends Figure
+{
+
+/**
+ * Overridden to implement transparent behavior.
+ * @see IFigure#containsPoint(int, int)
+ * 
+ */
+public boolean containsPoint(int x, int y) {
+	if (isOpaque())
+		return super.containsPoint(x, y);
+	Point pt = new Point(x, y);
+	translateFromParent(pt);
+	for (int i = 0; i < getChildren().size(); i++) {
+		IFigure child = (IFigure)getChildren().get(i);
+		if (child.containsPoint(pt.x, pt.y))
+			return true;
+	}
+	return false;
+}
+
+/**
+ * Overridden to implement transparency.
+ * @see IFigure#findFigureAt(int, int, TreeSearch)
+ */
+public IFigure findFigureAt(int x, int y, TreeSearch search) {
+	if (!isEnabled())
+		return null;
+	if (isOpaque())
+		return super.findFigureAt(x, y, search);
+
+	IFigure f = super.findFigureAt(x, y, search);
+	if (f == this)
+		return null;
+	return f;
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayeredPane.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayeredPane.java
new file mode 100644
index 0000000..b732bc9
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayeredPane.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A figure capable of holding any number of layers. Only layers can be added to this 
+ * figure. Layers are added to this figure with thier respective keys, which are used to
+ * identify them.
+ */
+public class LayeredPane
+	extends Layer
+{
+
+private List layerKeys = new ArrayList();
+
+/**
+ * Constructs a new layered pane with no layers in it.
+ */
+public LayeredPane() {
+	setLayoutManager(new StackLayout());
+}
+
+/**
+ * Adds the given layer figure, identifiable with the given key, at the specified index. 
+ * While adding the layer, it informs the surrounding layers of the addition.
+ *
+ * @param figure the layer
+ * @param layerKey the layer's key
+ * @param index the index where the layer should be added
+ * @since 2.0
+ */
+public void add(IFigure figure, Object layerKey, int index) {
+	if (index == -1) 
+		index = layerKeys.size();
+	super.add(figure, null, index);
+	layerKeys.add(index, layerKey);
+}
+
+/**
+ * Adds the given layer, identifiable with the given key, under the <i>after</i> layer 
+ * provided in the input.
+ *
+ * @param layer the layer
+ * @param key the layer's key
+ * @param after the layer under which the input layer should be added
+ * @since 2.0
+ */
+public void addLayerAfter(Layer layer, Object key, Object after) {
+	int index = layerKeys.indexOf(after);
+	add(layer, key, ++index);
+}
+
+/**
+ * Adds the given layer, identifiable with the given key, above the <i>before</i> layer 
+ * provided in the input.
+ *
+ * @param layer the layer
+ * @param key the layer's key
+ * @param before the layer above which the input layer should be added
+ * @since 2.0
+ */
+public void addLayerBefore(Layer layer, Object key, Object before) {
+	int index = layerKeys.indexOf(before);
+	add(layer, key, index);
+}
+
+/**
+ * Returns the layer identified by the key given in the input.
+ *
+ * @param key the key to identify the desired layer
+ * @return the desired layer
+ * @since 2.0
+ */
+public Layer getLayer(Object key) {
+	int index = layerKeys.indexOf(key);
+	if (index == -1)
+		return null;
+	return (Layer)getChildren().get(index);
+}
+
+/**
+ * Returns the layer at the specified index in this pane.
+ *
+ * @param index the index of the desired layer
+ * @return the desired layer
+ * @since 2.0
+ */
+protected Layer getLayer(int index) {
+	return (Layer)getChildren().get(index);
+}
+
+/**
+ * @see org.eclipse.draw2d.IFigure#remove(org.eclipse.draw2d.IFigure)
+ */
+public void remove(IFigure figure) {
+	int index = getChildren().indexOf(figure);
+	if (index != -1)
+		layerKeys.remove(index);
+	super.remove(figure);
+}
+
+/**
+ * Removes the layer identified by the given key from this layered pane.
+ *
+ * @param key the key of the layer to be removed
+ * @since 2.0
+ */
+public void removeLayer(Object key) {
+	removeLayer(layerKeys.indexOf(key));
+}
+
+/**
+ * Removes the given layer from this layered pane.
+ *
+ * @deprecated call {@link IFigure#remove(IFigure)} instead
+ * @param layer the layer to be removed
+ * @since 2.0
+ */
+public void removeLayer(IFigure layer) {
+	remove(layer);
+}
+
+/**
+ * Removes the layer at the specified index from the list of layers in this layered pane. 
+ * It collapses the layers, occupying the space vacated by the removed layer.
+ *
+ * @param index the index of the layer to be removed
+ * @since 2.0
+ */
+protected void removeLayer(int index) {
+	Layer removeLayer = getLayer(index);
+	remove(removeLayer);	 	
+}
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutAnimator.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutAnimator.java
new file mode 100644
index 0000000..9f558e1
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutAnimator.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.draw2d;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * Animates the layout of a figure's children. The animator will capture the effects of a
+ * layout manager, and then play back the placement of children using linear interpolation
+ * for each child's start and end locations.
+ * <P>
+ * To use an animator, hook it as a layout listener for the figure whose layout is to
+ * be animated, by calling {@link IFigure#addLayoutListener(LayoutListener)}. It is not
+ * necessary to have an animator for every figure in a composition that is undergoing
+ * animation. For example, if a figure without an animator moves during the animation, it
+ * will continue to move and layout its children normally during each step of the
+ * animation.
+ * <P>
+ * Animator must be used in conjunction with layouts. If figures are placed manually using
+ * <code>setBounds()</code>, the animator may not be able to track and playback the
+ * changes that occur.
+ * 
+ * @since 3.2
+ */
+public class LayoutAnimator extends Animator implements LayoutListener {
+
+static final LayoutAnimator INSTANCE = new LayoutAnimator();
+
+/**
+ * Constructs a new Animator. The default instance ({@link #getDefault()}) can be used on
+ * all figures being animated.
+ * 
+ * @since 3.2
+ */
+protected LayoutAnimator() { }
+
+/**
+ * Returns an object encapsulating the placement of children in a container. This method
+ * is called to capture both the initial and final states.
+ * @param container the container figure
+ * @return the current state
+ * @since 3.2
+ */
+protected Object getCurrentState(IFigure container) {
+	Map locations = new HashMap();
+	List children = container.getChildren();
+	IFigure child;
+	for (int i = 0; i < children.size(); i++) {
+		child = (IFigure)children.get(i);
+		locations.put(child, child.getBounds().getCopy());
+	}
+	return locations;
+}
+
+/**
+ * Returns the default instance.
+ * @return the default instance
+ * @since 3.2
+ */
+public static LayoutAnimator getDefault() {
+	return INSTANCE;
+}
+
+/**
+ * Hooks invalidation in case animation is in progress. 
+ * @see LayoutListener#invalidate(IFigure)
+ */
+public final void invalidate(IFigure container) {
+	if (Animation.isInitialRecording())
+		Animation.hookAnimator(container, this);
+}
+
+/**
+ * Hooks layout in case animation is in progress.
+ * @see org.eclipse.draw2d.LayoutListener#layout(org.eclipse.draw2d.IFigure)
+ */
+public final boolean layout(IFigure container) {
+	if (Animation.isAnimating())
+		return Animation.hookPlayback(container, this);
+	return false;
+}
+
+/**
+ * Plays back the animated layout.
+ * @see Animator#playback(IFigure)
+ */
+protected boolean playback(IFigure container) {
+	Map initial = (Map) Animation.getInitialState(this, container);
+	Map ending = (Map) Animation.getFinalState(this, container);
+	if (initial == null)
+		return false;
+	List children = container.getChildren();
+
+	float progress = Animation.getProgress();
+	float ssergorp = 1 - progress;
+
+	Rectangle rect1, rect2;
+	
+	for (int i = 0; i < children.size(); i++) {
+		IFigure child = (IFigure) children.get(i);
+		rect1 = (Rectangle)initial.get(child);
+		rect2 = (Rectangle)ending.get(child);
+		
+		//TODO need to change this to hide the figure until the end.
+		if (rect1 == null)
+			continue;
+		child.setBounds(new Rectangle(
+			Math.round(progress * rect2.x + ssergorp * rect1.x),
+			Math.round(progress * rect2.y + ssergorp * rect1.y),
+			Math.round(progress * rect2.width + ssergorp * rect1.width),
+			Math.round(progress * rect2.height + ssergorp * rect1.height)
+		));
+	}
+	return true;
+}
+
+/**
+ * Hooks post layout in case animation is in progress.
+ * @see LayoutListener#postLayout(IFigure)
+ */
+public final void postLayout(IFigure container) {
+	if (Animation.isFinalRecording())
+		Animation.hookNeedsCapture(container, this);
+}
+
+/**
+ * This callback is unused. Reserved for possible future use.
+ * @see LayoutListener#remove(IFigure)
+ */
+public final void remove(IFigure child) { }
+
+/**
+ * This callback is unused. Reserved for possible future use.
+ * @see LayoutListener#setConstraint(IFigure, Object)
+ */
+public final void setConstraint(IFigure child, Object constraint) { }
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutListener.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutListener.java
new file mode 100644
index 0000000..713d067
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutListener.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.draw2d;
+
+/**
+ * Classes which implement this interface provide callback hooks for various layout
+ * related events.
+ * <P>
+ * Instances can be hooked to figures by calling {@link
+ * IFigure#addLayoutListener(LayoutListener)}. Listeners will be made aware of various
+ * steps of the layout mechanism, and even have the opportunity to prevent normal layout
+ * from occurring.
+ * @since 3.1
+ */
+public interface LayoutListener {
+
+/**
+ * A stub implementation which implements all of the declared methods. 
+ * @since 3.1
+ */
+class Stub implements LayoutListener {
+
+	/**
+	 * Stub which does nothing.
+	 * @see LayoutListener#invalidate(IFigure)
+	 */
+	public void invalidate(IFigure container) { }
+	
+	/**
+	 * Stub which does nothing.
+	 * @see LayoutListener#layout(IFigure)
+	 */
+	public boolean layout(IFigure container) {
+		return false;
+	}
+
+	/**
+	 * Stub which does nothing.
+	 * @see LayoutListener#postLayout(IFigure)
+	 */
+	public void postLayout(IFigure container) { }
+
+	/**
+	 * Stub which does nothing.
+	 * @see LayoutListener#remove(IFigure)
+	 */
+	public void remove(IFigure child) { }
+
+	/**
+	 * Stub which does nothing.
+	 * @see LayoutListener#setConstraint(IFigure, java.lang.Object)
+	 */
+	public void setConstraint(IFigure child, Object constraint) { }
+	
+}
+
+/**
+ * Called when a container has been invalidated.
+ * @param container the invalidated Figure
+ * @since 3.1
+ */
+void invalidate(IFigure container);
+
+/**
+ * Called prior to layout occurring.  A listener may intercept a layout by
+ * returning <code>true</code>.  If the layout is intercepted, the container's
+ * <code>LayoutManager</code> will not receive a layout call.
+ * @param container the figure incurring a layout
+ * @return <code>true</code> if the layout has been intercepted by the listener
+ * @since 3.1
+ */
+boolean layout(IFigure container);
+
+/**
+ * Called after layout has occurred.
+ * @since 3.1
+ * @param container the figure incurring a layout 
+ */
+void postLayout(IFigure container);
+
+/**
+ * Called when a child is about to be removed from its parent.
+ * @since 3.1
+ * @param child the child being removed
+ */
+void remove(IFigure child);
+
+/**
+ * Called when a child's constraint is initialized or updated.
+ * @param child the child being updated
+ * @param constraint the child's new constraint
+ * @since 3.1
+ */
+void setConstraint(IFigure child, Object constraint);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutManager.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutManager.java
new file mode 100644
index 0000000..fc464d4
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LayoutManager.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.draw2d.geometry.Dimension;
+
+/**
+ * A helper for positioning child figures and determining the ideal size for a figure
+ * with children.
+ */
+public interface LayoutManager {
+
+/**
+ * Returns the constraint for the given figure.
+ * @param child The figure
+ * @return The constraint
+ */
+Object getConstraint(IFigure child);
+
+/**
+ * Returns the minimum size of the given figure.
+ * @param container The Figure
+ * @param wHint the width hint
+ * @param hHint the height hint
+ * @return The minimum size
+ */
+Dimension getMinimumSize(IFigure container, int wHint, int hHint);
+
+/**
+ * Returns the preferred size of the given figure, using width and height hints.
+ * @param container The figure
+ * @param wHint The width hint
+ * @param hHint The height hint
+ * @return The preferred size
+ */
+Dimension getPreferredSize(IFigure container, int wHint, int hHint);
+
+/**
+ * Tells the LayoutManager to throw away all cached information about the figures it is
+ * responsible for. This method is called whenever the owning figure is invalidated.
+ */
+void invalidate();
+
+/**
+ * Lays out the given figure.
+ * @param container The figure
+ */
+void layout(IFigure container);
+
+/**
+ * Removes the given child from this layout.
+ * @param child the child being remoced
+ */
+void remove(IFigure child);
+
+/**
+ * Sets the constraint for the given child.
+ * @param child The figure
+ * @param constraint The constraint
+ */
+void setConstraint(IFigure child, Object constraint);
+
+}
diff --git a/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LightweightSystem.java b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LightweightSystem.java
new file mode 100644
index 0000000..54aee04
--- /dev/null
+++ b/visualization/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/LightweightSystem.java
@@ -0,0 +1,547 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.draw2d;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.accessibility.AccessibleControlEvent;
+import org.eclipse.swt.accessibility.AccessibleControlListener;
+import org.eclipse.swt.accessibility.AccessibleEvent;
+import org.eclipse.swt.accessibility.AccessibleListener;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+
+/**
+ * The LightweightSystem is the link between SWT and Draw2d. It is the component that 
+ * provides the ability for {@link Figure Figures} to be hosted on an SWT Canvas.
+ * <p>
+ * Normal procedure for using a LightweightSystem:
+ * <ol>
+ * 		<li>Create an SWT Canvas.
+ * 		<li>Create a LightweightSystem passing it that Canvas. 
+ * 		<li>Create a Draw2d Figure and call setContents(IFigure). This Figure will be the 
+ * 			top-level Figure of the Draw2d application.
+ * </ol>
+ */
+public class LightweightSystem {
+
+private Canvas canvas;
+IFigure contents;
+private IFigure root;
+private EventDispatcher dispatcher;
+private UpdateManager manager = new DeferredUpdateManager();
+private int ignoreResize;
+
+/**
+ * Constructs a LightweightSystem on Canvas <i>c</i>.
+ * 
+ * @param c the canvas
+ * @since 2.0
+ */
+public LightweightSystem(Canvas c) {
+	this();
+	setControl(c);
+}
+
+/**
+ * Constructs a LightweightSystem <b>without</b> a Canvas.
+ */
+public LightweightSystem() {
+	init();
+}
+
+/**
+ * Adds SWT listeners to the LightWeightSystem's Canvas. This allows for SWT events to be 
+ * dispatched and handled by its {@link EventDispatcher}.
+ * <P>
+ * <EM>WARNING:</EM> This method should not be overridden.
+ * @since 2.0
+ */
+protected void addListeners() {
+	EventHandler handler = createEventHandler();
+	canvas.getAccessible().addAccessibleListener(handler);
+	canvas.getAccessible().addAccessibleControlListener(handler);
+	canvas.addMouseListener(handler);
+	canvas.addMouseMoveListener(handler);
+	canvas.addMouseTrackListener(handler);
+	canvas.addKeyListener(handler);
+	canvas.addTraverseListener(handler);
+	canvas.addFocusListener(handler);
+	canvas.addDisposeListener(handler);
+	canvas.addListener(SWT.MouseWheel, handler);
+
+	canvas.addControlListener(new ControlAdapter() {
+		public void controlResized(ControlEvent e) {
+			LightweightSystem.this.controlResized();
+		}
+	});
+	canvas.addListener(SWT.Paint, new Listener() {
+		public void handleEvent(Event e) {
+			LightweightSystem.this.paint(e.gc);
+		}
+	});
+}
+
+/**
+ * Resizes and revalidates the root figure when the control is resized.
+ */
+protected void controlResized() {
+	if (ignoreResize > 0)
+		return;
+	Rectangle r = new Rectangle(canvas.getClientArea());
+	r.setLocation(0, 0);
+	root.setBounds(r);
+	root.revalidate();
+	getUpdateManager().performUpdate();
+}
+
+/**
+ * Returns this LightwightSystem's EventDispatcher.
+ * 
+ * @return the event dispatcher
+ * @since 2.0
+ */
+protected EventDispatcher getEventDispatcher() {
+	if (dispatcher == null)
+		setEventDispatcher(new SWTEventDispatcher());
+	return dispatcher;
+}
+
+/**
+ * Returns this LightweightSystem's root figure.
+ * 
+ * @return the root figure
+ * @since 2.0
+ */
+public IFigure getRootFigure() {
+	return root;
+}
+
+/**
+ * Returns a new instance of this LightweightSystem's EventHandler.
+ * 
+ * @return the newly created event handler
+ * @since 2.0
+ */
+protected final EventHandler createEventHandler() {
+	return internalCreateEventHandler();
+}
+
+/**
+ * Creates and returns the root figure.
+ * 
+ * @return the newly created root figure
+ */
+protected RootFigure createRootFigure() {
+	RootFigure f = new RootFigure();
+	f.addNotify();
+	f.setOpaque(true);
+	f.setLayoutManager(new StackLayout());
+	return f;
+}
+
+/**
+ * Returns this LightweightSystem's UpdateManager.
+ * 
+ * @return the update manager
+ * @since 2.0
+ */
+public UpdateManager getUpdateManager() {
+	return manager;
+}
+
+/**
+ * Initializes this LightweightSystem by setting the root figure.
+ */
+protected void init() {
+	setRootPaneFigure(createRootFigure());
+}
+
+EventHandler internalCreateEventHandler() {
+	return new EventHandler();
+}
+
+/**
+ * Invokes this LightweightSystem's {@link UpdateManager} to paint this 
+ * LightweightSystem's Canvas and contents.
+ * 
+ * @param gc the GC used for painting
+ * @since 2.0
+ */
+public void paint(GC gc) {
+	getUpdateManager().paint(gc);
+}
+
+/**
+ * Sets the contents of the LightweightSystem to the passed figure. This figure should be 
+ * the top-level Figure in a Draw2d application.
+ * 
+ * @param figure the new root figure
+ * @since 2.0
+ */
+public void setContents(IFigure figure) {
+	if (contents != null)
+		root.remove(contents);
+	contents = figure;
+	root.add(contents);
+}
+
+/**
+ * Sets the LightweightSystem's control to the passed Canvas.
+ * 
+ * @param c the canvas
+ * @since 2.0
+ */
+public void setControl(Canvas c) {
+	if (canvas == c)