471341: [Draw2d] FigureUtilities#setFont does not check for disposed

Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=471341
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"/>