diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/ImageCombo.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/ImageCombo.java
index c4a0405..8f29469 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/ImageCombo.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.swt/src/org/eclipse/tcf/te/ui/swt/widgets/ImageCombo.java
@@ -1,16 +1,19 @@
 /*******************************************************************************
- * Copyright (c) 2014 Wind River Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the terms
- * of the Eclipse Public License v1.0 which accompanies this distribution, and is
- * available at http://www.eclipse.org/legal/epl-v10.html
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
- * Wind River Systems - initial API and implementation
+ *     IBM Corporation - initial API and implementation
+ *     Tom Seidel      - enhancements for image-handling
+ *     Wind River Systems - adopted from org.eclipse.cdt.internal.ui.ImageCombo
  *******************************************************************************/
 
 package org.eclipse.tcf.te.ui.swt.widgets;
 
-	import java.util.Arrays;
+import java.util.Arrays;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
@@ -45,33 +48,33 @@
 import org.eclipse.swt.widgets.TypedListener;
 import org.eclipse.swt.widgets.Widget;
 
-	/**
-	 * The ImageCombo class represents a selectable user interface object
-	 * that combines a text field and a table and issues notification
-	 * when an item is selected from the table.
-	 * <p>
-	 * Note that although this class is a subclass of <code>Composite</code>,
-	 * it does not make sense to add children to it, or set a layout on it.
-	 * </p>
-	 * <dl>
-	 * <dt><b>Styles:</b>
-	 * <dd>BORDER, READ_ONLY, FLAT</dd>
-	 * <dt><b>Events:</b>
-	 * <dd>Selection</dd>
-	 * </dl>
-	 */
-	public final class ImageCombo extends Composite {
+/**
+ * The ImageCombo class represents a selectable user interface object
+ * that combines a text field and a table and issues notification
+ * when an item is selected from the table.
+ * <p>
+ * Note that although this class is a subclass of <code>Composite</code>,
+ * it does not make sense to add children to it, or set a layout on it.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b>
+ * <dd>BORDER, READ_ONLY, FLAT</dd>
+ * <dt><b>Events:</b>
+ * <dd>Selection</dd>
+ * </dl>
+ */
+public final class ImageCombo extends Composite {
 
-		Label image;
-	    Text text;
-	    Table table;
-	    int visibleItemCount = 5;
-	    Shell popup;
-	    Button arrow;
-	    boolean hasFocus;
-	    Listener listener, filter;
-	    Color foreground, background;
-	    Font font;
+	Label image;
+	Text text;
+	Table table;
+	int visibleItemCount = 5;
+	Shell popup;
+	Button arrow;
+	boolean hasFocus;
+	Listener listener, filter;
+	Color foreground, background;
+	Font font;
 
 	/**
 	 * Constructs a new instance of this class given its parent
@@ -102,70 +105,70 @@
 	 * @see Widget#getStyle()
 	 */
 	public ImageCombo (Composite parent, int style) {
-	    super (parent, style = checkStyle (style));
+		super (parent, style = checkStyle (style));
 
-	    int textStyle = SWT.SINGLE;
-	    if ((style & SWT.READ_ONLY) != 0) textStyle |= SWT.READ_ONLY;
-	    if ((style & SWT.FLAT) != 0) textStyle |= SWT.FLAT;
-	    image = new Label (this, SWT.NONE);
-	    text = new Text (this, textStyle);
-	    int arrowStyle = SWT.ARROW | SWT.DOWN;
-	    if ((style & SWT.FLAT) != 0) arrowStyle |= SWT.FLAT;
-	    arrow = new Button (this, arrowStyle);
+		int textStyle = SWT.SINGLE;
+		if ((style & SWT.READ_ONLY) != 0) textStyle |= SWT.READ_ONLY;
+		if ((style & SWT.FLAT) != 0) textStyle |= SWT.FLAT;
+		image = new Label (this, SWT.NONE);
+		text = new Text (this, textStyle);
+		int arrowStyle = SWT.ARROW | SWT.DOWN;
+		if ((style & SWT.FLAT) != 0) arrowStyle |= SWT.FLAT;
+		arrow = new Button (this, arrowStyle);
 
-	    listener = new Listener () {
-	        @Override
-            public void handleEvent (Event event) {
-	            if (popup == event.widget) {
-	                popupEvent (event);
-	                return;
-	            }
-	            if (text == event.widget) {
-	                textEvent (event);
-	                return;
-	            }
-	            if (table == event.widget) {
-	                listEvent (event);
-	                return;
-	            }
-	            if (arrow == event.widget) {
-	                arrowEvent (event);
-	                return;
-	            }
-	            if (ImageCombo.this == event.widget) {
-	                comboEvent (event);
-	                return;
-	            }
-	            if (getShell () == event.widget) {
-	                handleFocus (SWT.FocusOut);
-	            }
-	        }
-	    };
-	    filter = new Listener() {
-	        @Override
-            public void handleEvent(Event event) {
-	            Shell shell = ((Control)event.widget).getShell ();
-	            if (shell == ImageCombo.this.getShell ()) {
-	                handleFocus (SWT.FocusOut);
-	            }
-	        }
-	    };
+		listener = new Listener () {
+			@Override
+			public void handleEvent (Event event) {
+				if (popup == event.widget) {
+					popupEvent (event);
+					return;
+				}
+				if (text == event.widget) {
+					textEvent (event);
+					return;
+				}
+				if (table == event.widget) {
+					listEvent (event);
+					return;
+				}
+				if (arrow == event.widget) {
+					arrowEvent (event);
+					return;
+				}
+				if (ImageCombo.this == event.widget) {
+					comboEvent (event);
+					return;
+				}
+				if (getShell () == event.widget) {
+					handleFocus (SWT.FocusOut);
+				}
+			}
+		};
+		filter = new Listener() {
+			@Override
+			public void handleEvent(Event event) {
+				Shell shell = ((Control)event.widget).getShell ();
+				if (shell == ImageCombo.this.getShell ()) {
+					handleFocus (SWT.FocusOut);
+				}
+			}
+		};
 
-	    int [] comboEvents = {SWT.Dispose, SWT.Move, SWT.Resize};
-	    for (int i=0; i<comboEvents.length; i++) this.addListener (comboEvents [i], listener);
+		int [] comboEvents = {SWT.Dispose, SWT.Move, SWT.Resize};
+		for (int i=0; i<comboEvents.length; i++) this.addListener (comboEvents [i], listener);
 
-	    int [] textEvents = {SWT.KeyDown, SWT.KeyUp, SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.Traverse, SWT.FocusIn};
-	    for (int i=0; i<textEvents.length; i++) text.addListener (textEvents [i], listener);
+		int [] textEvents = {SWT.KeyDown, SWT.KeyUp, SWT.Modify, SWT.MouseDown, SWT.MouseUp, SWT.Traverse, SWT.FocusIn};
+		for (int i=0; i<textEvents.length; i++) text.addListener (textEvents [i], listener);
 
-	    int [] arrowEvents = {SWT.Selection, SWT.FocusIn};
-	    for (int i=0; i<arrowEvents.length; i++) arrow.addListener (arrowEvents [i], listener);
+		int [] arrowEvents = {SWT.Selection, SWT.FocusIn};
+		for (int i=0; i<arrowEvents.length; i++) arrow.addListener (arrowEvents [i], listener);
 
-	    createPopup( -1);
-	    initAccessible();
+		createPopup( -1);
+		initAccessible();
 	}
 	static int checkStyle (int style) {
-	    int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
-	    return style & mask;
+		int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
+		return style & mask;
 	}
 	/**
 	 * Adds the argument to the end of the receiver's list.
@@ -183,11 +186,11 @@
 	 * @see #add(String,int)
 	 */
 	public void add (String string, Image image) {
-	    checkWidget();
-	    if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    TableItem newItem = new TableItem(this.table,SWT.NONE);
-	    newItem.setText(string);
-	    if (image != null) newItem.setImage(image);
+		checkWidget();
+		if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		TableItem newItem = new TableItem(this.table,SWT.NONE);
+		newItem.setText(string);
+		if (image != null) newItem.setImage(image);
 	}
 	/**
 	 * Adds the argument to the receiver's list at the given
@@ -213,10 +216,10 @@
 	 * @see #add(String)
 	 */
 	public void add (String string,Image image, int index) {
-	    checkWidget();
-	    if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    TableItem newItem = new TableItem(this.table,SWT.NONE,index);
-	    if (image != null) newItem.setImage(image);
+		checkWidget();
+		if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		TableItem newItem = new TableItem(this.table,SWT.NONE,index);
+		if (image != null) newItem.setImage(image);
 	}
 	/**
 	 * Adds the listener to the collection of listeners who will
@@ -238,10 +241,10 @@
 	 * @see #removeModifyListener
 	 */
 	public void addModifyListener (ModifyListener listener) {
-	    checkWidget();
-	    if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    TypedListener typedListener = new TypedListener (listener);
-	    addListener (SWT.Modify, typedListener);
+		checkWidget();
+		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		TypedListener typedListener = new TypedListener (listener);
+		addListener (SWT.Modify, typedListener);
 	}
 	/**
 	 * Adds the listener to the collection of listeners who will
@@ -268,23 +271,23 @@
 	 * @see SelectionEvent
 	 */
 	public void addSelectionListener(SelectionListener listener) {
-	    checkWidget();
-	    if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    TypedListener typedListener = new TypedListener (listener);
-	    addListener (SWT.Selection,typedListener);
-	    addListener (SWT.DefaultSelection,typedListener);
+		checkWidget();
+		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		TypedListener typedListener = new TypedListener (listener);
+		addListener (SWT.Selection,typedListener);
+		addListener (SWT.DefaultSelection,typedListener);
 	}
 	void arrowEvent (Event event) {
-	    switch (event.type) {
-	        case SWT.FocusIn: {
-	            handleFocus (SWT.FocusIn);
-	            break;
-	        }
-	        case SWT.Selection: {
-	            dropDown (!isDropped ());
-	            break;
-	        }
-	    }
+		switch (event.type) {
+		case SWT.FocusIn: {
+			handleFocus (SWT.FocusIn);
+			break;
+		}
+		case SWT.Selection: {
+			dropDown (!isDropped ());
+			break;
+		}
+		}
 	}
 	/**
 	 * Sets the selection in the receiver's text field to an empty
@@ -304,76 +307,76 @@
 	 * @see #deselectAll
 	 */
 	public void clearSelection () {
-	    checkWidget ();
-	    text.clearSelection ();
-	    table.deselectAll ();
+		checkWidget ();
+		text.clearSelection ();
+		table.deselectAll ();
 	}
 	void comboEvent (Event event) {
-	    switch (event.type) {
-	        case SWT.Dispose:
-	            if (popup != null && !popup.isDisposed ()) {
-	                table.removeListener (SWT.Dispose, listener);
-	                popup.dispose ();
-	            }
-	            Shell shell = getShell ();
-	            shell.removeListener (SWT.Deactivate, listener);
-	            Display display = getDisplay ();
-	            display.removeFilter (SWT.FocusIn, filter);
-	            popup = null;
-	            text = null;
-	            table = null;
-	            arrow = null;
-	            break;
-	        case SWT.Move:
-	            dropDown (false);
-	            break;
-	        case SWT.Resize:
-	            internalLayout (false);
-	            break;
-	    }
+		switch (event.type) {
+		case SWT.Dispose:
+			if (popup != null && !popup.isDisposed ()) {
+				table.removeListener (SWT.Dispose, listener);
+				popup.dispose ();
+			}
+			Shell shell = getShell ();
+			shell.removeListener (SWT.Deactivate, listener);
+			Display display = getDisplay ();
+			display.removeFilter (SWT.FocusIn, filter);
+			popup = null;
+			text = null;
+			table = null;
+			arrow = null;
+			break;
+		case SWT.Move:
+			dropDown (false);
+			break;
+		case SWT.Resize:
+			internalLayout (false);
+			break;
+		}
 	}
 
 	@Override
-    public Point computeSize (int wHint, int hHint, boolean changed) {
-	    checkWidget ();
-	    int width = 0, height = 0;
-	    String[] items = getStringsFromTable();
-	    int textWidth = 0;
-	    GC gc = new GC (text);
-	    int spacer = gc.stringExtent (" ").x; //$NON-NLS-1$
-	    for (int i = 0; i < items.length; i++) {
-	        textWidth = Math.max (gc.stringExtent (items[i]).x, textWidth);
-	    }
-	    gc.dispose();
-	    Point textSize = text.computeSize (SWT.DEFAULT, SWT.DEFAULT, changed);
-	    Point arrowSize = arrow.computeSize (SWT.DEFAULT, SWT.DEFAULT, changed);
-	    Point listSize = table.computeSize (wHint, SWT.DEFAULT, changed);
-	    int borderWidth = getBorderWidth ();
+	public Point computeSize (int wHint, int hHint, boolean changed) {
+		checkWidget ();
+		int width = 0, height = 0;
+		String[] items = getStringsFromTable();
+		int textWidth = 0;
+		GC gc = new GC (text);
+		int spacer = gc.stringExtent (" ").x; //$NON-NLS-1$
+		for (int i = 0; i < items.length; i++) {
+			textWidth = Math.max (gc.stringExtent (items[i]).x, textWidth);
+		}
+		gc.dispose();
+		Point textSize = text.computeSize (SWT.DEFAULT, SWT.DEFAULT, changed);
+		Point arrowSize = arrow.computeSize (SWT.DEFAULT, SWT.DEFAULT, changed);
+		Point listSize = table.computeSize (wHint, SWT.DEFAULT, changed);
+		int borderWidth = getBorderWidth ();
 
-	    height = Math.max (hHint, Math.max (textSize.y, arrowSize.y) + 2*borderWidth);
-	    width = Math.max (wHint, Math.max (textWidth + 2*spacer + arrowSize.x + 2*borderWidth, listSize.x));
-	    return new Point (width, height);
+		height = Math.max (hHint, Math.max (textSize.y, arrowSize.y) + 2*borderWidth);
+		width = Math.max (wHint, Math.max (textWidth + 2*spacer + arrowSize.x + 2*borderWidth, listSize.x));
+		return new Point (width, height);
 	}
 	void createPopup(int selectionIndex) {
-	        // create shell and list
-	        popup = new Shell (getShell (), SWT.NO_TRIM | SWT.ON_TOP);
-	        int style = getStyle ();
-	        int listStyle = SWT.SINGLE | SWT.V_SCROLL;
-	        if ((style & SWT.FLAT) != 0) listStyle |= SWT.FLAT;
-	        if ((style & SWT.RIGHT_TO_LEFT) != 0) listStyle |= SWT.RIGHT_TO_LEFT;
-	        if ((style & SWT.LEFT_TO_RIGHT) != 0) listStyle |= SWT.LEFT_TO_RIGHT;
-	        // create a table instead of a list.
-	        table = new Table (popup, listStyle);
-	        if (font != null) table.setFont (font);
-	        if (foreground != null) table.setForeground (foreground);
-	        if (background != null) table.setBackground (background);
+		// create shell and list
+		popup = new Shell (getShell (), SWT.NO_TRIM | SWT.ON_TOP);
+		int style = getStyle ();
+		int listStyle = SWT.SINGLE | SWT.V_SCROLL;
+		if ((style & SWT.FLAT) != 0) listStyle |= SWT.FLAT;
+		if ((style & SWT.RIGHT_TO_LEFT) != 0) listStyle |= SWT.RIGHT_TO_LEFT;
+		if ((style & SWT.LEFT_TO_RIGHT) != 0) listStyle |= SWT.LEFT_TO_RIGHT;
+		// create a table instead of a list.
+		table = new Table (popup, listStyle);
+		if (font != null) table.setFont (font);
+		if (foreground != null) table.setForeground (foreground);
+		if (background != null) table.setBackground (background);
 
-	        int [] popupEvents = {SWT.Close, SWT.Paint, SWT.Deactivate};
-	        for (int i=0; i<popupEvents.length; i++) popup.addListener (popupEvents [i], listener);
-	        int [] listEvents = {SWT.MouseUp, SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose};
-	        for (int i=0; i<listEvents.length; i++) table.addListener (listEvents [i], listener);
+		int [] popupEvents = {SWT.Close, SWT.Paint, SWT.Deactivate};
+		for (int i=0; i<popupEvents.length; i++) popup.addListener (popupEvents [i], listener);
+		int [] listEvents = {SWT.MouseUp, SWT.Selection, SWT.Traverse, SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.Dispose};
+		for (int i=0; i<listEvents.length; i++) table.addListener (listEvents [i], listener);
 
-	        if (selectionIndex != -1) table.setSelection (selectionIndex);
+		if (selectionIndex != -1) table.setSelection (selectionIndex);
 	}
 	/**
 	 * Deselects the item at the given zero-relative index in the receiver's
@@ -388,8 +391,8 @@
 	 * </ul>
 	 */
 	public void deselect (int index) {
-	    checkWidget ();
-	    table.deselect (index);
+		checkWidget ();
+		table.deselect (index);
 	}
 	/**
 	 * Deselects all selected items in the receiver's list.
@@ -406,71 +409,71 @@
 	 * @see #clearSelection
 	 */
 	public void deselectAll () {
-	    checkWidget ();
-	    table.deselectAll ();
+		checkWidget ();
+		table.deselectAll ();
 	}
 	void dropDown (boolean drop) {
-	    if (drop == isDropped ()) return;
-	    if (!drop) {
-	        popup.setVisible (false);
-	        if (!isDisposed ()&& arrow.isFocusControl()) {
-//	            setFocus();
-	        }
-	        return;
-	    }
+		if (drop == isDropped ()) return;
+		if (!drop) {
+			popup.setVisible (false);
+			if (!isDisposed ()&& arrow.isFocusControl()) {
+				//	            setFocus();
+			}
+			return;
+		}
 
-	    if (getShell() != popup.getParent ()) {
-//	        TableItem[] items = table.getItems ();
-	        int selectionIndex = table.getSelectionIndex ();
-	        table.removeListener (SWT.Dispose, listener);
-	        popup.dispose();
-	        popup = null;
-	        table = null;
-	        createPopup (selectionIndex);
-	    }
+		if (getShell() != popup.getParent ()) {
+			//	        TableItem[] items = table.getItems ();
+			int selectionIndex = table.getSelectionIndex ();
+			table.removeListener (SWT.Dispose, listener);
+			popup.dispose();
+			popup = null;
+			table = null;
+			createPopup (selectionIndex);
+		}
 
-	    Point size = getSize ();
-	    int itemCount = table.getItemCount ();
-	    itemCount = (itemCount == 0) ? visibleItemCount : Math.min(visibleItemCount, itemCount);
-	    int itemHeight = table.getItemHeight () * itemCount;
-	    Point listSize = table.computeSize (SWT.DEFAULT, itemHeight, false);
-	    table.setBounds (1, 1, Math.max (size.x - 2, listSize.x), listSize.y);
+		Point size = getSize ();
+		int itemCount = table.getItemCount ();
+		itemCount = (itemCount == 0) ? visibleItemCount : Math.min(visibleItemCount, itemCount);
+		int itemHeight = table.getItemHeight () * itemCount;
+		Point listSize = table.computeSize (SWT.DEFAULT, itemHeight, false);
+		table.setBounds (1, 1, Math.max (size.x - 2, listSize.x), listSize.y);
 
-	    int index = table.getSelectionIndex ();
-	    if (index != -1) table.setTopIndex (index);
-	    Display display = getDisplay ();
-	    Rectangle listRect = table.getBounds ();
-	    Rectangle parentRect = display.map (getParent (), null, getBounds ());
-	    Point comboSize = getSize ();
-	    Rectangle displayRect = getMonitor ().getClientArea ();
-	    int width = Math.max (comboSize.x, listRect.width + 2);
-	    int height = listRect.height + 2;
-	    int x = parentRect.x;
-	    int y = parentRect.y + comboSize.y;
-	    if (y + height > displayRect.y + displayRect.height) y = parentRect.y - height;
-	    popup.setBounds (x, y, width, height);
-	    popup.setVisible (true);
-	    table.setFocus ();
+		int index = table.getSelectionIndex ();
+		if (index != -1) table.setTopIndex (index);
+		Display display = getDisplay ();
+		Rectangle listRect = table.getBounds ();
+		Rectangle parentRect = display.map (getParent (), null, getBounds ());
+		Point comboSize = getSize ();
+		Rectangle displayRect = getMonitor ().getClientArea ();
+		int width = Math.max (comboSize.x, listRect.width + 2);
+		int height = listRect.height + 2;
+		int x = parentRect.x;
+		int y = parentRect.y + comboSize.y;
+		if (y + height > displayRect.y + displayRect.height) y = parentRect.y - height;
+		popup.setBounds (x, y, width, height);
+		popup.setVisible (true);
+		table.setFocus ();
 	}
 	/*
 	 * Return the Label immediately preceding the receiver in the z-order,
 	 * or null if none.
 	 */
 	Label getAssociatedLabel () {
-	    Control[] siblings = getParent ().getChildren ();
-	    for (int i = 0; i < siblings.length; i++) {
-	        if (siblings [i] == ImageCombo.this) {
-	            if (i > 0 && siblings [i-1] instanceof Label) {
-	                return (Label) siblings [i-1];
-	            }
-	        }
-	    }
-	    return null;
+		Control[] siblings = getParent ().getChildren ();
+		for (int i = 0; i < siblings.length; i++) {
+			if (siblings [i] == ImageCombo.this) {
+				if (i > 0 && siblings [i-1] instanceof Label) {
+					return (Label) siblings [i-1];
+				}
+			}
+		}
+		return null;
 	}
 	@Override
-    public Control [] getChildren () {
-	    checkWidget();
-	    return new Control [0];
+	public Control [] getChildren () {
+		checkWidget();
+		return new Control [0];
 	}
 	/**
 	 * Gets the editable state.
@@ -485,8 +488,8 @@
 	 * @since 3.0
 	 */
 	public boolean getEditable () {
-	    checkWidget ();
-	    return text.getEditable();
+		checkWidget ();
+		return text.getEditable();
 	}
 	/**
 	 * Returns the item at the given, zero-relative index in the
@@ -505,8 +508,8 @@
 	 * </ul>
 	 */
 	public TableItem getItem (int index) {
-	    checkWidget();
-	    return this.table.getItem (index);
+		checkWidget();
+		return this.table.getItem (index);
 	}
 	/**
 	 * Returns the number of items contained in the receiver's list.
@@ -519,8 +522,8 @@
 	 * </ul>
 	 */
 	public int getItemCount () {
-	    checkWidget ();
-	    return table.getItemCount ();
+		checkWidget ();
+		return table.getItemCount ();
 	}
 	/**
 	 * Returns the height of the area which would be used to
@@ -534,8 +537,8 @@
 	 * </ul>
 	 */
 	public int getItemHeight () {
-	    checkWidget ();
-	    return table.getItemHeight ();
+		checkWidget ();
+		return table.getItemHeight ();
 	}
 	/**
 	 * Returns an array of <code>String</code>s which are the items
@@ -554,28 +557,28 @@
 	 * </ul>
 	 */
 	public TableItem [] getItems () {
-	    checkWidget ();
-	    return table.getItems ();
+		checkWidget ();
+		return table.getItems ();
 	}
 	char getMnemonic (String string) {
-	    int index = 0;
-	    int length = string.length ();
-	    do {
-	        while ((index < length) && (string.charAt (index) != '&')) index++;
-	        if (++index >= length) return '\0';
-	        if (string.charAt (index) != '&') return string.charAt (index);
-	        index++;
-	    } while (index < length);
-	    return '\0';
+		int index = 0;
+		int length = string.length ();
+		do {
+			while ((index < length) && (string.charAt (index) != '&')) index++;
+			if (++index >= length) return '\0';
+			if (string.charAt (index) != '&') return string.charAt (index);
+			index++;
+		} while (index < length);
+		return '\0';
 	}
 
 	String [] getStringsFromTable()
 	{
-	    String[] items  = new String[this.table.getItems().length];
-	    for (int i = 0, n = items.length; i < n; i++) {
-	        items[i]=this.table.getItem(i).getText();
-	    }
-	    return items;
+		String[] items  = new String[this.table.getItems().length];
+		for (int i = 0, n = items.length; i < n; i++) {
+			items[i]=this.table.getItem(i).getText();
+		}
+		return items;
 	}
 	/**
 	 * Returns a <code>Point</code> whose x coordinate is the start
@@ -592,8 +595,8 @@
 	 * </ul>
 	 */
 	public Point getSelection () {
-	    checkWidget ();
-	    return text.getSelection ();
+		checkWidget ();
+		return text.getSelection ();
 	}
 	/**
 	 * Returns the zero-relative index of the item which is currently
@@ -607,15 +610,15 @@
 	 * </ul>
 	 */
 	public int getSelectionIndex () {
-	    checkWidget ();
-	    return table.getSelectionIndex ();
+		checkWidget ();
+		return table.getSelectionIndex ();
 	}
 	@Override
-    public int getStyle () {
-	    int style = super.getStyle ();
-	    style &= ~SWT.READ_ONLY;
-	    if (!getEditable()) style |= SWT.READ_ONLY;
-	    return style;
+	public int getStyle () {
+		int style = super.getStyle ();
+		style &= ~SWT.READ_ONLY;
+		if (!getEditable()) style |= SWT.READ_ONLY;
+		return style;
 	}
 	/**
 	 * Returns a string containing a copy of the contents of the
@@ -629,8 +632,8 @@
 	 * </ul>
 	 */
 	public String getText () {
-	    checkWidget ();
-	    return text.getText ();
+		checkWidget ();
+		return text.getText ();
 	}
 	/**
 	 * Returns the height of the receivers's text field.
@@ -643,8 +646,8 @@
 	 * </ul>
 	 */
 	public int getTextHeight () {
-	    checkWidget ();
-	    return text.getLineHeight ();
+		checkWidget ();
+		return text.getLineHeight ();
 	}
 	/**
 	 * Returns the maximum number of characters that the receiver's
@@ -660,8 +663,8 @@
 	 * </ul>
 	 */
 	public int getTextLimit () {
-	    checkWidget ();
-	    return text.getTextLimit ();
+		checkWidget ();
+		return text.getTextLimit ();
 	}
 	/**
 	 * Gets the number of items that are visible in the drop
@@ -677,40 +680,40 @@
 	 * @since 3.0
 	 */
 	public int getVisibleItemCount () {
-	    checkWidget ();
-	    return visibleItemCount;
+		checkWidget ();
+		return visibleItemCount;
 	}
 	void handleFocus (int type) {
-	    if (isDisposed ()) return;
-	    switch (type) {
-	        case SWT.FocusIn: {
-	            if (hasFocus) return;
-	            if (getEditable ()) text.selectAll ();
-	            hasFocus = true;
-	            Shell shell = getShell ();
-	            shell.removeListener (SWT.Deactivate, listener);
-	            shell.addListener (SWT.Deactivate, listener);
-	            Display display = getDisplay ();
-	            display.removeFilter (SWT.FocusIn, filter);
-	            display.addFilter (SWT.FocusIn, filter);
-	            Event e = new Event ();
-	            notifyListeners (SWT.FocusIn, e);
-	            break;
-	        }
-	        case SWT.FocusOut: {
-	            if (!hasFocus) return;
-	            Control focusControl = getDisplay ().getFocusControl ();
-	            if (focusControl == arrow || focusControl == table || focusControl == text) return;
-	            hasFocus = false;
-	            Shell shell = getShell ();
-	            shell.removeListener(SWT.Deactivate, listener);
-	            Display display = getDisplay ();
-	            display.removeFilter (SWT.FocusIn, filter);
-	            Event e = new Event ();
-	            notifyListeners (SWT.FocusOut, e);
-	            break;
-	        }
-	    }
+		if (isDisposed ()) return;
+		switch (type) {
+		case SWT.FocusIn: {
+			if (hasFocus) return;
+			if (getEditable ()) text.selectAll ();
+			hasFocus = true;
+			Shell shell = getShell ();
+			shell.removeListener (SWT.Deactivate, listener);
+			shell.addListener (SWT.Deactivate, listener);
+			Display display = getDisplay ();
+			display.removeFilter (SWT.FocusIn, filter);
+			display.addFilter (SWT.FocusIn, filter);
+			Event e = new Event ();
+			notifyListeners (SWT.FocusIn, e);
+			break;
+		}
+		case SWT.FocusOut: {
+			if (!hasFocus) return;
+			Control focusControl = getDisplay ().getFocusControl ();
+			if (focusControl == arrow || focusControl == table || focusControl == text) return;
+			hasFocus = false;
+			Shell shell = getShell ();
+			shell.removeListener(SWT.Deactivate, listener);
+			Display display = getDisplay ();
+			display.removeFilter (SWT.FocusIn, filter);
+			Event e = new Event ();
+			notifyListeners (SWT.FocusOut, e);
+			break;
+		}
+		}
 	}
 	/**
 	 * Searches the receiver's list starting at the first item
@@ -730,269 +733,269 @@
 	 * </ul>
 	 */
 	public int indexOf (String string) {
-	    checkWidget ();
-	    if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    return Arrays.asList(getStringsFromTable()).indexOf (string);
+		checkWidget ();
+		if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		return Arrays.asList(getStringsFromTable()).indexOf (string);
 	}
 
 
 	void initAccessible() {
-	    AccessibleAdapter accessibleAdapter = new AccessibleAdapter () {
-	        @Override
-            public void getName (AccessibleEvent e) {
-	            String name = null;
-	            Label label = getAssociatedLabel ();
-	            if (label != null) {
-	                name = stripMnemonic (label.getText());
-	            }
-	            e.result = name;
-	        }
-	        @Override
-            public void getKeyboardShortcut(AccessibleEvent e) {
-	            String shortcut = null;
-	            Label label = getAssociatedLabel ();
-	            if (label != null) {
-	                String text = label.getText ();
-	                if (text != null) {
-	                    char mnemonic = getMnemonic (text);
-	                    if (mnemonic != '\0') {
-	                        shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
-	                    }
-	                }
-	            }
-	            e.result = shortcut;
-	        }
-	        @Override
-            public void getHelp (AccessibleEvent e) {
-	            e.result = getToolTipText ();
-	        }
-	    };
-	    getAccessible ().addAccessibleListener (accessibleAdapter);
-	    text.getAccessible ().addAccessibleListener (accessibleAdapter);
-	    table.getAccessible ().addAccessibleListener (accessibleAdapter);
+		AccessibleAdapter accessibleAdapter = new AccessibleAdapter () {
+			@Override
+			public void getName (AccessibleEvent e) {
+				String name = null;
+				Label label = getAssociatedLabel ();
+				if (label != null) {
+					name = stripMnemonic (label.getText());
+				}
+				e.result = name;
+			}
+			@Override
+			public void getKeyboardShortcut(AccessibleEvent e) {
+				String shortcut = null;
+				Label label = getAssociatedLabel ();
+				if (label != null) {
+					String text = label.getText ();
+					if (text != null) {
+						char mnemonic = getMnemonic (text);
+						if (mnemonic != '\0') {
+							shortcut = "Alt+"+mnemonic; //$NON-NLS-1$
+						}
+					}
+				}
+				e.result = shortcut;
+			}
+			@Override
+			public void getHelp (AccessibleEvent e) {
+				e.result = getToolTipText ();
+			}
+		};
+		getAccessible ().addAccessibleListener (accessibleAdapter);
+		text.getAccessible ().addAccessibleListener (accessibleAdapter);
+		table.getAccessible ().addAccessibleListener (accessibleAdapter);
 
-	    arrow.getAccessible ().addAccessibleListener (new AccessibleAdapter() {
-	        @Override
-            public void getName (AccessibleEvent e) {
-	            e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$
-	        }
-	        @Override
-            public void getKeyboardShortcut (AccessibleEvent e) {
-	            e.result = "Alt+Down Arrow"; //$NON-NLS-1$
-	        }
-	        @Override
-            public void getHelp (AccessibleEvent e) {
-	            e.result = getToolTipText ();
-	        }
-	    });
+		arrow.getAccessible ().addAccessibleListener (new AccessibleAdapter() {
+			@Override
+			public void getName (AccessibleEvent e) {
+				e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			@Override
+			public void getKeyboardShortcut (AccessibleEvent e) {
+				e.result = "Alt+Down Arrow"; //$NON-NLS-1$
+			}
+			@Override
+			public void getHelp (AccessibleEvent e) {
+				e.result = getToolTipText ();
+			}
+		});
 
-	    getAccessible().addAccessibleTextListener (new AccessibleTextAdapter() {
-	        @Override
-            public void getCaretOffset (AccessibleTextEvent e) {
-	            e.offset = text.getCaretPosition ();
-	        }
-	    });
+		getAccessible().addAccessibleTextListener (new AccessibleTextAdapter() {
+			@Override
+			public void getCaretOffset (AccessibleTextEvent e) {
+				e.offset = text.getCaretPosition ();
+			}
+		});
 
-	    getAccessible().addAccessibleControlListener (new AccessibleControlAdapter() {
-	        @Override
-            public void getChildAtPoint (AccessibleControlEvent e) {
-	            Point testPoint = toControl (e.x, e.y);
-	            if (getBounds ().contains (testPoint)) {
-	                e.childID = ACC.CHILDID_SELF;
-	            }
-	        }
+		getAccessible().addAccessibleControlListener (new AccessibleControlAdapter() {
+			@Override
+			public void getChildAtPoint (AccessibleControlEvent e) {
+				Point testPoint = toControl (e.x, e.y);
+				if (getBounds ().contains (testPoint)) {
+					e.childID = ACC.CHILDID_SELF;
+				}
+			}
 
-	        @Override
-            public void getLocation (AccessibleControlEvent e) {
-	            Rectangle location = getBounds ();
-	            Point pt = toDisplay (location.x, location.y);
-	            e.x = pt.x;
-	            e.y = pt.y;
-	            e.width = location.width;
-	            e.height = location.height;
-	        }
+			@Override
+			public void getLocation (AccessibleControlEvent e) {
+				Rectangle location = getBounds ();
+				Point pt = toDisplay (location.x, location.y);
+				e.x = pt.x;
+				e.y = pt.y;
+				e.width = location.width;
+				e.height = location.height;
+			}
 
-	        @Override
-            public void getChildCount (AccessibleControlEvent e) {
-	            e.detail = 0;
-	        }
+			@Override
+			public void getChildCount (AccessibleControlEvent e) {
+				e.detail = 0;
+			}
 
-	        @Override
-            public void getRole (AccessibleControlEvent e) {
-	            e.detail = ACC.ROLE_COMBOBOX;
-	        }
+			@Override
+			public void getRole (AccessibleControlEvent e) {
+				e.detail = ACC.ROLE_COMBOBOX;
+			}
 
-	        @Override
-            public void getState (AccessibleControlEvent e) {
-	            e.detail = ACC.STATE_NORMAL;
-	        }
+			@Override
+			public void getState (AccessibleControlEvent e) {
+				e.detail = ACC.STATE_NORMAL;
+			}
 
-	        @Override
-            public void getValue (AccessibleControlEvent e) {
-	            e.result = getText ();
-	        }
-	    });
+			@Override
+			public void getValue (AccessibleControlEvent e) {
+				e.result = getText ();
+			}
+		});
 
-	    text.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter () {
-	        @Override
-            public void getRole (AccessibleControlEvent e) {
-	            e.detail = getEditable () ? ACC.ROLE_TEXT : ACC.ROLE_LABEL;
-	        }
-	    });
+		text.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter () {
+			@Override
+			public void getRole (AccessibleControlEvent e) {
+				e.detail = getEditable () ? ACC.ROLE_TEXT : ACC.ROLE_LABEL;
+			}
+		});
 
-	    arrow.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter() {
-	        @Override
-            public void getDefaultAction (AccessibleControlEvent e) {
-	            e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$
-	        }
-	    });
+		arrow.getAccessible ().addAccessibleControlListener (new AccessibleControlAdapter() {
+			@Override
+			public void getDefaultAction (AccessibleControlEvent e) {
+				e.result = isDropped () ? SWT.getMessage ("SWT_Close") : SWT.getMessage ("SWT_Open"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		});
 	}
 	boolean isDropped () {
-	    return popup.getVisible ();
+		return popup.getVisible ();
 	}
 	@Override
-    public boolean isFocusControl () {
-	    checkWidget();
-	    if (text.isFocusControl () || arrow.isFocusControl () || table.isFocusControl () || popup.isFocusControl ()) {
-	        return true;
-	    }
-	    return super.isFocusControl ();
+	public boolean isFocusControl () {
+		checkWidget();
+		if (text.isFocusControl () || arrow.isFocusControl () || table.isFocusControl () || popup.isFocusControl ()) {
+			return true;
+		}
+		return super.isFocusControl ();
 	}
 	void internalLayout (boolean changed) {
-	    if (isDropped ()) dropDown (false);
-	    Rectangle rect = getClientArea ();
-	    int width = rect.width;
-	    int height = rect.height;
-	    Point arrowSize = arrow.computeSize (SWT.DEFAULT, height, changed);
-	    image.setBounds (0, 0, 20, height);
-	    text.setBounds (20, 0, width - 20 - arrowSize.x, height);
-	    arrow.setBounds (width - arrowSize.x, 0, arrowSize.x, arrowSize.y);
+		if (isDropped ()) dropDown (false);
+		Rectangle rect = getClientArea ();
+		int width = rect.width;
+		int height = rect.height;
+		Point arrowSize = arrow.computeSize (SWT.DEFAULT, height, changed);
+		image.setBounds (0, 0, 20, height);
+		text.setBounds (20, 0, width - 20 - arrowSize.x, height);
+		arrow.setBounds (width - arrowSize.x, 0, arrowSize.x, arrowSize.y);
 	}
 	void listEvent (Event event) {
-	    switch (event.type) {
-	        case SWT.Dispose:
-	            if (getShell () != popup.getParent ()) {
-//	                TableItem[] items = table.getItems ();
-	                int selectionIndex = table.getSelectionIndex ();
-	                popup = null;
-	                table = null;
-	                createPopup (selectionIndex);
-	            }
-	            break;
-	        case SWT.FocusIn: {
-	            handleFocus (SWT.FocusIn);
-	            break;
-	        }
-	        case SWT.MouseUp: {
-	            if (event.button != 1) return;
-	            dropDown (false);
-	            break;
-	        }
-	        case SWT.Selection: {
-	            int index = table.getSelectionIndex ();
-	            if (index == -1) return;
-	            image.setImage(table.getItem (index).getImage());
-	            text.setText (table.getItem (index).getText());
-	            if (getEditable())
-	            	text.selectAll ();
-	            table.setSelection (index);
-	            Event e = new Event ();
-	            e.time = event.time;
-	            e.stateMask = event.stateMask;
-	            e.doit = event.doit;
-	            notifyListeners (SWT.Selection, e);
-	            event.doit = e.doit;
-	            break;
-	        }
-	        case SWT.Traverse: {
-	            switch (event.detail) {
-	                case SWT.TRAVERSE_RETURN:
-	                case SWT.TRAVERSE_ESCAPE:
-	                case SWT.TRAVERSE_ARROW_PREVIOUS:
-	                case SWT.TRAVERSE_ARROW_NEXT:
-	                    event.doit = false;
-	                    break;
-	            }
-	            Event e = new Event ();
-	            e.time = event.time;
-	            e.detail = event.detail;
-	            e.doit = event.doit;
-	            e.character = event.character;
-	            e.keyCode = event.keyCode;
-	            notifyListeners (SWT.Traverse, e);
-	            event.doit = e.doit;
-	            event.detail = e.detail;
-	            break;
-	        }
-	        case SWT.KeyUp: {
-	            Event e = new Event ();
-	            e.time = event.time;
-	            e.character = event.character;
-	            e.keyCode = event.keyCode;
-	            e.stateMask = event.stateMask;
-	            notifyListeners (SWT.KeyUp, e);
-	            break;
-	        }
-	        case SWT.KeyDown: {
-	            if (event.character == SWT.ESC) {
-	                // Escape key cancels popup list
-	                dropDown (false);
-	            }
-	            if ((event.stateMask & SWT.ALT) != 0 && (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN)) {
-	                dropDown (false);
-	            }
-	            if (event.character == SWT.CR) {
-	                // Enter causes default selection
-	                dropDown (false);
-	                Event e = new Event ();
-	                e.time = event.time;
-	                e.stateMask = event.stateMask;
-	                notifyListeners (SWT.DefaultSelection, e);
-	            }
-	            // At this point the widget may have been disposed.
-	            // If so, do not continue.
-	            if (isDisposed ()) break;
-	            Event e = new Event();
-	            e.time = event.time;
-	            e.character = event.character;
-	            e.keyCode = event.keyCode;
-	            e.stateMask = event.stateMask;
-	            notifyListeners(SWT.KeyDown, e);
-	            break;
+		switch (event.type) {
+		case SWT.Dispose:
+			if (getShell () != popup.getParent ()) {
+				//	                TableItem[] items = table.getItems ();
+				int selectionIndex = table.getSelectionIndex ();
+				popup = null;
+				table = null;
+				createPopup (selectionIndex);
+			}
+			break;
+		case SWT.FocusIn: {
+			handleFocus (SWT.FocusIn);
+			break;
+		}
+		case SWT.MouseUp: {
+			if (event.button != 1) return;
+			dropDown (false);
+			break;
+		}
+		case SWT.Selection: {
+			int index = table.getSelectionIndex ();
+			if (index == -1) return;
+			image.setImage(table.getItem (index).getImage());
+			text.setText (table.getItem (index).getText());
+			if (getEditable())
+				text.selectAll ();
+			table.setSelection (index);
+			Event e = new Event ();
+			e.time = event.time;
+			e.stateMask = event.stateMask;
+			e.doit = event.doit;
+			notifyListeners (SWT.Selection, e);
+			event.doit = e.doit;
+			break;
+		}
+		case SWT.Traverse: {
+			switch (event.detail) {
+			case SWT.TRAVERSE_RETURN:
+			case SWT.TRAVERSE_ESCAPE:
+			case SWT.TRAVERSE_ARROW_PREVIOUS:
+			case SWT.TRAVERSE_ARROW_NEXT:
+				event.doit = false;
+				break;
+			}
+			Event e = new Event ();
+			e.time = event.time;
+			e.detail = event.detail;
+			e.doit = event.doit;
+			e.character = event.character;
+			e.keyCode = event.keyCode;
+			notifyListeners (SWT.Traverse, e);
+			event.doit = e.doit;
+			event.detail = e.detail;
+			break;
+		}
+		case SWT.KeyUp: {
+			Event e = new Event ();
+			e.time = event.time;
+			e.character = event.character;
+			e.keyCode = event.keyCode;
+			e.stateMask = event.stateMask;
+			notifyListeners (SWT.KeyUp, e);
+			break;
+		}
+		case SWT.KeyDown: {
+			if (event.character == SWT.ESC) {
+				// Escape key cancels popup list
+				dropDown (false);
+			}
+			if ((event.stateMask & SWT.ALT) != 0 && (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN)) {
+				dropDown (false);
+			}
+			if (event.character == SWT.CR) {
+				// Enter causes default selection
+				dropDown (false);
+				Event e = new Event ();
+				e.time = event.time;
+				e.stateMask = event.stateMask;
+				notifyListeners (SWT.DefaultSelection, e);
+			}
+			// At this point the widget may have been disposed.
+			// If so, do not continue.
+			if (isDisposed ()) break;
+			Event e = new Event();
+			e.time = event.time;
+			e.character = event.character;
+			e.keyCode = event.keyCode;
+			e.stateMask = event.stateMask;
+			notifyListeners(SWT.KeyDown, e);
+			break;
 
-	        }
-	    }
+		}
+		}
 	}
 
 	void popupEvent(Event event) {
-	    switch (event.type) {
-	        case SWT.Paint:
-	            // draw black rectangle around list
-	            Rectangle listRect = table.getBounds();
-	            Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK);
-	            event.gc.setForeground(black);
-	            event.gc.drawRectangle(0, 0, listRect.width + 1, listRect.height + 1);
-	            break;
-	        case SWT.Close:
-	            event.doit = false;
-	            dropDown (false);
-	            break;
-	        case SWT.Deactivate:
-	            dropDown (false);
-	            break;
-	    }
+		switch (event.type) {
+		case SWT.Paint:
+			// draw black rectangle around list
+			Rectangle listRect = table.getBounds();
+			Color black = getDisplay().getSystemColor(SWT.COLOR_BLACK);
+			event.gc.setForeground(black);
+			event.gc.drawRectangle(0, 0, listRect.width + 1, listRect.height + 1);
+			break;
+		case SWT.Close:
+			event.doit = false;
+			dropDown (false);
+			break;
+		case SWT.Deactivate:
+			dropDown (false);
+			break;
+		}
 	}
 	@Override
-    public void redraw () {
-	    super.redraw();
-	    image.redraw();
-	    text.redraw();
-	    arrow.redraw();
-	    if (popup.isVisible()) table.redraw();
+	public void redraw () {
+		super.redraw();
+		image.redraw();
+		text.redraw();
+		arrow.redraw();
+		if (popup.isVisible()) table.redraw();
 	}
 	@Override
-    public void redraw (int x, int y, int width, int height, boolean all) {
-	    super.redraw(x, y, width, height, true);
+	public void redraw (int x, int y, int width, int height, boolean all) {
+		super.redraw(x, y, width, height, true);
 	}
 
 	/**
@@ -1010,8 +1013,8 @@
 	 * </ul>
 	 */
 	public void remove (int index) {
-	    checkWidget();
-	    table.remove (index);
+		checkWidget();
+		table.remove (index);
 	}
 	/**
 	 * Removes the items from the receiver's list which are
@@ -1030,8 +1033,8 @@
 	 * </ul>
 	 */
 	public void remove (int start, int end) {
-	    checkWidget();
-	    table.remove (start, end);
+		checkWidget();
+		table.remove (start, end);
 	}
 	/**
 	 * Searches the receiver's list starting at the first item
@@ -1050,16 +1053,16 @@
 	 * </ul>
 	 */
 	public void remove (String string) {
-	    checkWidget();
-	    if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    int index = -1;
-	    for (int i = 0, n = table.getItemCount(); i < n; i++) {
-	        if (table.getItem(i).getText().equals(string)) {
-	            index = i;
-	            break;
-	        }
-	    }
-	    remove(index);
+		checkWidget();
+		if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		int index = -1;
+		for (int i = 0, n = table.getItemCount(); i < n; i++) {
+			if (table.getItem(i).getText().equals(string)) {
+				index = i;
+				break;
+			}
+		}
+		remove(index);
 	}
 	/**
 	 * Removes all of the items from the receiver's list and clear the
@@ -1071,10 +1074,10 @@
 	 * </ul>
 	 */
 	public void removeAll () {
-	    checkWidget();
-        image.setImage(null);
-	    text.setText (""); //$NON-NLS-1$
-	    table.removeAll ();
+		checkWidget();
+		image.setImage(null);
+		text.setText (""); //$NON-NLS-1$
+		table.removeAll ();
 	}
 	/**
 	 * Removes the listener from the collection of listeners who will
@@ -1094,9 +1097,9 @@
 	 * @see #addModifyListener
 	 */
 	public void removeModifyListener (ModifyListener listener) {
-	    checkWidget();
-	    if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    removeListener(SWT.Modify, listener);
+		checkWidget();
+		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		removeListener(SWT.Modify, listener);
 	}
 	/**
 	 * Removes the listener from the collection of listeners who will
@@ -1116,10 +1119,10 @@
 	 * @see #addSelectionListener
 	 */
 	public void removeSelectionListener (SelectionListener listener) {
-	    checkWidget();
-	    if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    removeListener(SWT.Selection, listener);
-	    removeListener(SWT.DefaultSelection,listener);
+		checkWidget();
+		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		removeListener(SWT.Selection, listener);
+		removeListener(SWT.DefaultSelection,listener);
 	}
 	/**
 	 * Selects the item at the given zero-relative index in the receiver's
@@ -1134,32 +1137,32 @@
 	 * </ul>
 	 */
 	public void select (int index) {
-	    checkWidget();
-	    if (index == -1) {
-	        table.deselectAll ();
-            image.setImage(null);
-	        text.setText (""); //$NON-NLS-1$
-	        return;
-	    }
-	    if (0 <= index && index < table.getItemCount()) {
-	        if (index != getSelectionIndex()) {
-	            image.setImage(table.getItem (index).getImage());
-	            text.setText (table.getItem (index).getText());
-	            if (getEditable())
-	            	text.selectAll ();
-	            table.select (index);
-	            table.showSelection ();
-	        }
-	    }
+		checkWidget();
+		if (index == -1) {
+			table.deselectAll ();
+			image.setImage(null);
+			text.setText (""); //$NON-NLS-1$
+			return;
+		}
+		if (0 <= index && index < table.getItemCount()) {
+			if (index != getSelectionIndex()) {
+				image.setImage(table.getItem (index).getImage());
+				text.setText (table.getItem (index).getText());
+				if (getEditable())
+					text.selectAll ();
+				table.select (index);
+				table.showSelection ();
+			}
+		}
 	}
 	@Override
-    public void setBackground (Color color) {
-	    super.setBackground(color);
-	    background = color;
-	    if (image != null) image.setBackground(color);
-	    if (text != null) text.setBackground(color);
-	    if (table != null) table.setBackground(color);
-	    if (arrow != null) arrow.setBackground(color);
+	public void setBackground (Color color) {
+		super.setBackground(color);
+		background = color;
+		if (image != null) image.setBackground(color);
+		if (text != null) text.setBackground(color);
+		if (table != null) table.setBackground(color);
+		if (arrow != null) arrow.setBackground(color);
 	}
 	/**
 	 * Sets the editable state.
@@ -1174,38 +1177,38 @@
 	 * @since 3.0
 	 */
 	public void setEditable (boolean editable) {
-	    checkWidget ();
-	    text.setEditable(editable);
+		checkWidget ();
+		text.setEditable(editable);
 	}
 	@Override
-    public void setEnabled (boolean enabled) {
-	    super.setEnabled(enabled);
-	    if (popup != null) popup.setVisible (false);
-	    if (image != null) image.setEnabled(enabled);
-	    if (text != null) text.setEnabled(enabled);
-	    if (arrow != null) arrow.setEnabled(enabled);
+	public void setEnabled (boolean enabled) {
+		super.setEnabled(enabled);
+		if (popup != null) popup.setVisible (false);
+		if (image != null) image.setEnabled(enabled);
+		if (text != null) text.setEnabled(enabled);
+		if (arrow != null) arrow.setEnabled(enabled);
 	}
 	@Override
-    public boolean setFocus () {
-	    checkWidget();
-	    return text.setFocus ();
+	public boolean setFocus () {
+		checkWidget();
+		return text.setFocus ();
 	}
 	@Override
-    public void setFont (Font font) {
-	    super.setFont (font);
-	    this.font = font;
-	    text.setFont (font);
-	    table.setFont (font);
-	    internalLayout (true);
+	public void setFont (Font font) {
+		super.setFont (font);
+		this.font = font;
+		text.setFont (font);
+		table.setFont (font);
+		internalLayout (true);
 	}
 	@Override
-    public void setForeground (Color color) {
-	    super.setForeground(color);
-	    foreground = color;
-	    if (image != null) image.setForeground(color);
-	    if (text != null) text.setForeground(color);
-	    if (table != null) table.setForeground(color);
-	    if (arrow != null) arrow.setForeground(color);
+	public void setForeground (Color color) {
+		super.setForeground(color);
+		foreground = color;
+		if (image != null) image.setForeground(color);
+		if (text != null) text.setForeground(color);
+		if (table != null) table.setForeground(color);
+		if (arrow != null) arrow.setForeground(color);
 	}
 	/**
 	 * Sets the text of the item in the receiver's list at the given
@@ -1226,9 +1229,9 @@
 	 * </ul>
 	 */
 	public void setItem (int index, String string, Image image) {
-	    checkWidget();
-	    remove(index);
-	    add(string,image,index);
+		checkWidget();
+		remove(index);
+		add(string,image,index);
 	}
 	/**
 	 * Sets the receiver's list to be the given array of items.
@@ -1245,15 +1248,15 @@
 	 * </ul>
 	 */
 	public void setItems (String [] items) {
-	    checkWidget ();
-	    this.table.removeAll();
-	    for (int i = 0, n = items.length; i < n; i++) {
-	        add(items[i],null);
-	    }
-	    if (!getEditable ()) {
-            image.setImage(null);
-	    	text.setText (""); //$NON-NLS-1$
-	    }
+		checkWidget ();
+		this.table.removeAll();
+		for (int i = 0, n = items.length; i < n; i++) {
+			add(items[i],null);
+		}
+		if (!getEditable ()) {
+			image.setImage(null);
+			text.setText (""); //$NON-NLS-1$
+		}
 	}
 
 	/**
@@ -1272,9 +1275,9 @@
 	 * </ul>
 	 */
 	@Override
-    public void setLayout (Layout layout) {
-	    checkWidget ();
-	    return;
+	public void setLayout (Layout layout) {
+		checkWidget ();
+		return;
 	}
 	/**
 	 * Sets the selection in the receiver's text field to the
@@ -1293,9 +1296,9 @@
 	 * </ul>
 	 */
 	public void setSelection (Point selection) {
-	    checkWidget();
-	    if (selection == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    text.setSelection (selection.x, selection.y);
+		checkWidget();
+		if (selection == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		text.setSelection (selection.x, selection.y);
 	}
 
 	/**
@@ -1320,27 +1323,27 @@
 	 * </ul>
 	 */
 	public void setText (String string, Image icon) {
-	    checkWidget();
-	    if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
-	    int index = -1;
-	    for (int i = 0, n = table.getItemCount(); i < n; i++) {
-	        if (table.getItem(i).getText().equals(string)) {
-	            index = i;
-	            break;
-	        }
-	    }
-	    if (index == -1) {
-	        table.deselectAll ();
-            image.setImage(icon);
-	        text.setText (string);
-	        return;
-	    }
-        image.setImage(icon);
-	    text.setText (string);
-	    if (getEditable())
-	    	text.selectAll ();
-	    table.setSelection (index);
-	    table.showSelection ();
+		checkWidget();
+		if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+		int index = -1;
+		for (int i = 0, n = table.getItemCount(); i < n; i++) {
+			if (table.getItem(i).getText().equals(string)) {
+				index = i;
+				break;
+			}
+		}
+		if (index == -1) {
+			table.deselectAll ();
+			image.setImage(icon);
+			text.setText (string);
+			return;
+		}
+		image.setImage(icon);
+		text.setText (string);
+		if (getEditable())
+			text.selectAll ();
+		table.setSelection (index);
+		table.showSelection ();
 	}
 
 	/**
@@ -1358,23 +1361,23 @@
 	 * </ul>
 	 */
 	public void setTextLimit (int limit) {
-	    checkWidget();
-	    text.setTextLimit (limit);
+		checkWidget();
+		text.setTextLimit (limit);
 	}
 
 	@Override
-    public void setToolTipText (String string) {
-	    checkWidget();
-	    super.setToolTipText(string);
-	    arrow.setToolTipText (string);
-	    image.setToolTipText (string);
-	    text.setToolTipText (string);
+	public void setToolTipText (String string) {
+		checkWidget();
+		super.setToolTipText(string);
+		arrow.setToolTipText (string);
+		image.setToolTipText (string);
+		text.setToolTipText (string);
 	}
 
 	@Override
-    public void setVisible (boolean visible) {
-	    super.setVisible(visible);
-	    if (!visible) popup.setVisible(false);
+	public void setVisible (boolean visible) {
+		super.setVisible(visible);
+		if (!visible) popup.setVisible(false);
 	}
 	/**
 	 * Sets the number of items that are visible in the drop
@@ -1390,131 +1393,131 @@
 	 * @since 3.0
 	 */
 	public void setVisibleItemCount (int count) {
-	    checkWidget ();
-	    if (count < 0) return;
-	    visibleItemCount = count;
+		checkWidget ();
+		if (count < 0) return;
+		visibleItemCount = count;
 	}
 	String stripMnemonic (String string) {
-	    int index = 0;
-	    int length = string.length ();
-	    do {
-	        while ((index < length) && (string.charAt (index) != '&')) index++;
-	        if (++index >= length) return string;
-	        if (string.charAt (index) != '&') {
-	            return string.substring(0, index-1) + string.substring(index, length);
-	        }
-	        index++;
-	    } while (index < length);
-	    return string;
+		int index = 0;
+		int length = string.length ();
+		do {
+			while ((index < length) && (string.charAt (index) != '&')) index++;
+			if (++index >= length) return string;
+			if (string.charAt (index) != '&') {
+				return string.substring(0, index-1) + string.substring(index, length);
+			}
+			index++;
+		} while (index < length);
+		return string;
 	}
 	void textEvent (Event event) {
-	    switch (event.type) {
-	        case SWT.FocusIn: {
-	            handleFocus (SWT.FocusIn);
-	            break;
-	        }
-	        case SWT.KeyDown: {
-	            if (event.character == SWT.CR) {
-	                dropDown (false);
-	                Event e = new Event ();
-	                e.time = event.time;
-	                e.stateMask = event.stateMask;
-	                notifyListeners (SWT.DefaultSelection, e);
-	            }
-	            //At this point the widget may have been disposed.
-	            // If so, do not continue.
-	            if (isDisposed ()) break;
+		switch (event.type) {
+		case SWT.FocusIn: {
+			handleFocus (SWT.FocusIn);
+			break;
+		}
+		case SWT.KeyDown: {
+			if (event.character == SWT.CR) {
+				dropDown (false);
+				Event e = new Event ();
+				e.time = event.time;
+				e.stateMask = event.stateMask;
+				notifyListeners (SWT.DefaultSelection, e);
+			}
+			//At this point the widget may have been disposed.
+			// If so, do not continue.
+			if (isDisposed ()) break;
 
-	            if (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN) {
-	                event.doit = false;
-	                if ((event.stateMask & SWT.ALT) != 0) {
-	                    boolean dropped = isDropped ();
-	                    if (getEditable())
-	                    	text.selectAll ();
-	                    if (!dropped) setFocus ();
-	                    dropDown (!dropped);
-	                    break;
-	                }
+			if (event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_DOWN) {
+				event.doit = false;
+				if ((event.stateMask & SWT.ALT) != 0) {
+					boolean dropped = isDropped ();
+					if (getEditable())
+						text.selectAll ();
+					if (!dropped) setFocus ();
+					dropDown (!dropped);
+					break;
+				}
 
-	                int oldIndex = getSelectionIndex ();
-	                if (event.keyCode == SWT.ARROW_UP) {
-	                    select (Math.max (oldIndex - 1, 0));
-	                } else {
-	                    select (Math.min (oldIndex + 1, getItemCount () - 1));
-	                }
-	                if (oldIndex != getSelectionIndex ()) {
-	                    Event e = new Event();
-	                    e.time = event.time;
-	                    e.stateMask = event.stateMask;
-	                    notifyListeners (SWT.Selection, e);
-	                }
-	                //At this point the widget may have been disposed.
-	                // If so, do not continue.
-	                if (isDisposed ()) break;
-	            }
+				int oldIndex = getSelectionIndex ();
+				if (event.keyCode == SWT.ARROW_UP) {
+					select (Math.max (oldIndex - 1, 0));
+				} else {
+					select (Math.min (oldIndex + 1, getItemCount () - 1));
+				}
+				if (oldIndex != getSelectionIndex ()) {
+					Event e = new Event();
+					e.time = event.time;
+					e.stateMask = event.stateMask;
+					notifyListeners (SWT.Selection, e);
+				}
+				//At this point the widget may have been disposed.
+				// If so, do not continue.
+				if (isDisposed ()) break;
+			}
 
-	            Event e = new Event ();
-	            e.time = event.time;
-	            e.character = event.character;
-	            e.keyCode = event.keyCode;
-	            e.stateMask = event.stateMask;
-	            notifyListeners (SWT.KeyDown, e);
-	            break;
-	        }
-	        case SWT.KeyUp: {
-	            Event e = new Event ();
-	            e.time = event.time;
-	            e.character = event.character;
-	            e.keyCode = event.keyCode;
-	            e.stateMask = event.stateMask;
-	            notifyListeners (SWT.KeyUp, e);
-	            break;
-	        }
-	        case SWT.Modify: {
-	            table.deselectAll ();
-	            Event e = new Event ();
-	            e.time = event.time;
-	            notifyListeners (SWT.Modify, e);
-	            break;
-	        }
-	        case SWT.MouseDown: {
-	            if (event.button != 1) return;
-	            if (getEditable ()) return;
-	            boolean dropped = isDropped ();
-            	text.selectAll ();
-	            if (!dropped) setFocus ();
-	            dropDown (!dropped);
-	            break;
-	        }
-	        case SWT.MouseUp: {
-	            if (event.button != 1) return;
-	            if (getEditable ()) return;
-	            text.selectAll ();
-	            break;
-	        }
-	        case SWT.Traverse: {
-	            switch (event.detail) {
-	                case SWT.TRAVERSE_RETURN:
-	                case SWT.TRAVERSE_ARROW_PREVIOUS:
-	                case SWT.TRAVERSE_ARROW_NEXT:
-	                    // The enter causes default selection and
-	                    // the arrow keys are used to manipulate the list contents so
-	                    // do not use them for traversal.
-	                    event.doit = false;
-	                    break;
-	            }
+			Event e = new Event ();
+			e.time = event.time;
+			e.character = event.character;
+			e.keyCode = event.keyCode;
+			e.stateMask = event.stateMask;
+			notifyListeners (SWT.KeyDown, e);
+			break;
+		}
+		case SWT.KeyUp: {
+			Event e = new Event ();
+			e.time = event.time;
+			e.character = event.character;
+			e.keyCode = event.keyCode;
+			e.stateMask = event.stateMask;
+			notifyListeners (SWT.KeyUp, e);
+			break;
+		}
+		case SWT.Modify: {
+			table.deselectAll ();
+			Event e = new Event ();
+			e.time = event.time;
+			notifyListeners (SWT.Modify, e);
+			break;
+		}
+		case SWT.MouseDown: {
+			if (event.button != 1) return;
+			if (getEditable ()) return;
+			boolean dropped = isDropped ();
+			text.selectAll ();
+			if (!dropped) setFocus ();
+			dropDown (!dropped);
+			break;
+		}
+		case SWT.MouseUp: {
+			if (event.button != 1) return;
+			if (getEditable ()) return;
+			text.selectAll ();
+			break;
+		}
+		case SWT.Traverse: {
+			switch (event.detail) {
+			case SWT.TRAVERSE_RETURN:
+			case SWT.TRAVERSE_ARROW_PREVIOUS:
+			case SWT.TRAVERSE_ARROW_NEXT:
+				// The enter causes default selection and
+				// the arrow keys are used to manipulate the list contents so
+				// do not use them for traversal.
+				event.doit = false;
+				break;
+			}
 
-	            Event e = new Event ();
-	            e.time = event.time;
-	            e.detail = event.detail;
-	            e.doit = event.doit;
-	            e.character = event.character;
-	            e.keyCode = event.keyCode;
-	            notifyListeners (SWT.Traverse, e);
-	            event.doit = e.doit;
-	            event.detail = e.detail;
-	            break;
-	        }
-	    }
+			Event e = new Event ();
+			e.time = event.time;
+			e.detail = event.detail;
+			e.doit = event.doit;
+			e.character = event.character;
+			e.keyCode = event.keyCode;
+			notifyListeners (SWT.Traverse, e);
+			event.doit = e.doit;
+			event.detail = e.detail;
+			break;
+		}
+		}
 	}
-	}
\ No newline at end of file
+}
