Fix for missing commit.
diff --git a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest.ide/src/org/eclipse/amp/agf/zest/ide/SpringLayoutModAction.java b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest.ide/src/org/eclipse/amp/agf/zest/ide/SpringLayoutModAction.java
index 701e17f..12ea942 100644
--- a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest.ide/src/org/eclipse/amp/agf/zest/ide/SpringLayoutModAction.java
+++ b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest.ide/src/org/eclipse/amp/agf/zest/ide/SpringLayoutModAction.java
@@ -16,6 +16,7 @@
 package org.eclipse.amp.agf.zest.ide;
 
 import org.eclipse.amp.agf.zest.GraphViewPart;
+import org.eclipse.amp.agf.zest.SpringPartitionLayoutAlgorithm;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
 import org.eclipse.jface.viewers.ISelection;
@@ -33,14 +34,14 @@
 import org.eclipse.ui.IViewActionDelegate;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.zest.layouts.algorithms.AbstractLayoutAlgorithm;
-import org.eclipse.zest.layouts.algorithms.SpringLayoutAlgorithm;
 
 // TODO: Auto-generated Javadoc
 /**
  * The Class SpringLayoutModAction.
  */
 public class SpringLayoutModAction implements IViewActionDelegate {
-    SpringLayoutAlgorithm algorithm;
+
+	SpringPartitionLayoutAlgorithm algorithm;
 
     private boolean modified = false;
 
diff --git a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/GraphViewPart.java b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/GraphViewPart.java
index 40d6ce1..952d721 100644
--- a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/GraphViewPart.java
+++ b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/GraphViewPart.java
@@ -15,8 +15,6 @@
  */
 package org.eclipse.amp.agf.zest;
 
-import javax.swing.LayoutStyle;
-
 import org.eclipse.amp.agf.IGraphicsAdapter;
 import org.eclipse.amp.agf.gef.AGFViewPart;
 import org.eclipse.amp.axf.core.ICompositionProvider;
@@ -38,7 +36,6 @@
 import org.eclipse.zest.core.viewers.GraphViewer;
 import org.eclipse.zest.core.widgets.ZestStyles;
 import org.eclipse.zest.layouts.LayoutAlgorithm;
-import org.eclipse.zest.layouts.algorithms.RadialLayoutAlgorithm;
 
 // TODO: Auto-generated Javadoc
 /**
diff --git a/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/SpringPartitionLayoutAlgorithm.java b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/SpringPartitionLayoutAlgorithm.java
new file mode 100644
index 0000000..e3efbad
--- /dev/null
+++ b/org.eclipse.amp.agf/plugins/org.eclipse.amp.agf.zest/src/org/eclipse/amp/agf/zest/SpringPartitionLayoutAlgorithm.java
@@ -0,0 +1,871 @@
+package org.eclipse.amp.agf.zest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.zest.layouts.LayoutStyles;
+import org.eclipse.zest.layouts.algorithms.ContinuousLayoutAlgorithm;
+import org.eclipse.zest.layouts.dataStructures.DisplayIndependentRectangle;
+import org.eclipse.zest.layouts.dataStructures.InternalNode;
+import org.eclipse.zest.layouts.dataStructures.InternalRelationship;
+
+/**
+ * The SpringLayoutAlgorithm has its own data repository and relation repository. A user can populate the repository,
+ * specify the layout conditions, do the computation and query the computed results.
+ * <p>
+ * Instructions for using SpringLayoutAlgorithm: <br>
+ * 1. Instantiate a SpringLayout object; <br>
+ * 2. Populate the data repository using {@link #add add(...)}; <br>
+ * 3. Populate the relation repository using {@link #addRelation addRelation(...)}; <br>
+ * 4. Execute {@link #compute compute()}; <br>
+ * 5. Execute {@link #fitWithinBounds fitWithinBounds(...)}; <br>
+ * 6. Query the computed results(node size and node position).
+ * 
+ * @version 2.0
+ * @author Ian Bull
+ * @author Casey Best (version 1.0 by Jingwei Wu/Rob Lintern)
+ */
+public class SpringPartitionLayoutAlgorithm extends ContinuousLayoutAlgorithm {
+
+	private final static boolean DEFAULT_ANCHOR = false;
+
+	/**
+	 * The default value for the spring layout number of interations.
+	 */
+	public static final int DEFAULT_SPRING_ITERATIONS = 500;
+
+	/**
+	 * the default value for the time algorithm runs.
+	 */
+	public static final long MAX_SPRING_TIME = 500;
+
+	/**
+	 * The default value for positioning nodes randomly.
+	 */
+	public static final boolean DEFAULT_SPRING_RANDOM = true;
+
+	/**
+	 * The default value for ignoring unconnected nodes.
+	 */
+	public static final boolean DEFAULT_SPRING_IGNORE_UNCON = true;
+
+	/**
+	 * The default value for separating connected components.
+	 */
+	public static final boolean DEFAULT_SPRING_SEPARATE_COMPONENTS = true;
+
+	/**
+	 * The default value for the spring layout move-control.
+	 */
+	public static final double DEFAULT_SPRING_MOVE = 1.0f;
+
+	/**
+	 * The default value for the spring layout strain-control.
+	 */
+	public static final double DEFAULT_SPRING_STRAIN = 1.0f;
+
+	/**
+	 * The default value for the spring layout length-control.
+	 */
+	public static final double DEFAULT_SPRING_LENGTH = 1.0f;
+
+	/**
+	 * The default value for the spring layout gravitation-control.
+	 */
+	public static final double DEFAULT_SPRING_GRAVITATION = 1.0f;
+
+	/**
+	 * The variable can be customized to set the number of iterations used.
+	 */
+	private static int sprIterations = DEFAULT_SPRING_ITERATIONS;
+
+	/**
+	 * This variable can be customized to set the max number of MS the algorithm should run
+	 */
+	private static long maxTimeMS = MAX_SPRING_TIME;
+
+	/**
+	 * The variable can be customized to set whether or not the spring layout nodes are positioned randomly before
+	 * beginning iterations.
+	 */
+	private static boolean sprRandom = DEFAULT_SPRING_RANDOM;
+
+	/**
+	 * Minimum distance considered between nodes
+	 */
+	protected static final double MIN_DISTANCE = 0.001d;
+
+	/**
+	 * An arbitrarily small value in mathematics.
+	 */
+	protected static final double EPSILON = 0.001d;
+
+	/**
+	 * The variable can be customerized to set the spring layout move-control.
+	 */
+	private static double sprMove = DEFAULT_SPRING_MOVE;
+
+	/**
+	 * The variable can be customized to set the spring layout strain-control.
+	 */
+	private static double sprStrain = DEFAULT_SPRING_STRAIN;
+
+	/**
+	 * The variable can be customized to set the spring layout length-control.
+	 */
+	private static double sprLength = DEFAULT_SPRING_LENGTH;
+
+	/**
+	 * The variable can be customized to set the spring layout gravitation-control.
+	 */
+	private static double sprGravitation = DEFAULT_SPRING_GRAVITATION;
+
+	/**
+	 * The largest movement of all vertices that has occured in the most recent iteration.
+	 */
+	private double largestMovement = 0;
+
+	/**
+	 * Maps a src and dest object to the number of relations between them. Key is src.toString() + dest.toString(),
+	 * value is an Integer
+	 */
+	private Map srcDestToNumRelsMap;
+
+	/**
+	 * Maps a src and dest object to the average weight of the relations between them. Key is src.toString() +
+	 * dest.toString(), value is a Double
+	 */
+	private Map srcDestToRelsAvgWeightMap;
+
+	/**
+	 * Maps a relationship type to a weight. Key is a string, value is a Double
+	 */
+	private static Map relTypeToWeightMap = new HashMap();
+
+	private int iteration;
+
+	private int[][] srcDestToNumRels;
+
+	private double[][] srcDestToRelsAvgWeight;
+
+	private double[] tempLocationsX = new double[0];
+
+	private double[] tempLocationsY = new double[0];
+
+	private Map<InternalNode, Integer> indexForEntity = new HashMap<InternalNode, Integer>();
+
+	private double[] forcesX = new double[0];
+
+	private double[] forcesY = new double[0];
+
+	private boolean[] anchors;
+
+	private DisplayIndependentRectangle bounds = null;
+
+	Date date = null;
+
+	/**
+	 * Constructor.
+	 */
+	public SpringPartitionLayoutAlgorithm(int styles) {
+		super(styles);
+		srcDestToNumRelsMap = new HashMap();
+		srcDestToRelsAvgWeightMap = new HashMap();
+		date = new Date();
+	}
+
+	/**
+	 * Creates a sprint layout algoirthm with no style
+	 * 
+	 */
+	public SpringPartitionLayoutAlgorithm() {
+		this(LayoutStyles.NONE);
+	}
+
+	public void setLayoutArea(double x, double y, double width, double height) {
+		bounds = new DisplayIndependentRectangle(x, y, width, height);
+	}
+
+	/**
+	 * Sets the spring layout move-control.
+	 * 
+	 * @param move The move-control value.
+	 */
+	public void setSpringMove(double move) {
+		sprMove = move;
+	}
+
+	/**
+	 * Returns the move-control value of this SpringLayoutAlgorithm in double presion.
+	 * 
+	 * @return The move-control value.
+	 */
+	public double getSpringMove() {
+		return sprMove;
+	}
+
+	/**
+	 * Sets the spring layout strain-control.
+	 * 
+	 * @param strain The strain-control value.
+	 */
+	public void setSpringStrain(double strain) {
+		sprStrain = strain;
+	}
+
+	/**
+	 * Returns the strain-control value of this SpringLayoutAlgorithm in double presion.
+	 * 
+	 * @return The strain-control value.
+	 */
+	public double getSpringStrain() {
+		return sprStrain;
+	}
+
+	/**
+	 * Sets the spring layout length-control.
+	 * 
+	 * @param length The length-control value.
+	 */
+	public void setSpringLength(double length) {
+		sprLength = length;
+	}
+
+	/**
+	 * Gets the max time this algorithm will run for
+	 * 
+	 * @return
+	 */
+	public long getSpringTimeout() {
+		return maxTimeMS;
+	}
+
+	/**
+	 * Sets the spring timeout
+	 * 
+	 * @param timeout
+	 */
+	public void setSpringTimeout(long timeout) {
+		maxTimeMS = timeout;
+	}
+
+	/**
+	 * Returns the length-control value of this SpringLayoutAlgorithm in double presion.
+	 * 
+	 * @return The length-control value.
+	 */
+	public double getSpringLength() {
+		return sprLength;
+	}
+
+	/**
+	 * Sets the spring layout gravitation-control.
+	 * 
+	 * @param gravitation The gravitation-control value.
+	 */
+	public void setSpringGravitation(double gravitation) {
+		sprGravitation = gravitation;
+	}
+
+	/**
+	 * Returns the gravitation-control value of this SpringLayoutAlgorithm in double presion.
+	 * 
+	 * @return The gravitation-control value.
+	 */
+	public double getSpringGravitation() {
+		return sprGravitation;
+	}
+
+	/**
+	 * Sets the number of iterations to be used.
+	 * 
+	 * @param gravitation The number of iterations.
+	 */
+	public void setIterations(int iterations) {
+		sprIterations = iterations;
+	}
+
+	/**
+	 * Returns the number of iterations to be used.
+	 * 
+	 * @return The number of iterations.
+	 */
+	public int getIterations() {
+		return sprIterations;
+	}
+
+	/**
+	 * Sets whether or not this SpringLayoutAlgorithm will layout the nodes randomly before beginning iterations.
+	 * 
+	 * @param random The random placement value.
+	 */
+	public void setRandom(boolean random) {
+		sprRandom = random;
+	}
+
+	/**
+	 * Returns whether or not this SpringLayoutAlgorithm will layout the nodes randomly before beginning iterations.
+	 */
+	public boolean getRandom() {
+		return sprRandom;
+	}
+
+	public void setWeight(String relType, double weight) {
+		relTypeToWeightMap.put(relType, new Double(weight));
+	}
+
+	public double getWeight(String relType) {
+		Double weight = (Double) relTypeToWeightMap.get(relType);
+		return (weight == null) ? 1 : weight.doubleValue();
+	}
+
+	/**
+	 * Sets the default conditions.
+	 */
+	public void setDefaultConditions() {
+		// sprMove = DEFAULT_SPRING_MOVE;
+		// sprStrain = DEFAULT_SPRING_STRAIN;
+		// sprLength = DEFAULT_SPRING_LENGTH;
+		// sprGravitation = DEFAULT_SPRING_GRAVITATION;
+		// sprIterations = DEFAULT_SPRING_ITERATIONS;
+	}
+
+	/**
+	 * Clean up after done
+	 * 
+	 * @param entitiesToLayout
+	 */
+	private void reset(InternalNode[] entitiesToLayout) {
+		resetTemps(entitiesToLayout);
+		anchors = null;
+		setDefaultConditions();
+		srcDestToNumRelsMap = new HashMap();
+		srcDestToRelsAvgWeightMap = new HashMap();
+		relTypeToWeightMap = new HashMap();
+	}
+
+	private long startTime = 0;
+
+	private boolean clearLocation = true;
+
+	protected void preLayoutAlgorithm(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider,
+			double x, double y, double width, double height) {
+		// TODO: Filter out any non-wanted entities and relationships
+		// super.applyLayout(entitiesToLayout, relationshipsToConsider, x, y,
+		// width, height);
+		// InternalNode[] a_entitiesToLayout = (InternalNode[]) entitiesToLayout.toArray(new
+		// InternalNode[entitiesToLayout.size()]);
+		bounds = new DisplayIndependentRectangle(x, y, width, height);
+		resetTemps(entitiesToLayout);
+		anchors = new boolean[entitiesToLayout.length];
+
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			anchors[i] = DEFAULT_ANCHOR;
+		}
+		for (int i = 0; i < relationshipsToConsider.length; i++) {
+			InternalRelationship layoutRelationship = relationshipsToConsider[i];
+			addRelation(layoutRelationship);
+		}
+
+		// do the calculations
+		preCompute(entitiesToLayout);
+		startTime = date.getTime();
+	}
+
+	/**
+	 * @param entitiesToLayout
+	 */
+	private void resetTemps(InternalNode[] entitiesToLayout) {
+		if (tempLocationsX.length != entitiesToLayout.length) {
+			tempLocationsX = Arrays.copyOf(tempLocationsX, entitiesToLayout.length);
+			tempLocationsY = Arrays.copyOf(tempLocationsY, entitiesToLayout.length);
+		}
+		// forcesX = Arrays.copyOf(forcesX, entitiesToLayout.length);
+		// forcesY = Arrays.copyOf(forcesY, entitiesToLayout.length);
+		forcesX = new double[entitiesToLayout.length];
+		forcesY = new double[entitiesToLayout.length];
+
+		int i = 0;
+		for (InternalNode internalNode : entitiesToLayout) {
+			indexForEntity.put(internalNode, i++);
+		}
+	}
+
+	protected void postLayoutAlgorithm(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider) {
+		reset(entitiesToLayout);
+	}
+
+	Map<InternalNode, Collection<InternalNode>> targetsForNode = new HashMap<InternalNode, Collection<InternalNode>>();
+
+	/**
+	 * Adds a simple relation between two nodes to the relation repository.
+	 * 
+	 * @param layoutRelationship The simple relation to be added
+	 * @throws java.lang.NullPointerExcetption If <code>sr</code> is null
+	 * @see SimpleRelation
+	 */
+	private void addRelation(InternalRelationship layoutRelationship) {
+		if (layoutRelationship == null) {
+			throw new IllegalArgumentException("The arguments can not be null!");
+		} else {
+			addToRelationMap(layoutRelationship.getSource(), layoutRelationship.getDestination());
+			addToRelationMap(layoutRelationship.getDestination(), layoutRelationship.getSource());
+			double weight = layoutRelationship.getWeight();
+			weight = (weight <= 0 ? 0.1 : weight);
+			String key1 = layoutRelationship.getSource().toString() + layoutRelationship.getDestination().toString();
+			String key2 = layoutRelationship.getDestination().toString() + layoutRelationship.getSource().toString();
+			String[] keys = { key1, key2 };
+			for (int i = 0; i < keys.length; i++) {
+				String key = keys[i];
+				Integer count = (Integer) srcDestToNumRelsMap.get(key);
+				Double avgWeight = (Double) srcDestToRelsAvgWeightMap.get(key);
+				if (count == null) {
+					count = new Integer(1);
+					avgWeight = new Double(weight);
+				} else {
+					int newCount = count.intValue() + 1;
+					double newAverage = (avgWeight.doubleValue() * count.doubleValue() + weight) / newCount;
+					avgWeight = new Double(newAverage);
+					count = new Integer(newCount);
+				}
+				srcDestToNumRelsMap.put(key, count);
+				srcDestToRelsAvgWeightMap.put(key, avgWeight);
+			}
+		}
+	}
+
+	/**
+	 * @param layoutRelationship
+	 */
+	private void addToRelationMap(InternalNode source, InternalNode target) {
+		Collection<InternalNode> targets = targetsForNode.get(source);
+		if (targets == null) {
+			targets = new ArrayList<InternalNode>();
+			targetsForNode.put(source, targets);
+		}
+		targets.add(target);
+	}
+
+	private void preCompute(InternalNode[] entitiesToLayout) {
+		// count number of relationships between all nodes and the average
+		// weight between them
+		srcDestToNumRels = new int[entitiesToLayout.length][entitiesToLayout.length];
+		srcDestToRelsAvgWeight = new double[entitiesToLayout.length][entitiesToLayout.length];
+
+		for (int i = 0; i < entitiesToLayout.length - 1; i++) {
+			InternalNode layoutEntity1 = entitiesToLayout[i];
+			for (int j = i + 1; j < entitiesToLayout.length; j++) {
+				InternalNode layoutEntity2 = entitiesToLayout[j];
+				srcDestToNumRels[i][j] = numRelations(layoutEntity1, layoutEntity2);
+				srcDestToNumRels[i][j] += numRelations(layoutEntity2, layoutEntity1);
+				srcDestToRelsAvgWeight[i][j] = avgWeight(layoutEntity1, layoutEntity2);
+			}
+		}
+
+		initialPlacement(entitiesToLayout);
+
+		iteration = 1;
+		largestMovement = Double.MAX_VALUE;
+	}
+
+	/**
+	 * @param entitiesToLayout
+	 */
+	private void initialPlacement(InternalNode[] entitiesToLayout) {
+		if (clearLocation) {
+			if (sprRandom) {
+				placeRandomly(entitiesToLayout); // put vertices in random places
+			} else {
+				convertToUnitCoordinates(entitiesToLayout);
+			}
+		}
+		// clearLocation = false;
+	}
+
+	// TODO: This is a complete Clone! (and not in a good way)
+	protected DisplayIndependentRectangle getLayoutBoundsTemp(InternalNode[] entitiesToLayout, boolean includeNodeSize) {
+		double rightSide = Double.MIN_VALUE;
+		double bottomSide = Double.MIN_VALUE;
+		double leftSide = Double.MAX_VALUE;
+		double topSide = Double.MAX_VALUE;
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			double x = tempLocationsX[i];
+			double y = tempLocationsY[i];
+
+			leftSide = Math.min(x, leftSide);
+			topSide = Math.min(y, topSide);
+			rightSide = Math.max(x, rightSide);
+			bottomSide = Math.max(y, bottomSide);
+
+		}
+		return new DisplayIndependentRectangle(leftSide, topSide, rightSide - leftSide, bottomSide - topSide);
+	}
+
+	protected void convertNodePositionsBack(int i, InternalNode entityToConvert, double px, double py,
+			double screenWidth, double screenHeight, DisplayIndependentRectangle layoutBounds) {
+
+		// If the node selected is outside the screen, map it to the boarder
+		if (px > screenWidth) px = screenWidth;
+		if (py > screenHeight) py = screenHeight;
+
+		if (px < 0) px = 1;
+		if (py < 0) py = 1;
+
+		double x = (px / screenWidth) * layoutBounds.width + layoutBounds.x;
+		double y = (py / screenHeight) * layoutBounds.height + layoutBounds.y;
+
+		tempLocationsX[i] = x;
+		tempLocationsY[i] = y;
+		// setTempLocation(entityToConvert, new DisplayIndependentPoint(x, y));
+
+		if (entityToConvert.getInternalX() < 0) {
+			// System.out.println("We have nodes less than 0 here!");
+		}
+
+	}
+
+	private void checkPreferredLocation(InternalNode[] entitiesToLayout, DisplayIndependentRectangle realBounds) {
+		// use 10% for the border - 5% on each side
+		double borderWidth = Math.min(realBounds.width, realBounds.height) / 10.0;
+		DisplayIndependentRectangle screenBounds = new DisplayIndependentRectangle(realBounds.x + borderWidth / 2.0,
+			realBounds.y + borderWidth / 2.0, realBounds.width - borderWidth, realBounds.height - borderWidth);
+
+		DisplayIndependentRectangle layoutBounds = getLayoutBoundsTemp(entitiesToLayout, false);
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			InternalNode layoutEntity = entitiesToLayout[i];
+			if (layoutEntity.hasPreferredLocation()) {
+				convertNodePositionsBack(	i, layoutEntity, layoutEntity.getPreferredX(),
+											layoutEntity.getPreferredY(),
+											screenBounds.width, screenBounds.height, layoutBounds);
+			}
+		}
+	}
+
+	/**
+	 * Scales the current iteration counter based on how long the algorithm has been running for. You can set the
+	 * MaxTime in maxTimeMS!
+	 */
+	private void setSprIterationsBasedOnTime() {
+		if (maxTimeMS <= 0) return;
+
+		long currentTime = date.getTime();
+		double fractionComplete = (double) ((double) (currentTime - startTime) / ((double) maxTimeMS));
+		int currentIteration = (int) (fractionComplete * sprIterations);
+		if (currentIteration > iteration) {
+			iteration = currentIteration;
+		}
+
+	}
+
+	protected boolean performAnotherNonContinuousIteration() {
+		setSprIterationsBasedOnTime();
+		if (iteration <= sprIterations && largestMovement >= sprMove)
+			return true;
+		else
+			return false;
+	}
+
+	protected int getCurrentLayoutStep() {
+		return iteration;
+	}
+
+	protected int getTotalNumberOfLayoutSteps() {
+		return sprIterations;
+	}
+
+	protected void computeOneIteration(InternalNode[] entitiesToLayout, InternalRelationship[] relationshipsToConsider,
+			double x, double y, double width, double height) {
+		DisplayIndependentRectangle oldBounds = bounds;
+		if (bounds == null) bounds = new DisplayIndependentRectangle(x, y, width, height);
+		checkPreferredLocation(entitiesToLayout, bounds);
+		computeForces(entitiesToLayout);
+		largestMovement = Double.MAX_VALUE;
+		computePositions(entitiesToLayout);
+
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			InternalNode layoutEntity = entitiesToLayout[i];
+			layoutEntity.setInternalLocation(tempLocationsX[i], tempLocationsY[i]);
+		}
+
+		if (!oldBounds.equals(bounds) || iteration % 10 == 0) {
+			defaultFitWithinBounds(entitiesToLayout, bounds);
+		}
+		iteration++;
+	}
+
+	/**
+	 * Puts vertices in random places, all between (0,0) and (1,1).
+	 */
+	public void placeRandomly(InternalNode[] entitiesToLayout) {
+		// If only one node in the data repository, put it in the middle
+		if (entitiesToLayout.length == 1) {
+			// If only one node in the data repository, put it in the middle
+			tempLocationsX[0] = 0.5;
+			tempLocationsY[0] = 0.5;
+		} else {
+			for (int i = 0; i < entitiesToLayout.length; i++) {
+				if (tempLocationsX[i] == 0.0 || tempLocationsY[i] == 0.0) {
+					if (i == 0) {
+						tempLocationsX[i] = 0.0;
+						tempLocationsY[i] = 0.0;
+					} else if (i == 1) {
+						tempLocationsX[i] = 1.0;
+						tempLocationsY[i] = 1.0;
+					} else {
+						tempLocationsX[i] = Math.random();
+						tempLocationsY[i] = Math.random();
+					}
+				}
+			}
+		}
+	}
+
+	// /////////////////////////////////////////////////////////////////
+	// /// Protected Methods /////
+	// /////////////////////////////////////////////////////////////////
+
+	/**
+	 * Computes the force for each node in this SpringLayoutAlgorithm. The computed force will be stored in the data
+	 * repository
+	 */
+	protected void computeForces(InternalNode[] entitiesToLayout) {
+
+		// initialize all forces to zero
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			forcesX[i] = 0.0;
+			forcesY[i] = 0.0;
+		}
+
+		// TODO: Again really really slow!
+
+		for (int i = 0; i < entitiesToLayout.length - 1; i++) {
+			InternalNode sourceEntity = entitiesToLayout[i];
+
+			double srcLocationX = tempLocationsX[i];
+			double srcLocationY = tempLocationsY[i];
+			double fx = forcesX[i]; // force in x direction
+			double fy = forcesY[i]; // force in y direction
+
+			// Collection<InternalNode> entityTargets= targetsForNode.get(sourceEntity);
+			// for (InternalNode destinationEntity : entityTargets) {
+			// if (!destinationEntity.equals(sourceEntity)) {
+			// int j = indexForEntity.get(destinationEntity);
+			// double destLocationX = tempLocationsX[j];
+			// double destLocationY = tempLocationsY[j];
+			// double dx = srcLocationX - destLocationX;
+			// double dy = srcLocationY - destLocationY;
+			// double distance = Math.sqrt(dx * dx + dy * dy);
+			// double distance_sq = distance * distance;
+			// // make sure distance and distance squared not too small
+			// distance = Math.max(MIN_DISTANCE, distance);
+			//
+			// // If there are relationships between srcObj and destObj
+			// // then decrease force on srcObj (a pull) in direction of destObj
+			// // If no relation between srcObj and destObj then increase
+			// // force on srcObj (a push) from direction of destObj.
+			// int numRels = srcDestToNumRels[i][j];
+			// double avgWeight = srcDestToRelsAvgWeight[i][j];
+			// if (numRels > 0) {
+			// // nodes are pulled towards each other
+			// double f = sprStrain * Math.log(distance / sprLength) * numRels * avgWeight;
+			//
+			// fx = fx - (f * dx / distance);
+			// fy = fy - (f * dy / distance);
+			//
+			// } else {
+			// // nodes are repelled from each other
+			// // double f = Math.min(100, sprGravitation / (distance*distance));
+			// double f = sprGravitation / (distance_sq);
+			// fx = fx + (f * dx / distance);
+			// fy = fy + (f * dy / distance);
+			// }
+			//
+			// // According to Newton, "for every action, there is an equal
+			// // and opposite reaction."
+			// // so give the dest an opposite force
+			// forcesX[j] = forcesX[j] - fx;
+			// forcesY[j] = forcesY[j] - fy;
+			// }
+			// }
+
+//			double prob = 0.2;
+
+			for (int j = i + 1; j < entitiesToLayout.length; j++) {
+
+				// for (int k = 0; k < 100; k++) {
+				// int j = (int) (Math.random() * (double) entitiesToLayout.length);
+				InternalNode destinationEntity = entitiesToLayout[j];
+
+				if (!destinationEntity.equals(sourceEntity)) {
+//					if (Math.random() < prob) {
+						double destLocationX = tempLocationsX[j];
+						double destLocationY = tempLocationsY[j];
+						double dx = srcLocationX - destLocationX;
+						double dy = srcLocationY - destLocationY;
+						double distance = Math.sqrt(dx * dx + dy * dy);
+						double distance_sq = distance * distance;
+						// make sure distance and distance squared not too small
+						distance = Math.max(MIN_DISTANCE, distance);
+
+						// If there are relationships between srcObj and destObj
+						// then decrease force on srcObj (a pull) in direction of destObj
+						// If no relation between srcObj and destObj then increase
+						// force on srcObj (a push) from direction of destObj.
+						int numRels = srcDestToNumRels[i][j];
+						double avgWeight = srcDestToRelsAvgWeight[i][j];
+						if (numRels > 0) {
+							// nodes are pulled towards each other
+							double f = sprStrain * Math.log(distance / sprLength) * numRels * avgWeight;
+
+							fx = fx - (f * dx / distance);
+							fy = fy - (f * dy / distance);
+
+						} else {
+							// nodes are repelled from each other
+							// double f = Math.min(100, sprGravitation / (distance*distance));
+							double f = (sprGravitation / (distance_sq));
+							fx = fx + (f * dx / distance);
+							fy = fy + (f * dy / distance);
+						}
+
+						// According to Newton, "for every action, there is an equal
+						// and opposite reaction."
+						// so give the dest an opposite force
+						forcesX[j] = forcesX[j] - fx;
+						forcesY[j] = forcesY[j] - fy;
+//					}
+				}
+			}
+
+			/*
+			 * //make sure forces aren't too big if (fx > 0 ) fx = Math.min(fx, 10*sprMove); else fx = Math.max(fx,
+			 * -10*sprMove); if (fy > 0) fy = Math.min(fy, 10*sprMove); else fy = Math.max(fy, -10*sprMove);
+			 */
+			forcesX[i] = fx;
+			forcesY[i] = fy;
+			// Remove the src object from the list of destinations since
+			// we've already calculated the force from it on all other
+			// objects.
+			// dests.remove(srcObj);
+
+		}
+	}
+
+	/**
+	 * Computes the position for each node in this SpringLayoutAlgorithm. The computed position will be stored in the
+	 * data repository. position = position + sprMove * force
+	 */
+	protected void computePositions(InternalNode[] entitiesToLayout) {
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			if (!anchors[i] || entitiesToLayout[i].hasPreferredLocation()) {
+				double oldX = tempLocationsX[i];
+				double oldY = tempLocationsY[i];
+				double deltaX = sprMove * forcesX[i];
+				double deltaY = sprMove * forcesY[i];
+
+				// constrain movement, so that nodes don't shoot way off to the edge
+				double maxMovement = 0.2d * sprMove;
+				if (deltaX >= 0) {
+					deltaX = Math.min(deltaX, maxMovement);
+				} else {
+					deltaX = Math.max(deltaX, -maxMovement);
+				}
+				if (deltaY >= 0) {
+					deltaY = Math.min(deltaY, maxMovement);
+				} else {
+					deltaY = Math.max(deltaY, -maxMovement);
+				}
+
+				largestMovement = Math.max(largestMovement, Math.abs(deltaX));
+				largestMovement = Math.max(largestMovement, Math.abs(deltaY));
+
+				double newX = oldX + deltaX;
+				double newY = oldY + deltaY;
+				tempLocationsX[i] = newX;
+				tempLocationsY[i] = newY;
+			}
+
+		}
+
+	}
+
+	/**
+	 * Converts the position for each node in this SpringLayoutAlgorithm to unit coordinates in double precision. The
+	 * computed positions will be still stored in the data repository.
+	 */
+	protected void convertToUnitCoordinates(InternalNode[] entitiesToLayout) {
+		double minX = Double.MAX_VALUE;
+		double maxX = Double.MIN_VALUE;
+		double minY = Double.MAX_VALUE;
+		double maxY = Double.MIN_VALUE;
+		for (int i = 0; i < entitiesToLayout.length; i++) {
+			InternalNode layoutEntity = entitiesToLayout[i];
+			minX = Math.min(minX, layoutEntity.getInternalX());
+			minY = Math.min(minY, layoutEntity.getInternalY());
+			maxX = Math.max(maxX, layoutEntity.getInternalX());
+			maxY = Math.max(maxY, layoutEntity.getInternalY());
+		}
+
+		double spanX = maxX - minX;
+		double spanY = maxY - minY;
+		double maxSpan = Math.max(spanX, spanY);
+
+		if (maxSpan > EPSILON) {
+			for (int i = 0; i < entitiesToLayout.length; i++) {
+				InternalNode layoutEntity = entitiesToLayout[i];
+				double x = (layoutEntity.getInternalX() - minX) / spanX;
+				double y = (layoutEntity.getInternalY() - minY) / spanY;
+				tempLocationsX[i] = x;
+				tempLocationsY[i] = y;
+			}
+		} else {
+			placeRandomly(entitiesToLayout);
+		}
+	}
+
+	/**
+	 * Examines the number of specified relation between the <code>src</code> and the <code>dest</code> that exist in
+	 * this SpringLayoutAlgorithm's relation repository.
+	 * 
+	 * @param src The source part of the relaton to be examined.
+	 * @param dest The destination part of the relation to be examined.
+	 * @return The number of relations between src and dest.
+	 */
+	private int numRelations(Object src, Object dest) {
+		String key = src.toString() + dest.toString();
+		Integer count = (Integer) srcDestToNumRelsMap.get(key);
+		int intCount = (count == null) ? 0 : count.intValue();
+		return intCount;
+	}
+
+	/**
+	 * Returns the average weight between a src and dest object.
+	 * 
+	 * @param src
+	 * @param dest
+	 * @return The average weight between the given src and dest nodes
+	 */
+	private double avgWeight(Object src, Object dest) {
+		String key = src.toString() + dest.toString();
+		Double avgWeight = (Double) srcDestToRelsAvgWeightMap.get(key);
+		double doubleWeight = (avgWeight == null) ? 1 : avgWeight.doubleValue();
+		return doubleWeight;
+	}
+
+	protected boolean isValidConfiguration(boolean asynchronous, boolean continueous) {
+		if (asynchronous && continueous)
+			return true;
+		else if (asynchronous && !continueous)
+			return true;
+		else if (!asynchronous && continueous)
+			return false;
+		else if (!asynchronous && !continueous) return true;
+
+		return false;
+	}
+
+}
diff --git a/releng/org.eclipse.amp.releng/releng/amp.rmap b/releng/org.eclipse.amp.releng/releng/amp.rmap
index 003d995..59bd806 100644
--- a/releng/org.eclipse.amp.releng/releng/amp.rmap
+++ b/releng/org.eclipse.amp.releng/releng/amp.rmap
@@ -60,6 +60,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 	<rm:searchPath name="amp.releng">
@@ -70,6 +71,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 
@@ -122,6 +124,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 		<rm:provider componentTypes="eclipse.feature" readerType="git" resolutionFilter="">
 			<rm:uri format="{0},{1}/features/{2}-feature">
@@ -139,6 +142,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 
@@ -158,6 +162,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 
@@ -177,6 +182,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 
@@ -204,6 +210,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 
@@ -239,6 +246,7 @@
 			</rm:uri>
 			<rm:property key="git.remote.uri" value="git://dev.eclipse.org/org.eclipse.amp/org.eclipse.amp.git" />
 			<rm:property key="git.remote.name" value="org.eclipse.amp" />
+			<rm:property key="git.auto.fetch" value="true" />
 		</rm:provider>
 	</rm:searchPath>
 	<rm:searchPath name="gef3d">