diff --git a/bundles/org.eclipse.rap.draw2d.compatibility/src/org/eclipse/draw2d/rap/swt/graphics/FontUtil.java b/bundles/org.eclipse.rap.draw2d.compatibility/src/org/eclipse/draw2d/rap/swt/graphics/FontUtil.java
new file mode 100644
index 0000000..e281288
--- /dev/null
+++ b/bundles/org.eclipse.rap.draw2d.compatibility/src/org/eclipse/draw2d/rap/swt/graphics/FontUtil.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2015. 
+ * 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: 
+ *   Arnaud Mergey - initial API and implementation
+*******************************************************************************/
+package org.eclipse.draw2d.rap.swt.graphics;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jface.resource.ColorRegistry;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.RGB;
+
+
+public class FontUtil {
+
+  private final static String FONT_KEY = "DRAW2D_{0}_{1}_{2}"; //$NON-NLS-1$
+
+  public static Font getFont( FontData[] fontData ) {
+    String key = MessageFormat.format( FONT_KEY,
+                                       fontData[ 0 ].getName(),
+                                       fontData[ 0 ].getHeight(),
+                                       fontData[ 0 ].getStyle() );
+    FontRegistry reg = JFaceResources.getFontRegistry();
+    if(! reg.hasValueFor( key ) ) {
+      reg.put( key, fontData );
+    }
+    return reg.get( key );
+  }
+}
diff --git a/bundles/org.eclipse.rap.draw2d/src/org/eclipse/draw2d/FigureUtilities.java b/bundles/org.eclipse.rap.draw2d/src/org/eclipse/draw2d/FigureUtilities.java
index b05ed74..0332547 100644
--- a/bundles/org.eclipse.rap.draw2d/src/org/eclipse/draw2d/FigureUtilities.java
+++ b/bundles/org.eclipse.rap.draw2d/src/org/eclipse/draw2d/FigureUtilities.java
@@ -15,6 +15,7 @@
 import org.eclipse.draw2d.geometry.Dimension;
 import org.eclipse.draw2d.geometry.Rectangle;
 import org.eclipse.draw2d.rap.swt.graphics.ColorUtil;
+import org.eclipse.draw2d.rap.swt.graphics.FontUtil;
 import org.eclipse.rap.rwt.SingletonUtil;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Font;
@@ -22,442 +23,389 @@
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.widgets.Shell;
 
+
 /**
  * Provides miscellaneous Figure operations.
  */
 public class FigureUtilities {
 
-	private static final float RGB_VALUE_MULTIPLIER = 0.6f;
-	//[RAP AM] remove static usage
-	private GC gc;
-    private Font appliedFont;
-    private FontMetrics metrics;
-	//private static Color ghostFillColor = new Color(null, 31, 31, 31);
-	private static Color ghostFillColor() {
-	   return ColorUtil.getColor( 31, 31, 31 );
+  private static final float RGB_VALUE_MULTIPLIER = 0.6f;
+  // [RAP AM] remove static usage
+  private GC gc;
+  private Font appliedFont;
+  private FontMetrics metrics;
+
+  // private static Color ghostFillColor = new Color(null, 31, 31, 31);
+  private static Color ghostFillColor() {
+    return ColorUtil.getColor( 31, 31, 31 );
+  }
+
+  private static FigureUtilities instance() {
+    return SingletonUtil.getSessionInstance( FigureUtilities.class );
+  }
+
+  /**
+   * 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 );
+    FigureUtilities fu = instance();
+    if( fu.metrics == null )
+      fu.metrics = getGC().getFontMetrics();
+    return fu.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() {
+    FigureUtilities fu = instance();
+    if( fu.gc == null ) {
+      fu.gc = new GC( new Shell() );
+      fu.appliedFont = fu.gc.getFont();
     }
-	
-	private static FigureUtilities instance() {
-	  return SingletonUtil.getSessionInstance( FigureUtilities.class );
-	}
-	
-	/**
-	 * 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));
-	}
+    return fu.gc;
+  }
 
-	/**
-	 * 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);
-		FigureUtilities fu = instance();
-		if (fu.metrics == null)
-			fu.metrics = getGC().getFontMetrics();
-		return fu.metrics;
-	}
+  /**
+   * 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 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() {
-	    FigureUtilities fu = instance();
-		if (fu.gc == null) {
-			fu.gc = new GC(new Shell());
-			fu.appliedFont = fu.gc.getFont();
-		}
-		return fu.gc;
-	}
+  /**
+   * 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>.
-	 * 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 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 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 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 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 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 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 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 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 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 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 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 ) ) );
+  }
 
-	/**
-	 * 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;
-	}
+  /**
+   * 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;
+  }
 
-	/**
-	 * 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();
+  /**
+   * 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 ) ) );
+  }
 
-		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)));
-	}
+  /**
+   * 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 );
+  }
 
-	/**
-	 * 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;
-	}
+  /**
+   * 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 );
+  }
 
-	/**
-	 * 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)));
-	}
+  /**
+   * 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.getSINGLETON() );
+    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 );
+    }
+  }
 
-	/**
-	 * 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 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 );
+  }
 
-	/**
-	 * 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;
+  /**
+   * Sets Font to passed value.
+   * 
+   * @param f the new font
+   * @since 2.0
+   */
+  protected static void setFont( Font f ) {
+    FigureUtilities fu = instance();
+    f = FontUtil.getFont( f.getFontData() );
+    getGC().setFont( f );
+    fu.appliedFont = f;
+    fu.metrics = null;
+  }
 
-		g.setLineStyle(Graphics.LINE_SOLID);
-		g.setLineWidth(1);
-		g.setXORMode(false);
+  /**
+   * Returns the figure which is the nearest common ancestor of both figures, or <code>null</code>
+   * if there is no common ancestor. 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 is the ancestor of the other,
+   * it is returned as the common ancestor.
+   * 
+   * @since 3.1
+   * @param l left
+   * @param r right
+   * @return the common ancestor, if it exists, or <code>null</code>.
+   */
+  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;
+    for( int i = 0; i < left.size(); i++ ) {
+      if( right.contains( left.get( i ) ) )
+        return ( IFigure )left.get( i );
+    }
+    return null;
+  }
 
-		w -= 2;
-		h -= 2;
+  /**
+   * 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;
+  }
 
-		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.getSINGLETON());
-
-		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) {
-	    FigureUtilities fu = instance();
-		if (fu.appliedFont == f || (f != null && f.equals(fu.appliedFont)))
-			return;
-		getGC().setFont(f);
-		fu.appliedFont = f;
-		fu.metrics = null;
-	}
-
-	/**
-	 * Returns the figure which is the nearest common ancestor of both figures,
-	 * or <code>null</code> if there is no common ancestor. 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 is the ancestor of the other, it
-	 * is returned as the common ancestor.
-	 * 
-	 * @since 3.1
-	 * @param l
-	 *            left
-	 * @param r
-	 *            right
-	 * @return the common ancestor, if it exists, or <code>null</code>.
-	 */
-	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;
-
-		for (int i = 0; i < left.size(); i++) {
-			if (right.contains(left.get(i)))
-				return (IFigure) left.get(i);
-		}
-		return null;
-	}
-
-	/**
-	 * 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;
-	}
-
-	/**
-	 * Determines whether the given figure is showing and not (completely)
-	 * clipped.
-	 * 
-	 * @param figure
-	 *            The figure to test
-	 * @return <code>true</code> if the given figure is showing and not
-	 *         completely clipped, <code>false</code> otherwise.
-	 * @since 3.7
-	 */
-	public static boolean isNotFullyClipped(IFigure figure) {
-		if (figure == null || !figure.isShowing()) {
-			return false;
-		}
-		// check if figure is clipped
-		// TODO: IClippingStrategy has to be taken into consideration as well.
-		Rectangle figBounds = figure.getBounds().getCopy();
-		IFigure walker = figure.getParent();
-		while (!figBounds.isEmpty() && walker != null) {
-			walker.translateToParent(figBounds);
-			figBounds.intersect(walker.getBounds());
-			walker = walker.getParent();
-		}
-		return !figBounds.isEmpty();
-	}
-
+  /**
+   * Determines whether the given figure is showing and not (completely) clipped.
+   * 
+   * @param figure The figure to test
+   * @return <code>true</code> if the given figure is showing and not completely clipped,
+   *         <code>false</code> otherwise.
+   * @since 3.7
+   */
+  public static boolean isNotFullyClipped( IFigure figure ) {
+    if( figure == null || !figure.isShowing() ) {
+      return false;
+    }
+    // check if figure is clipped
+    // TODO: IClippingStrategy has to be taken into consideration as well.
+    Rectangle figBounds = figure.getBounds().getCopy();
+    IFigure walker = figure.getParent();
+    while( !figBounds.isEmpty() && walker != null ) {
+      walker.translateToParent( figBounds );
+      figBounds.intersect( walker.getBounds() );
+      walker = walker.getParent();
+    }
+    return !figBounds.isEmpty();
+  }
 }
diff --git a/bundles/org.eclipse.rap.gef.demo/RAP GEF Demo.launch b/bundles/org.eclipse.rap.gef.demo/RAP GEF Demo.launch
index 23aa529..268dbb7 100644
--- a/bundles/org.eclipse.rap.gef.demo/RAP GEF Demo.launch
+++ b/bundles/org.eclipse.rap.gef.demo/RAP GEF Demo.launch
@@ -14,7 +14,7 @@
 <intAttribute key="default_start_level" value="4"/>
 <booleanAttribute key="includeOptional" value="false"/>
 <booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
-<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-7-openjdk-amd64"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/java-8-oracle"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -console -consolelog"/>
 <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
 <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Declipse.ignoreApp=true -Dosgi.noShutdown=true"/>
@@ -37,7 +37,7 @@
 <booleanAttribute key="org.eclipse.rap.launch.useSessionTimeout" value="false"/>
 <stringAttribute key="pde.version" value="3.3"/>
 <booleanAttribute key="show_selected_only" value="false"/>
-<stringAttribute key="target_bundles" value="com.ibm.icu.base@default:default,javax.servlet*3.1.0.v201410161800@default:default,javax.xml@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.jobs*3.7.0.v20150115-2226@default:default,org.eclipse.core.runtime@default:true,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common*3.6.200.v20141113-1308@2:true,org.eclipse.equinox.console*1.1.100.v20141023-1406@default:default,org.eclipse.equinox.http.jetty*3.1.0.v20141113-1503@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.equinox.http.servlet*1.2.0.v20150120-1816@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jetty.http*9.2.5.v20141112@default:default,org.eclipse.jetty.io*9.2.5.v20141112@default:default,org.eclipse.jetty.security*9.2.5.v20141112@default:default,org.eclipse.jetty.server*9.2.5.v20141112@default:default,org.eclipse.jetty.servlet*9.2.5.v20141112@default:default,org.eclipse.jetty.util*9.2.5.v20141112@default:default,org.eclipse.osgi*3.10.100.v20150129-2253@-1:true,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services*3.5.0.v20150126-1936@default:default,org.eclipse.rap.jface.databinding@default:default,org.eclipse.rap.jface@default:default,org.eclipse.rap.rwt.osgi@default:default,org.eclipse.rap.rwt@default:default,org.eclipse.rap.ui.views@default:default,org.eclipse.rap.ui.workbench@default:default,org.eclipse.rap.ui@default:default"/>
+<stringAttribute key="target_bundles" value="com.ibm.icu.base@default:default,javax.servlet@default:default,javax.xml@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.runtime@default:true,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.equinox.http.jetty@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.help@default:default,org.eclipse.jetty.http@default:default,org.eclipse.jetty.io@default:default,org.eclipse.jetty.security@default:default,org.eclipse.jetty.server@default:default,org.eclipse.jetty.servlet@default:default,org.eclipse.jetty.util@default:default,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.rap.jface.databinding@default:default,org.eclipse.rap.jface@default:default,org.eclipse.rap.rwt.osgi@default:default,org.eclipse.rap.rwt.testfixture@default:default,org.eclipse.rap.rwt@default:default,org.eclipse.rap.ui.views@default:default,org.eclipse.rap.ui.workbench@default:default,org.eclipse.rap.ui@default:default,org.hamcrest.core@default:default,org.junit@default:default"/>
 <booleanAttribute key="tracing" value="false"/>
 <booleanAttribute key="useCustomFeatures" value="false"/>
 <booleanAttribute key="useDefaultConfigArea" value="true"/>
